Commit 0a2d2796 authored by Bentriou Mahmoud's avatar Bentriou Mahmoud
Browse files

Restructuration in the package: separate types from methods related to

an object.

Type stability of simulate, dist, read_trajectory seems to be preserved.
parent 21c72d7e
......@@ -3,23 +3,33 @@ module MarkovProcesses
import Base: +, -, *
import Base: copy, getfield, getindex, lastindex, setindex!, getproperty, setproperty!
export Model, ContinuousTimeModel, DiscreteTimeModel
export simulate, set_param!, get_param, set_observed_var!
export is_bounded
export load_model, get_module_path
include("model.jl")
import StaticArrays: SVector
# Common types and constructors
export Observations, AbstractTrajectory, Trajectory
export LHA, StateLHA, Edge
export Model, ContinuousTimeModel, DiscreteTimeModel
# Trajectory related methods
export +, -, δ, dist_lp
export get_obs_var, length_states, length_obs_var, get_state_from_time
export is_bounded, times, transitions
export check_consistency, is_steadystate
include("trajectory.jl")
export LHA, StateLHA, Edge
# LHA related methods
export init_state, next_state!, read_trajectory
export load_automaton, get_index, get_value, length_var
# Model related methods
export simulate, set_param!, get_param, set_observed_var!
export is_bounded
export load_model, get_module_path
include("common.jl")
include("trajectory.jl")
include("lha.jl")
include("model.jl")
end
abstract type Model end
abstract type AbstractTrajectory end
const Transition = Union{String,Nothing}
const Location = String
const VariableAutomaton = String
mutable struct ContinuousTimeModel <: Model
d::Int # state space dim
k::Int # parameter space dim
map_var_idx::Dict{String,Int} # maps str to full state space
_map_obs_var_idx::Dict{String,Int} # maps str to observed state space
map_param_idx::Dict{String,Int} # maps str in parameter space
l_transitions::Vector{Transition}
p::Vector{Float64}
x0::Vector{Int}
t0::Float64
f!::Function
g::Vector{String} # of dimension dobs
_g_idx::Vector{Int} # of dimension dobs
is_absorbing::Function
time_bound::Float64
buffer_size::Int
end
struct Trajectory <: AbstractTrajectory
m::ContinuousTimeModel
values::Matrix{Int}
times::Vector{Float64}
transitions::Vector{Transition}
end
struct Edge
transitions::Vector{Transition}
check_constraints::Function
update_state!::Function
end
struct LHA
l_transitions::Vector{Transition}
l_loc::Vector{Location}
Λ::Dict{Location,Function}
l_loc_init::Vector{Location}
l_loc_final::Vector{Location}
map_var_automaton_idx::Dict{VariableAutomaton,Int} # nvar keys : str_var => idx in l_var
l_flow::Dict{Location,Vector{Float64}} # output of length nvar
map_edges::Dict{Tuple{Location,Location},Vector{Edge}}
l_ctes::Dict{String,Float64}
map_var_model_idx::Dict{String,Int} # of dim d (of a model)
end
mutable struct StateLHA
A::LHA
loc::Location
l_var::Vector{Float64}
time::Float64
end
mutable struct SynchronizedModel
m::ContinuousTimeModel
automaton::LHA
end
# Constructors
function ContinuousTimeModel(d::Int, k::Int, map_var_idx::Dict, map_param_idx::Dict, l_transitions::Vector{String},
p::Vector{Float64}, x0::Vector{Int}, t0::Float64,
f!::Function, is_absorbing::Function;
g::Vector{String} = keys(map_var_idx), time_bound::Float64 = Inf, buffer_size::Int = 10)
dobs = length(g)
_map_obs_var_idx = Dict()
_g_idx = Vector{Int}(undef, dobs)
for i = 1:dobs
_g_idx[i] = map_var_idx[g[i]] # = ( (g[i] = i-th obs var)::String => idx in state space )
_map_obs_var_idx[g[i]] = i
end
if length(methods(f!)) >= 2
@warn "You have possibly redefined a function Model.f! used in a previously instantiated model."
end
if length(methods(is_absorbing)) >= 2
@warn "You have possibly redefined a function Model.is_absorbing used in a previously instantiated model."
end
return ContinuousTimeModel(d, k, map_var_idx, _map_obs_var_idx, map_param_idx, l_transitions, p, x0, t0, f!, g, _g_idx, is_absorbing, time_bound, buffer_size)
end
LHA(A::LHA, map_var::Dict{String,Int}) = LHA(A.l_transitions, A.l_loc, A.Λ,
A.l_loc_init, A.l_loc_final, A.map_var_automaton_idx, A.l_flow,
A.map_edges, A.l_ctes, map_var)
const Location = String
const VariableAutomaton = String
struct Edge
transitions::Vector{Transition}
check_constraints::Function
update_state!::Function
end
struct LHA
l_transitions::Vector{Transition}
l_loc::Vector{Location}
Λ::Dict{Location,Function}
l_loc_init::Vector{Location}
l_loc_final::Vector{Location}
map_var_automaton_idx::Dict{VariableAutomaton,Int} # nvar keys : str_var => idx in l_var
l_flow::Dict{Location,Vector{Float64}} # output of length nvar
map_edges::Dict{Tuple{Location,Location},Vector{Edge}}
l_ctes::Dict{String,Float64}
map_var_model_idx::Dict{String,Int} # of dim d (of a model)
end
load_automaton(automaton::String) = include(get_module_path() * "/automata/$(automaton).jl")
LHA(A::LHA, map_var::Dict{String,Int}) = LHA(A.l_transitions, A.l_loc, A.Λ,
A.l_loc_init, A.l_loc_final, A.map_var_automaton_idx, A.l_flow,
A.map_edges, A.l_ctes, map_var)
length_var(A::LHA) = length(A.map_var_automaton_idx)
get_value(A::LHA, x::SubArray{Int,1}, var::String) = x[A.map_var_model_idx[var]]
load_automaton(automaton::String) = include(get_module_path() * "/automata/$(automaton).jl")
mutable struct StateLHA
A::LHA
loc::Location
l_var::Vector{Float64}
time::Float64
end
copy(S::StateLHA) = StateLHA(S.A, S.loc, S.l_var, S.time)
# Not overring getproperty, setproperty to avoid a conversion Symbol => String for the dict key
......@@ -50,6 +19,7 @@ function Base.show(io::IO, S::StateLHA)
end
end
# Methods for synchronize / read the trajectory
function init_state(A::LHA, x0::SubArray{Int,1}, t0::Float64)
S0 = StateLHA(A, "", zeros(length_var(A)), t0)
for loc in A.l_loc_init
......
import StaticArrays: SVector
abstract type Model end
abstract type DiscreteTimeModel <: Model end
const Transition = Union{String,Nothing}
# Model types
mutable struct ContinuousTimeModel <: Model
d::Int # state space dim
k::Int # parameter space dim
map_var_idx::Dict{String,Int} # maps str to full state space
_map_obs_var_idx::Dict{String,Int} # maps str to observed state space
map_param_idx::Dict{String,Int} # maps str in parameter space
l_transitions::Vector{Transition}
p::Vector{Float64}
x0::Vector{Int}
t0::Float64
f!::Function
g::Vector{String} # of dimension dobs
_g_idx::Vector{Int} # of dimension dobs
is_absorbing::Function
time_bound::Float64
buffer_size::Int
end
function ContinuousTimeModel(d::Int, k::Int, map_var_idx::Dict, map_param_idx::Dict, l_transitions::Vector{String},
p::Vector{Float64}, x0::Vector{Int}, t0::Float64,
f!::Function, is_absorbing::Function;
g::Vector{String} = keys(map_var_idx), time_bound::Float64 = Inf, buffer_size::Int = 10)
dobs = length(g)
_map_obs_var_idx = Dict()
_g_idx = Vector{Int}(undef, dobs)
for i = 1:dobs
_g_idx[i] = map_var_idx[g[i]] # = ( (g[i] = i-th obs var)::String => idx in state space )
_map_obs_var_idx[g[i]] = i
end
if length(methods(f!)) >= 2
@warn "You have possibly redefined a function Model.f! used in a previously instantiated model."
end
if length(methods(is_absorbing)) >= 2
@warn "You have possibly redefined a function Model.is_absorbing used in a previously instantiated model."
end
return ContinuousTimeModel(d, k, map_var_idx, _map_obs_var_idx, map_param_idx, l_transitions, p, x0, t0, f!, g, _g_idx, is_absorbing, time_bound, buffer_size)
end
#=
mutable struct SynchronizedModel
m::ContinuousTimeModel
automaton::LHA
end
=#
# Simulation
function simulate(m::ContinuousTimeModel)
# trajectory fields
......@@ -99,7 +45,6 @@ function simulate(m::ContinuousTimeModel)
return Trajectory(m, values, times, transitions)
end
#=
function simulate(product::SynchronizedModel)
# trajectory fields
m = product.m
......@@ -153,7 +98,6 @@ function simulate(product::SynchronizedModel)
values = view(full_values, :, m._g_idx)
return Trajectory(m, values, times, transitions)
end
=#
function simulate(m::ContinuousTimeModel, n::Int)
obs = ContinuousObservations(undef, n)
......
abstract type AbstractTrajectory end
ContinuousObservations = AbstractVector{AbstractTrajectory}
struct Trajectory <: AbstractTrajectory
m::ContinuousTimeModel
values::Matrix{Int}
times::Vector{Float64}
transitions::Vector{Transition}
end
# Operations
function +(σ1::AbstractTrajectory,σ2::AbstractTrajectory) end
function -(σ1::AbstractTrajectory,σ2::AbstractTrajectory) end
# Top-level Lp distance function
"""
`dist_lp(l_σ1, l_σ2; verbose, p, str_stat_list, str_stat_trajectory)`
......@@ -170,7 +156,6 @@ function check_consistency(σ::AbstractTrajectory)
end
is_steadystate(σ::AbstractTrajectory) = (σ.m).is_absorbing((σ.m).p, σ[end])
# Properties of the trajectory
length_states(σ::AbstractTrajectory) = length(σ.times)
length_obs_var(σ::AbstractTrajectory) = size(σ.values)[2]
......@@ -200,7 +185,6 @@ function get_state_from_time(σ::AbstractTrajectory, t::Float64)
end
error("Unexpected behavior")
end
δ(σ::AbstractTrajectory,idx::Int) = times(σ)[i+1] - times(σ)[i]
states(σ::AbstractTrajectory) = σ.values
times(σ::AbstractTrajectory) = σ.times
......@@ -214,3 +198,8 @@ getindex(σ::AbstractTrajectory, var::String, idx::Int) = get_value(σ, var, idx
getindex(σ::AbstractTrajectory, var::String) = get_var_values(σ, var)
lastindex(σ::AbstractTrajectory) = length_states(σ)
# Operations
function +(σ1::AbstractTrajectory,σ2::AbstractTrajectory) end
function -(σ1::AbstractTrajectory,σ2::AbstractTrajectory) end
δ(σ::AbstractTrajectory,idx::Int) = times(σ)[i+1] - times(σ)[i]
......@@ -7,6 +7,6 @@ SIR.time_bound = 120.0
x1, x2, t1, t2 = 0.0, Inf, 100.0, 120.0
A_F = create_automaton_F(SIR, x1, x2, t1, t2, "I") # <: LHA
#sync_SIR = SIR * A_F
#σ, state_lha = simulate(sync_SIR)
sync_SIR = SIR * A_F
σ, state_lha = simulate(sync_SIR)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment