diff --git a/automata/automaton_F.jl b/automata/automaton_F.jl index 75bb98103efa34205d537c259ede3b85d703b2b8..5fa594b47dd5eb1664b44e8a8ace954bf3329a19 100644 --- a/automata/automaton_F.jl +++ b/automata/automaton_F.jl @@ -1,6 +1,11 @@ # Creation of the automaton types -@everywhere @eval abstract type EdgeAutomatonF <: Edge end +#@everywhere @eval abstract type EdgeAutomatonF <: Edge end +@everywhere struct EdgeAutomatonF <: Edge + transitions::TransitionSet + check_constraints::CheckConstraintsFunction + update_state!::UpdateStateFunction +end @everywhere @eval $(MarkovProcesses.generate_code_lha_type_def(:AutomatonF, :EdgeAutomatonF)) function create_automaton_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1::Float64, t2::Float64, sym_obs::VariableModel) @@ -46,78 +51,85 @@ function create_automaton_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 basename_func = "$(model_name)_$(id)" edge_name(from_loc::Location, to_loc::Location, edge_number::Int) = Symbol("Edge_$(lha_name)_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)") + function check_constraints(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("check_constraints_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") + end + function update_state!(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("update_state_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)!") + end ## check_constraints & update_state! - @everywhere @eval begin - istrue(val::Float64) = convert(Bool, val) + meta_funcs = quote + @everywhere istrue(val::Float64) = convert(Bool, val) ## Check constraints and update state functions # l0 loc : we construct the edges of the form l0 => (..) # "cc" as check_constraints and "us" as update_state # l0 => l1 - struct $(edge_name(:l0, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l0, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(:l0, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l0, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l0, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l0, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var)]; S_values[$(to_idx(:d))] = Inf; S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p,x); :l1) # l1 loc # l1 => l2 - struct $(edge_name(:l1, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_time >= $t1 && S_values[$(to_idx(:d))] == 0 - $(update_state!)(edge::$(edge_name(:l1, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2) - struct $(edge_name(:l1, :l2, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l2, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l2, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l2, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t2) && (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2) - $(update_state!)(edge::$(edge_name(:l1, :l2, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l2, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2;) #setindex!(S_values, min(abs(S_values[$(to_idx(:n))] - $x1), abs(S_values[$(to_idx(:n))] - $x2)), $(to_idx(:d)))) # l1 => l3 - struct $(edge_name(:l1, :l3, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l3, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l3, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l3, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time <= $t1) && (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2) - $(update_state!)(edge::$(edge_name(:l1, :l3, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l3, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = min(sqrt((S_time - $t1)^2 + (S_values[$(to_idx(:n))] - $x2)^2), sqrt((S_time - $t1)^2 + (S_values[$(to_idx(:n))] - $x1)^2)); :l3) - struct $(edge_name(:l1, :l3, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l3, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l3, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l3, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = ($x1 <= S_values[$(to_idx(:n))] <= $x2) - $(update_state!)(edge::$(edge_name(:l1, :l3, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l3, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = 0; :l3) - struct $(edge_name(:l1, :l3, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l3, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l3, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l3, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t1) && (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2) - $(update_state!)(edge::$(edge_name(:l1, :l3, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l3, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (val_min = min(S_values[$(to_idx(:d))], min(abs(S_values[$(to_idx(:n))] - $x1), abs(S_values[$(to_idx(:n))] - $x2))); S_values[$(to_idx(:d))] = val_min; :l3) # l3 loc # l3 => l1 - struct $(edge_name(:l3, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l3, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(:l3, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l3, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l3, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l3, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var)]; S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p,x); :l1) # l3 => l2 - struct $(edge_name(:l3, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l3, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l3, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l3, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t2 || istrue(S_values[$(to_idx(:isabs))])) - $(update_state!)(edge::$(edge_name(:l3, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l3, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2) end + eval(meta_funcs) @eval begin map_edges = Dict{Location, Dict{Location, Vector{$(edge_type)}}}() @@ -127,46 +139,50 @@ function create_automaton_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 # l0 loc # l0 => l1 - edge1 = $(edge_name(:l0, :l1, 1))(nothing) + edge1 = EdgeAutomatonF(nothing, $(check_constraints(:l0, :l1, 1)), $(update_state!(:l0, :l1, 1))) map_edges[:l0][:l1] = [edge1] # l1 loc # l1 => l2 - edge1 = $(edge_name(:l1, :l2, 1))(nothing) - edge2 = $(edge_name(:l1, :l2, 2))(nothing) + edge1 = EdgeAutomatonF(nothing, $(check_constraints(:l1, :l2, 1)), $(update_state!(:l1, :l2, 1))) + edge2 = EdgeAutomatonF(nothing, $(check_constraints(:l1, :l2, 2)), $(update_state!(:l1, :l2, 2))) map_edges[:l1][:l2] = [edge1, edge2] - #edge3 = $(edge_name(:l1, :l2, 3))(nothing) - #edge4 = $(edge_name(:l1, :l2, 4))(nothing) + #edge3 = EdgeAutomatonF(nothing, $(check_constraints(:l1, :l2, 3)), $(update_state!(:l1, :l2, 3))) + #edge4 = EdgeAutomatonF(nothing, $(check_constraints(:l1, :l2, 4)), $(update_state!(:l1, :l2, 4))) #map_edges[:l1][:l2] = [edge1, edge2, edge3, edge4] # l1 => l3 - edge1 = $(edge_name(:l1, :l3, 1))(nothing) - edge2 = $(edge_name(:l1, :l3, 2))(nothing) - edge3 = $(edge_name(:l1, :l3, 3))(nothing) + edge1 = EdgeAutomatonF(nothing, $(check_constraints(:l1, :l3, 1)), $(update_state!(:l1, :l3, 1))) + edge2 = EdgeAutomatonF(nothing, $(check_constraints(:l1, :l3, 2)), $(update_state!(:l1, :l3, 2))) + edge3 = EdgeAutomatonF(nothing, $(check_constraints(:l1, :l3, 3)), $(update_state!(:l1, :l3, 3))) map_edges[:l1][:l3] = [edge1, edge2, edge3] # l3 loc # l3 => l1 - edge1 = $(edge_name(:l3, :l1, 1))([:ALL]) + edge1 = EdgeAutomatonF([:ALL], $(check_constraints(:l3, :l1, 1)), $(update_state!(:l3, :l1, 1))) map_edges[:l3][:l1] = [edge1] # l3 => l2 - edge1 = $(edge_name(:l3, :l2, 1))(nothing) + edge1 = EdgeAutomatonF(nothing, $(check_constraints(:l3, :l2, 1)), $(update_state!(:l3, :l2, 1))) map_edges[:l3][:l2] = [edge1] end ## Constants constants = Dict{Symbol,Float64}(:x1 => x1, :x2 => x2, :t1 => t1, :t2 => t2) + map_edges_transitions = Dict{Symbol, Dict{Symbol,Vector{TransitionSet}}}() + map_edges_check_constraints = Dict{Symbol, Dict{Symbol,Vector{CheckConstraintsFunction}}}() + map_edges_update_state = Dict{Symbol, Dict{Symbol,Vector{UpdateStateFunction}}}() + # Updating types and simulation methods @everywhere @eval $(MarkovProcesses.generate_code_synchronized_model_type_def(model_name, lha_name)) - @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type, check_constraints, update_state!)) + @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type)) @everywhere @eval $(MarkovProcesses.generate_code_synchronized_simulation(model_name, lha_name, edge_type, m.f!, m.isabsorbing)) A = AutomatonF(m.transitions, locations, Λ_F, locations_init, locations_final, - map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx) + map_var_automaton_idx, flow, map_edges, + map_edges_transitions, map_edges_check_constraints, map_edges_update_state, + constants, m.map_var_idx) return A end -export create_automaton_F - diff --git a/automata/automaton_G.jl b/automata/automaton_G.jl index 920e91a3b0a2ed2c3f24ce1df46ca01089eae2e9..35ae1822fb9ee747fb69451af192a9d5791c36e3 100644 --- a/automata/automaton_G.jl +++ b/automata/automaton_G.jl @@ -1,6 +1,11 @@ # Creation of the automaton types -@everywhere @eval abstract type EdgeAutomatonG <: Edge end +#@everywhere @eval abstract type EdgeAutomatonG <: Edge end +@everywhere struct EdgeAutomatonG <: Edge + transitions::TransitionSet + check_constraints::CheckConstraintsFunction + update_state!::UpdateStateFunction +end @everywhere @eval $(MarkovProcesses.generate_code_lha_type_def(:AutomatonG, :EdgeAutomatonG)) function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1::Float64, t2::Float64, sym_obs::VariableModel) @@ -47,15 +52,21 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 basename_func = "$(model_name)_$(id)" edge_name(from_loc::Location, to_loc::Location, edge_number::Int) = Symbol("Edge_$(lha_name)_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)") + function check_constraints(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("check_constraints_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") + end + function update_state!(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("update_state_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)!") + end ## check_constraints & update_state! - @everywhere @eval begin - istrue(val::Float64) = convert(Bool, val) + meta_funcs = quote + @everywhere istrue(val::Float64) = convert(Bool, val) # l0 loc # l0 => l1 - struct $(edge_name(:l0, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l0, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(:l0, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l0, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l0, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l0, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = 0; S_values[$(to_idx(:n))] = x[$(idx_obs_var)]; S_values[$(to_idx(:in))] = true; @@ -63,107 +74,107 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 :l1) # l1 => l3 - struct $(edge_name(:l1, :l3, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l3, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l3, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l3, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_time <= $t1 && S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2 - $(update_state!)(edge::$(edge_name(:l1, :l3, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l3, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); S_values[$(to_idx(:in))] = false; :l3) - struct $(edge_name(:l1, :l3, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l3, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l3, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l3, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time <= $t1) && ($x1 <= S_values[$(to_idx(:n))] <= $x2) - $(update_state!)(edge::$(edge_name(:l1, :l3, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l3, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = 0; S_values[$(to_idx(:in))] = false; :l3) - struct $(edge_name(:l1, :l3, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l3, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l3, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l3, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && ($x1 <= S_values[$(to_idx(:n))] <= $x2) - $(update_state!)(edge::$(edge_name(:l1, :l3, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l3, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * (S_time - $t1); S_values[$(to_idx(:tprime))] = 0.0; :l3) - struct $(edge_name(:l1, :l3, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l3, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l3, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l3, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && ($x1 <= S_values[$(to_idx(:n))] <= $x2) - $(update_state!)(edge::$(edge_name(:l1, :l3, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l3, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:tprime))] = 0.0; :l3) # l1 => l4 - struct $(edge_name(:l1, :l4, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l4, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l4, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l4, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2) - $(update_state!)(edge::$(edge_name(:l1, :l4, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l4, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:d))] * (S_time - $t1); :l4) - struct $(edge_name(:l1, :l4, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l4, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l4, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l4, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2) - $(update_state!)(edge::$(edge_name(:l1, :l4, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l4, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l4) # l1 => l2 #= - struct $(edge_name(:l1, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && S_time >= $t2 - $(update_state!)(edge::$(edge_name(:l1, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2) - struct $(edge_name(:l1, :l2, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l2, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l2, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l2, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && S_time >= $t2 - $(update_state!)(edge::$(edge_name(:l1, :l2, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l2, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * ($t2 - $t1); :l2) - struct $(edge_name(:l1, :l2, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l2, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l2, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l2, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:isabs))]) && S_time <= $t1 - $(update_state!)(edge::$(edge_name(:l1, :l2, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l2, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = ($t2 - $t1) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); :l2) - struct $(edge_name(:l1, :l2, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l2, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l2, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l2, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:isabs))]) && ($t1 <= S_time <= $t2) - $(update_state!)(edge::$(edge_name(:l1, :l2, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l2, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + ($t2 - S_time) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); :l2) =# # l3 => l1 - struct $(edge_name(:l3, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l3, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(:l3, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l3, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l3, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l3, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var)]; S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p, x); :l1) # l4 => l1 - struct $(edge_name(:l4, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l4, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(:l4, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l4, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l4, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l4, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:tprime))] * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); S_values[$(to_idx(:tprime))] = 0.0; S_values[$(to_idx(:n))] = x[$(idx_obs_var)]; @@ -172,39 +183,39 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 :l1) # l3 => l2 - struct $(edge_name(:l3, :l2, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l3, :l2, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l3, :l2, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l3, :l2, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && (S_time >= $t2 || istrue(S_values[$(to_idx(:isabs))])) - $(update_state!)(edge::$(edge_name(:l3, :l2, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l3, :l2, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * ($t2 - $t1); :l2) - struct $(edge_name(:l3, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l3, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l3, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l3, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && (S_time >= $t2 || istrue(S_values[$(to_idx(:isabs))])) - $(update_state!)(edge::$(edge_name(:l3, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l3, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2) # l4 => l2 - struct $(edge_name(:l4, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l4, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l4, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l4, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (istrue(S_values[$(to_idx(:isabs))])) - $(update_state!)(edge::$(edge_name(:l4, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l4, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + ($t2 - S_time) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); S_values[$(to_idx(:tprime))] = 0.0; :l2) - struct $(edge_name(:l4, :l2, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l4, :l2, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l4, :l2, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l4, :l2, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t2) - $(update_state!)(edge::$(edge_name(:l4, :l2, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l4, :l2, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:tprime))] * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); S_values[$(to_idx(:tprime))] = 0.0; :l2) - end + eval(meta_funcs) @eval begin map_edges = Dict{Location, Dict{Location, Vector{$(edge_type)}}}() @@ -214,62 +225,69 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 # l0 loc # l0 => l1 - edge1 = $(edge_name(:l0, :l1, 1))(nothing) + edge1 = EdgeAutomatonG(nothing, $(check_constraints(:l0, :l1, 1)), $(update_state!(:l0, :l1, 1))) map_edges[:l0][:l1] = [edge1] # l1 loc # l1 => l3 - edge1 = $(edge_name(:l1, :l3, 1))(nothing) - edge2 = $(edge_name(:l1, :l3, 2))(nothing) - edge3 = $(edge_name(:l1, :l3, 3))(nothing) - edge4 = $(edge_name(:l1, :l3, 4))(nothing) + edge1 = EdgeAutomatonG(nothing, $(check_constraints(:l1, :l3, 1)), $(update_state!(:l1, :l3, 1))) + edge2 = EdgeAutomatonG(nothing, $(check_constraints(:l1, :l3, 2)), $(update_state!(:l1, :l3, 2))) + edge3 = EdgeAutomatonG(nothing, $(check_constraints(:l1, :l3, 3)), $(update_state!(:l1, :l3, 3))) + edge4 = EdgeAutomatonG(nothing, $(check_constraints(:l1, :l3, 4)), $(update_state!(:l1, :l3, 4))) map_edges[:l1][:l3] = [edge1, edge2, edge3, edge4] # l1 => l4 - edge1 = $(edge_name(:l1, :l4, 1))(nothing) - edge2 = $(edge_name(:l1, :l4, 2))(nothing) + edge1 = EdgeAutomatonG(nothing, $(check_constraints(:l1, :l4, 1)), $(update_state!(:l1, :l4, 1))) + edge2 = EdgeAutomatonG(nothing, $(check_constraints(:l1, :l4, 2)), $(update_state!(:l1, :l4, 2))) map_edges[:l1][:l4] = [edge1, edge2] # l1 => l2 #= - edge1 = $(edge_name(:l1, :l2, 1))(nothing) - edge2 = $(edge_name(:l1, :l2, 2))(nothing) - edge3 = $(edge_name(:l1, :l2, 3))(nothing) - edge4 = $(edge_name(:l1, :l2, 4))(nothing) + edge1 = EdgeAutomatonG(nothing, $(check_constraints(:l1, :l2, 1)), $(update_state!(:l1, :l2, 1))) + edge2 = EdgeAutomatonG(nothing, $(check_constraints(:l1, :l2, 2)), $(update_state!(:l1, :l2, 2))) + edge3 = EdgeAutomatonG(nothing, $(check_constraints(:l1, :l2, 3)), $(update_state!(:l1, :l2, 3))) + edge4 = EdgeAutomatonG(nothing, $(check_constraints(:l1, :l2, 4)), $(update_state!(:l1, :l2, 4))) map_edges[:l1][:l2] = [edge1, edge2, edge3, edge4] =# # l3 loc # l3 => l1 - edge1 = $(edge_name(:l3, :l1, 1))([:ALL]) + edge1 = EdgeAutomatonG([:ALL], $(check_constraints(:l3, :l1, 1)), $(update_state!(:l3, :l1, 1))) map_edges[:l3][:l1] = [edge1] # l3 => l2 - edge1 = $(edge_name(:l3, :l2, 1))(nothing) - edge2 = $(edge_name(:l3, :l2, 2))(nothing) + edge1 = EdgeAutomatonG(nothing, $(check_constraints(:l3, :l2, 1)), $(update_state!(:l3, :l2, 1))) + edge2 = EdgeAutomatonG(nothing, $(check_constraints(:l3, :l2, 2)), $(update_state!(:l3, :l2, 2))) map_edges[:l3][:l2] = [edge1, edge2] # l4 loc # l4 => l1 - edge1 = $(edge_name(:l4, :l1, 1))([:ALL]) + edge1 = EdgeAutomatonG([:ALL], $(check_constraints(:l4, :l1, 1)), $(update_state!(:l4, :l1, 1))) map_edges[:l4][:l1] = [edge1] # l4 => l2 - edge1 = $(edge_name(:l4, :l2, 1))(nothing) - edge2 = $(edge_name(:l4, :l2, 2))(nothing) + edge1 = EdgeAutomatonG(nothing, $(check_constraints(:l4, :l2, 1)), $(update_state!(:l4, :l2, 1))) + edge2 = EdgeAutomatonG(nothing, $(check_constraints(:l4, :l2, 2)), $(update_state!(:l4, :l2, 2))) map_edges[:l4][:l2] = [edge1,edge2] end + ## Create data separately + map_edges_transitions = Dict{Symbol, Dict{Symbol,Vector{TransitionSet}}}() + map_edges_check_constraints = Dict{Symbol, Dict{Symbol,Vector{CheckConstraintsFunction}}}() + map_edges_update_state = Dict{Symbol, Dict{Symbol,Vector{UpdateStateFunction}}}() + ## Constants constants = Dict{Symbol,Float64}(:x1 => x1, :x2 => x2, :t1 => t1, :t2 => t2) # Updating types and simulation methods @everywhere @eval $(MarkovProcesses.generate_code_synchronized_model_type_def(model_name, lha_name)) - @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type, check_constraints, update_state!)) + @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type)) @everywhere @eval $(MarkovProcesses.generate_code_synchronized_simulation(model_name, lha_name, edge_type, m.f!, m.isabsorbing)) A = AutomatonG(m.transitions, locations, Λ_F, locations_init, locations_final, - map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx) + map_var_automaton_idx, flow, map_edges, + map_edges_transitions, map_edges_check_constraints, map_edges_update_state, + constants, m.map_var_idx) return A end diff --git a/automata/automaton_G_and_F.jl b/automata/automaton_G_and_F.jl index ba05cabdd66c062687176f6d69d57c1c12d32697..6b8d6f94ff151866ea6c6039f7f2be2ebf19879a 100644 --- a/automata/automaton_G_and_F.jl +++ b/automata/automaton_G_and_F.jl @@ -1,7 +1,11 @@ # Creation of the automaton types #@everywhere @eval abstract type EdgeAutomatonGandF <: Edge end -@everywhere struct EdgeAutomatonGandF{T} <: Edge transitions::Union{Nothing,Vector{Symbol}} end +@everywhere struct EdgeAutomatonGandF <: Edge + transitions::TransitionSet + check_constraints::CheckConstraintsFunction + update_state!::UpdateStateFunction +end @everywhere @eval $(MarkovProcesses.generate_code_lha_type_def(:AutomatonGandF, :EdgeAutomatonGandF)) function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1::Float64, t2::Float64, sym_obs_G::VariableModel, @@ -27,11 +31,11 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float # Invariant predicates @everywhere true_inv_predicate(x::Vector{Int}) = true - Λ_F = Dict(:l0G => getfield(Main, :true_inv_predicate), :l1G => getfield(Main, :true_inv_predicate), - :l2G => getfield(Main, :true_inv_predicate), :l3G => getfield(Main, :true_inv_predicate), - :l4G => getfield(Main, :true_inv_predicate), - :l1F => getfield(Main, :true_inv_predicate), - :l2F => getfield(Main, :true_inv_predicate), :l3F => getfield(Main, :true_inv_predicate)) + Λ_F = Dict{Symbol,InvariantPredicateFunction}(:l0G => getfield(Main, :true_inv_predicate), :l1G => getfield(Main, :true_inv_predicate), + :l2G => getfield(Main, :true_inv_predicate), :l3G => getfield(Main, :true_inv_predicate), + :l4G => getfield(Main, :true_inv_predicate), + :l1F => getfield(Main, :true_inv_predicate), + :l2F => getfield(Main, :true_inv_predicate), :l3F => getfield(Main, :true_inv_predicate)) ## Init and final loc locations_init = [:l0G] @@ -59,23 +63,26 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float id = MarkovProcesses.newid() #Symbol("Edge_$(lha_name)_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)") - function generate_edge_type(from_loc::Location, to_loc::Location, edge_number::Int) - tag_type = Symbol("$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") - @eval type = EdgeAutomatonGandF{$(Meta.quot(tag_type))} - return @eval($type) + function edge_name(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") + end + function check_constraints(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("check_constraints_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") + end + function update_state!(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("update_state_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)!") end ## check_constraints & update_state! - @everywhere @eval begin - #return quote - istrue(val::Float64) = convert(Bool, val) + meta_funcs = quote + @everywhere istrue(val::Float64) = convert(Bool, val) ## Edges check constraint and update state functions # l0G loc # l0G => l1G - #struct $(generate_edge_type(:l0G, :l1G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l0G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(generate_edge_type(:l0G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l0G, :l1G, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l0G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l0G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = 0; S_values[$(to_idx(:n))] = x[$(idx_obs_var_G)]; S_values[$(to_idx(:in))] = true; @@ -84,125 +91,125 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float # l1G loc # l1G => l3G - #struct $(generate_edge_type(:l1G, :l3G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1G, :l3G, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1G, :l3G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_time <= $t1 && S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2 - $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1G, :l3G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); S_values[$(to_idx(:in))] = false; :l3G) - #struct $(generate_edge_type(:l1G, :l3G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1G, :l3G, 2)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1G, :l3G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time <= $t1) && ($x1 <= S_values[$(to_idx(:n))] <= $x2) - $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1G, :l3G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = 0; S_values[$(to_idx(:in))] = false; :l3G) - #struct $(generate_edge_type(:l1G, :l3G, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1G, :l3G, 3)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1G, :l3G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && ($x1 <= S_values[$(to_idx(:n))] <= $x2) - $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1G, :l3G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * (S_time - $t1); S_values[$(to_idx(:tprime))] = 0.0; :l3G) - #struct $(generate_edge_type(:l1G, :l3G, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1G, :l3G, 4)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1G, :l3G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && ($x1 <= S_values[$(to_idx(:n))] <= $x2) - $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1G, :l3G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:tprime))] = 0.0; :l3G) # l1G => l4G - #struct $(generate_edge_type(:l1G, :l4G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1G, :l4G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1G, :l4G, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1G, :l4G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2) - $(update_state!)(edge::$(generate_edge_type(:l1G, :l4G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1G, :l4G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:d))] * (S_time - $t1); :l4G) - #struct $(generate_edge_type(:l1G, :l4G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1G, :l4G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1G, :l4G, 2)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1G, :l4G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2) - $(update_state!)(edge::$(generate_edge_type(:l1G, :l4G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1G, :l4G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l4G) # l1G => l2G #= - #struct $(generate_edge_type(:l1G, :l2G, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1G, :l2G, 3)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1G, :l2G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:isabs))]) && S_time <= $t1 - $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1G, :l2G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = ($t2 - $t1) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); :l2G) - #struct $(generate_edge_type(:l1G, :l2G, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1G, :l2G, 4)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1G, :l2G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:isabs))]) && ($t1 <= S_time <= $t2) - $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1G, :l2G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + ($t2 - S_time) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); :l2G) - #struct $(generate_edge_type(:l1G, :l2G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1G, :l2G, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && S_time >= $t2 - $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2G) - #struct $(generate_edge_type(:l1G, :l2G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1G, :l2G, 2)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && S_time >= $t2 - $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * ($t2 - $t1); :l2G) =# # l3G loc # l3G => l1G - #struct $(generate_edge_type(:l3G, :l1G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l3G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(generate_edge_type(:l3G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l3G, :l1G, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l3G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l3G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var_G)]; S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p, x); :l1G) # l3G => l2G - #struct $(generate_edge_type(:l3G, :l2G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l3G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l3G, :l2G, 2)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l3G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && (S_time >= $t2 || istrue(S_values[$(to_idx(:isabs))])) - $(update_state!)(edge::$(generate_edge_type(:l3G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l3G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * ($t2 - $t1); :l2G) - #struct $(generate_edge_type(:l3G, :l2G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l3G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l3G, :l2G, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l3G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && (S_time >= $t2 || istrue(S_values[$(to_idx(:isabs))])) - $(update_state!)(edge::$(generate_edge_type(:l3G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l3G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2G) # l4G loc # l4G => l1G - #struct $(generate_edge_type(:l4G, :l1G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l4G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(generate_edge_type(:l4G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l4G, :l1G, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l4G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l4G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:tprime))] * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); S_values[$(to_idx(:tprime))] = 0.0; S_values[$(to_idx(:n))] = x[$(idx_obs_var_G)]; @@ -211,25 +218,25 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float :l1G) # l4G => l2G - #struct $(generate_edge_type(:l4G, :l2G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l4G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l4G, :l2G, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l4G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (istrue(S_values[$(to_idx(:isabs))])) - $(update_state!)(edge::$(generate_edge_type(:l4G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l4G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + ($t2 - S_time) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); :l2G) - #struct $(generate_edge_type(:l4G, :l2G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l4G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l4G, :l2G, 2)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l4G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t2) - $(update_state!)(edge::$(generate_edge_type(:l4G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l4G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:tprime))] * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); :l2G) # Connection between the two automata: l2G => l1F - #struct $(generate_edge_type(:l2G, :l1F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l2G, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(generate_edge_type(:l2G, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l2G, :l1F, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l2G, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l2G, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var_F)]; S_values[$(to_idx(:dprime))] = Inf; S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p, x); @@ -237,80 +244,81 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float # l1F loc : we con#struct the edges of the form l1F => (..) # l1F => l2F - #struct $(generate_edge_type(:l1F, :l2F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1F, :l2F, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_time >= $t3 && S_values[$(to_idx(:dprime))] == 0 - $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (#S_values[$(to_idx(:dprime))] = 0; :l2F) - #struct $(generate_edge_type(:l1F, :l2F, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1F, :l2F, 2)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1F, :l2F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t4) && (S_values[$(to_idx(:n))] < $x3 || S_values[$(to_idx(:n))] > $x4) - $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1F, :l2F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (#S_values[$(to_idx(:dprime))] = min(abs(S_values[$(to_idx(:n))] - $x3), abs(S_values[$(to_idx(:n))] - $x4)); S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:dprime))]; :l2F) #= - #struct $(generate_edge_type(:l1F, :l2F, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1F, :l2F, 3)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1F, :l2F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:isabs))]) && S_time <= $t4 - $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1F, :l2F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:dprime))]; :l2F) - #struct $(generate_edge_type(:l1F, :l2F, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1F, :l2F, 4)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1F, :l2F, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_time >= $t3 && S_values[$(to_idx(:dprime))] == 0 - $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1F, :l2F, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2F) =# # l1F => l3F - #struct $(generate_edge_type(:l1F, :l3F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1F, :l3F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1F, :l3F, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1F, :l3F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time <= $t3) && (S_values[$(to_idx(:n))] < $x3 || S_values[$(to_idx(:n))] > $x4) - $(update_state!)(edge::$(generate_edge_type(:l1F, :l3F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1F, :l3F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:dprime))] = min(sqrt((S_time - $t3)^2 + (S_values[$(to_idx(:n))] - $x4)^2), sqrt((S_time - $t3)^2 + (S_values[$(to_idx(:n))] - $x3)^2)); :l3F) - #struct $(generate_edge_type(:l1F, :l3F, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1F, :l3F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1F, :l3F, 2)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1F, :l3F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = ($x3 <= S_values[$(to_idx(:n))] <= $x4) - $(update_state!)(edge::$(generate_edge_type(:l1F, :l3F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1F, :l3F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:dprime))] = 0; :l3F) - #struct $(generate_edge_type(:l1F, :l3F, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l1F, :l3F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1F, :l3F, 3)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l1F, :l3F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t3) && (S_values[$(to_idx(:n))] < $x3 || S_values[$(to_idx(:n))] > $x4) - $(update_state!)(edge::$(generate_edge_type(:l1F, :l3F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1F, :l3F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:dprime))] = min(S_values[$(to_idx(:dprime))], min(abs(S_values[$(to_idx(:n))] - $x3), abs(S_values[$(to_idx(:n))] - $x4))); :l3F) # l3F loc # l3F => l1F - #struct $(generate_edge_type(:l3F, :l1F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l3F, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(generate_edge_type(:l3F, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l3F, :l1F, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l3F, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l3F, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var_F)]; S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p, x); :l1F) # l3F => l2F - #struct $(generate_edge_type(:l3F, :l2F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(generate_edge_type(:l3F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l3F, :l2F, 1)) <: $(edge_type) transitions::TransitionSet end + @everywhere $(check_constraints(:l3F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t4 || istrue(S_values[$(to_idx(:isabs))])) - $(update_state!)(edge::$(generate_edge_type(:l3F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l3F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:dprime))]; :l2F) end + eval(meta_funcs) @eval begin map_edges = Dict{Location, Dict{Location, Vector{$(edge_type)}}}() @@ -320,91 +328,114 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float # l0G loc # l0G => l1G - edge1 = $(generate_edge_type(:l0G, :l1G, 1))(nothing) + edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l0G, :l1G, 1)), $(update_state!(:l0G, :l1G, 1))) map_edges[:l0G][:l1G] = [edge1] # l1G => l3G - edge1 = $(generate_edge_type(:l1G, :l3G, 1))(nothing) - edge2 = $(generate_edge_type(:l1G, :l3G, 2))(nothing) - edge3 = $(generate_edge_type(:l1G, :l3G, 3))(nothing) - edge4 = $(generate_edge_type(:l1G, :l3G, 4))(nothing) + edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 1)), $(update_state!(:l1G, :l3G, 1))) + edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 2)), $(update_state!(:l1G, :l3G, 2))) + edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 3)), $(update_state!(:l1G, :l3G, 3))) + edge4 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 4)), $(update_state!(:l1G, :l3G, 4))) map_edges[:l1G][:l3G] = [edge1, edge2, edge3, edge4] # l1G => l4G - edge1 = $(generate_edge_type(:l1G, :l4G, 1))(nothing) - edge2 = $(generate_edge_type(:l1G, :l4G, 2))(nothing) + edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l4G, 1)), $(update_state!(:l1G, :l4G, 1))) + edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l4G, 2)), $(update_state!(:l1G, :l4G, 2))) map_edges[:l1G][:l4G] = [edge1, edge2] # l1G => l2G #= - edge1 = $(generate_edge_type(:l1G, :l2G, 1))(nothing) - edge2 = $(generate_edge_type(:l1G, :l2G, 2))(nothing) - edge3 = $(generate_edge_type(:l1G, :l2G, 3))(nothing) - edge4 = $(generate_edge_type(:l1G, :l2G, 4))(nothing) + edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 1)), $(update_state!(:l1G, :l2G, 1))) + edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 2)), $(update_state!(:l1G, :l2G, 2))) + edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 3)), $(update_state!(:l1G, :l2G, 3))) + edge4 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 4)), $(update_state!(:l1G, :l2G, 4))) map_edges[:l1G][:l2G] = [edge3, edge4, edge1, edge2] =# # l3G loc # l3G => l1G - edge1 = $(generate_edge_type(:l3G, :l1G, 1))([:ALL]) + edge1 = EdgeAutomatonGandF([:ALL], $(check_constraints(:l3G, :l1G, 1)), $(update_state!(:l3G, :l1G, 1))) map_edges[:l3G][:l1G] = [edge1] # l3G => l2G - edge1 = $(generate_edge_type(:l3G, :l2G, 1))(nothing) - edge2 = $(generate_edge_type(:l3G, :l2G, 2))(nothing) + edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l3G, :l2G, 1)), $(update_state!(:l3G, :l2G, 1))) + edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l3G, :l2G, 2)), $(update_state!(:l3G, :l2G, 2))) map_edges[:l3G][:l2G] = [edge1, edge2] # l4 loc # l4G => l1G - edge1 = $(generate_edge_type(:l4G, :l1G, 1))([:ALL]) + edge1 = EdgeAutomatonGandF([:ALL], $(check_constraints(:l4G, :l1G, 1)), $(update_state!(:l4G, :l1G, 1))) map_edges[:l4G][:l1G] = [edge1] # l4G => l2G - edge1 = $(generate_edge_type(:l4G, :l2G, 1))(nothing) - edge2 = $(generate_edge_type(:l4G, :l2G, 2))(nothing) + edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l4G, :l2G, 1)), $(update_state!(:l4G, :l2G, 1))) + edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l4G, :l2G, 2)), $(update_state!(:l4G, :l2G, 2))) map_edges[:l4G][:l2G] = [edge1,edge2] # l2G loc # l2G => l1F : Transition from autF to autG - edge1 = $(generate_edge_type(:l2G, :l1F, 1))(nothing) + edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l2G, :l1F, 1)), $(update_state!(:l2G, :l1F, 1))) map_edges[:l2G][:l1F] = [edge1] # l1F loc # l1F => l3F - edge1 = $(generate_edge_type(:l1F, :l2F, 1))(nothing) - edge2 = $(generate_edge_type(:l1F, :l2F, 2))(nothing) + edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 1)), $(update_state!(:l1F, :l2F, 1))) + edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 2)), $(update_state!(:l1F, :l2F, 2))) map_edges[:l1F][:l2F] = [edge1, edge2] - #edge3 = $(generate_edge_type(:l1F, :l2F, 3))(nothing) - #edge4 = $(generate_edge_type(:l1F, :l2F, 4))(nothing) + #edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 3)), $(update_state!(:l1F, :l2F, 3))) + #edge4 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 4)), $(update_state!(:l1F, :l2F, 4))) #map_edges[:l1F][:l2F] = [edge1, edge4, edge3, edge2] # l1F => l3F - edge1 = $(generate_edge_type(:l1F, :l3F, 1))(nothing) - edge2 = $(generate_edge_type(:l1F, :l3F, 2))(nothing) - edge3 = $(generate_edge_type(:l1F, :l3F, 3))(nothing) + edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l3F, 1)), $(update_state!(:l1F, :l3F, 1))) + edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l3F, 2)), $(update_state!(:l1F, :l3F, 2))) + edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l3F, 3)), $(update_state!(:l1F, :l3F, 3))) map_edges[:l1F][:l3F] = [edge1, edge2, edge3] # l3F loc # l3F => l1F - edge1 = $(generate_edge_type(:l3F, :l1F, 1))([:ALL]) + edge1 = EdgeAutomatonGandF([:ALL], $(check_constraints(:l3F, :l1F, 1)), $(update_state!(:l3F, :l1F, 1))) map_edges[:l3F][:l1F] = [edge1] # l3F => l2F - edge1 = $(generate_edge_type(:l3F, :l2F, 1))(nothing) + edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l3F, :l2F, 1)), $(update_state!(:l3F, :l2F, 1))) map_edges[:l3F][:l2F] = [edge1] end + ## Create data separately + map_edges_transitions = Dict{Symbol, Dict{Symbol,Vector{TransitionSet}}}() + map_edges_check_constraints = Dict{Symbol, Dict{Symbol,Vector{CheckConstraintsFunction}}}() + map_edges_update_state = Dict{Symbol, Dict{Symbol,Vector{UpdateStateFunction}}}() + for from_loc in keys(map_edges) + map_edges_transitions[from_loc] = Dict{Symbol,Vector{TransitionSet}}() + map_edges_check_constraints[from_loc] = Dict{Symbol,Vector{CheckConstraintsFunction}}() + map_edges_update_state[from_loc] = Dict{Symbol,Vector{UpdateStateFunction}}() + for to_loc in keys(map_edges[from_loc]) + map_edges_transitions[from_loc][to_loc] = TransitionSet[] + map_edges_check_constraints[from_loc][to_loc] = CheckConstraintsFunction[] + map_edges_update_state[from_loc][to_loc] = UpdateStateFunction[] + for edge in map_edges[from_loc][to_loc] + push!(map_edges_transitions[from_loc][to_loc], edge.transitions) + push!(map_edges_check_constraints[from_loc][to_loc], edge.check_constraints) + push!(map_edges_update_state[from_loc][to_loc], edge.update_state!) + end + end + end + ## Constants constants = Dict{Symbol,Float64}(:x1 => x1, :x2 => x2, :t1 => t1, :t2 => t2, :x3 => x3, :x4 => x4, :t3 => t3, :t4 => t4) - # Updating types and simulation methods + # Updating types and simulation method @everywhere @eval $(MarkovProcesses.generate_code_synchronized_model_type_def(model_name, lha_name)) - @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type, check_constraints, update_state!)) + @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type)) + #@everywhere @eval $(MarkovProcesses.generate_code_next_state_with_dicts(lha_name, edge_type)) @everywhere @eval $(MarkovProcesses.generate_code_synchronized_simulation(model_name, lha_name, edge_type, m.f!, m.isabsorbing)) A = AutomatonGandF(m.transitions, locations, Λ_F, locations_init, locations_final, - map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx) + map_var_automaton_idx, flow, map_edges, + map_edges_transitions, map_edges_check_constraints, map_edges_update_state, + constants, m.map_var_idx) return A end diff --git a/automata/euclidean_distance_automaton.jl b/automata/euclidean_distance_automaton.jl index ae3ace3f7d9ccca2e5ba651538a447ee840b1f90..be7b1c07e15d29f5d536c99bc9ec41f7141d4a86 100644 --- a/automata/euclidean_distance_automaton.jl +++ b/automata/euclidean_distance_automaton.jl @@ -1,6 +1,11 @@ # Creation of the automaton types -@everywhere @eval abstract type EdgeEuclideanDistanceAutomaton <: Edge end +#@everywhere @eval abstract type EdgeEuclideanDistanceAutomaton <: Edge end +@everywhere struct EdgeEuclideanDistanceAutomaton <: Edge + transitions::TransitionSet + check_constraints::CheckConstraintsFunction + update_state!::UpdateStateFunction +end @everywhere @eval $(MarkovProcesses.generate_code_lha_type_def(:EuclideanDistanceAutomaton, :EdgeEuclideanDistanceAutomaton)) function create_euclidean_distance_automaton(m::ContinuousTimeModel, timeline::AbstractVector{Float64}, observations::AbstractVector{Float64}, sym_obs::VariableModel) @@ -43,14 +48,20 @@ function create_euclidean_distance_automaton(m::ContinuousTimeModel, timeline::A basename_func = "$(model_name)_$(id)" edge_name(from_loc::Location, to_loc::Location, edge_number::Int) = Symbol("Edge_$(lha_name)_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)") - + function check_constraints(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("check_constraints_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") + end + function update_state!(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("update_state_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)!") + end + ## check_constraints & update_state! - @everywhere @eval begin + meta_funcs = quote # l0 loc # l0 => l1 - struct $(edge_name(:l0, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l0, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(:l0, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l0, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l0, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l0, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var)]; S_values[$(to_idx(:d))] = 0.0; S_values[$(to_idx(:idx))] = 1.0; @@ -59,32 +70,33 @@ function create_euclidean_distance_automaton(m::ContinuousTimeModel, timeline::A # l1 loc # l1 => l1 # Defined below - struct $(edge_name(:l1, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (tml = $(Tuple(timeline)); tml_idx = tml[convert(Int, S_values[$(to_idx(:idx))])]; S_values[$(to_idx(:t))] >= tml_idx) - $(update_state!)(edge::$(edge_name(:l1, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (y_obs = $(Tuple(observations)); y_obs_idx = y_obs[convert(Int, S_values[$(to_idx(:idx))])]; S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))]+(S_values[$(to_idx(:n))]-y_obs_idx)^2; S_values[$(to_idx(:idx))] = S_values[$(to_idx(:idx))]+1.0; :l1) - struct $(edge_name(:l1, :l1, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l1, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(:l1, :l1, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l1, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l1, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l1, :l1, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var)]; :l1) # l1 => l2 - struct $(edge_name(:l1, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l1, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l1, :l2, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l1, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:idx))] >= ($nbr_observations + 1) - $(update_state!)(edge::$(edge_name(:l1, :l2, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l1, :l2, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = sqrt(S_values[$(to_idx(:d))]); :l2) end + eval(meta_funcs) @eval begin map_edges = Dict{Location,Dict{Location,Vector{$(edge_type)}}}() @@ -95,20 +107,24 @@ function create_euclidean_distance_automaton(m::ContinuousTimeModel, timeline::A ## Edges # l0 loc # l0 => l1 - edge1 = $(edge_name(:l0, :l1, 1))(nothing) + edge1 = EdgeEuclideanDistanceAutomaton(nothing, $(check_constraints(:l0, :l1, 1)), $(update_state!(:l0, :l1, 1))) map_edges[:l0][:l1] = [edge1] # l1 loc # l1 => l1 - edge1 = $(edge_name(:l1, :l1, 1))(nothing) - edge2 = $(edge_name(:l1, :l1, 2))([:ALL]) + edge1 = EdgeEuclideanDistanceAutomaton(nothing, $(check_constraints(:l1, :l1, 1)), $(update_state!(:l1, :l1, 1))) + edge2 = EdgeEuclideanDistanceAutomaton([:ALL], $(check_constraints(:l1, :l1, 2)), $(update_state!(:l1, :l1, 2))) map_edges[:l1][:l1] = [edge1, edge2] # l1 => l2 - edge1 = $(edge_name(:l1, :l2, 1))(nothing) + edge1 = EdgeEuclideanDistanceAutomaton(nothing, $(check_constraints(:l1, :l2, 1)), $(update_state!(:l1, :l2, 1))) map_edges[:l1][:l2] = [edge1] end + map_edges_transitions = Dict{Symbol, Dict{Symbol,Vector{TransitionSet}}}() + map_edges_check_constraints = Dict{Symbol, Dict{Symbol,Vector{CheckConstraintsFunction}}}() + map_edges_update_state = Dict{Symbol, Dict{Symbol,Vector{UpdateStateFunction}}}() + ## Constants constants = Dict{Symbol,Float64}(:nbr_obs => nbr_observations) for i = 1:nbr_observations @@ -118,11 +134,13 @@ function create_euclidean_distance_automaton(m::ContinuousTimeModel, timeline::A # Updating types and simulation methods @everywhere @eval $(MarkovProcesses.generate_code_synchronized_model_type_def(model_name, lha_name)) - @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type, check_constraints, update_state!)) + @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type)) @everywhere @eval $(MarkovProcesses.generate_code_synchronized_simulation(model_name, lha_name, edge_type, m.f!, m.isabsorbing)) A = EuclideanDistanceAutomaton(m.transitions, locations, Λ_F, locations_init, locations_final, - map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx) + map_var_automaton_idx, flow, + map_edges, map_edges_transitions, map_edges_check_constraints, map_edges_update_state, + constants, m.map_var_idx) return A end diff --git a/automata/euclidean_distance_automaton_2.jl b/automata/euclidean_distance_automaton_2.jl index ceb7d52eca326070062bfbb11483df93db8f7ffe..c3dfaa4c5863145026de47634fd80eae2dc77ce2 100644 --- a/automata/euclidean_distance_automaton_2.jl +++ b/automata/euclidean_distance_automaton_2.jl @@ -1,6 +1,11 @@ # Creation of the automaton types -@everywhere @eval abstract type EdgeEuclideanDistanceAutomaton2 <: Edge end +#@everywhere @eval abstract type EdgeEuclideanDistanceAutomaton2 <: Edge end +@everywhere struct EdgeEuclideanDistanceAutomaton2 <: Edge + transitions::TransitionSet + check_constraints::CheckConstraintsFunction + update_state!::UpdateStateFunction +end @everywhere @eval $(MarkovProcesses.generate_code_lha_type_def(:EuclideanDistanceAutomaton2,:EdgeEuclideanDistanceAutomaton2)) function create_euclidean_distance_automaton_2(m::ContinuousTimeModel, timeline::AbstractVector{Float64}, observations::AbstractVector{Float64}, sym_obs::VariableModel) @@ -48,99 +53,104 @@ function create_euclidean_distance_automaton_2(m::ContinuousTimeModel, timeline: basename_func = "$(model_name)_$(id)" edge_name(from_loc::Location, to_loc::Location, edge_number::Int) = Symbol("Edge_$(lha_name)_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)") + function check_constraints(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("check_constraints_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") + end + function update_state!(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("update_state_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)!") + end loc_nbr_obs = Symbol("l$(nbr_observations)") - @everywhere @eval begin + meta_funcs = quote # l0 loc # l0 => l1 - @everywhere struct $(edge_name(:l0, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l0, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - @everywhere $(update_state!)(edge::$(edge_name(:l0, :l1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l0, :l1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l0, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(:l0, :l1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var)]; S_values[$(to_idx(:d))] = 0.0; :l1) # lnbr_obs => lfinal - @everywhere struct $(edge_name(loc_nbr_obs, :lfinal, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(loc_nbr_obs, :lfinal, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(loc_nbr_obs, :lfinal, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(loc_nbr_obs, :lfinal, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:t))] >= $(timeline[nbr_observations]) - @everywhere $(update_state!)(edge::$(edge_name(loc_nbr_obs, :lfinal, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(loc_nbr_obs, :lfinal, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))]+(S_values[$(to_idx(:n))]-$(observations[nbr_observations]))^2; S_values[$(to_idx(:d))] = sqrt(S_values[$(to_idx(:d))]); :lfinal) # lnbr_obs => lnbr_obs - @everywhere struct $(edge_name(loc_nbr_obs, loc_nbr_obs, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(loc_nbr_obs, loc_nbr_obs, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - @everywhere $(update_state!)(edge::$(edge_name(loc_nbr_obs, loc_nbr_obs, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(loc_nbr_obs, loc_nbr_obs, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(loc_nbr_obs, loc_nbr_obs, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(loc_nbr_obs, loc_nbr_obs, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var)]; $(Meta.quot(loc_nbr_obs))) end + eval(meta_funcs) @eval begin map_edges = Dict{Location,Dict{Location,Vector{$(edge_type)}}}() for loc in $(locations) map_edges[loc] = Dict{Location,Vector{$(edge_type)}}() end - + # l0 loc # l0 => l1 - edge1 = $(edge_name(:l0, :l1, 1))(nothing) + edge1 = EdgeEuclideanDistanceAutomaton2(nothing, $(check_constraints(:l0, :l1, 1)), $(update_state!(:l0, :l1, 1))) map_edges[:l0][:l1] = [edge1] # lnbr_obs => lfinal - edge1 = $(edge_name(loc_nbr_obs, :lfinal, 1))(nothing) + edge1 = EdgeEuclideanDistanceAutomaton2(nothing, $(check_constraints(loc_nbr_obs, :lfinal, 1)), $(update_state!(loc_nbr_obs, :lfinal, 1))) map_edges[$(Meta.quot(loc_nbr_obs))][:lfinal] = [edge1] # lnbr_obs => lnbr_obs - edge1 = $(edge_name(loc_nbr_obs, loc_nbr_obs, 1))([:ALL]) + edge1 = EdgeEuclideanDistanceAutomaton2([:ALL], $(check_constraints(loc_nbr_obs, loc_nbr_obs, 1)), $(update_state!(loc_nbr_obs, loc_nbr_obs, 1))) map_edges[$(Meta.quot(loc_nbr_obs))][$(Meta.quot(loc_nbr_obs))] = [edge1] end - function generate_code_loci_functions(i::Int, loci::Symbol, locip1::Symbol) - return quote - struct $(edge_name(loci, locip1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(loci, locip1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + for i = 1:(nbr_observations-1) + loci = Symbol("l$(i)") + locip1 = Symbol("l$(i+1)") + meta_funcs = quote + #struct $(edge_name(loci, locip1, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(loci, locip1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:t))] >= $(timeline[i]) - $(update_state!)(edge::$(edge_name(loci, locip1, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(loci, locip1, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))]+(S_values[$(to_idx(:n))]-$(observations[i]))^2; $(Meta.quot(locip1))) - struct $(edge_name(loci, loci, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(loci, loci, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(loci, loci, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(loci, loci, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(loci, loci, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(update_state!(loci, loci, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var)]; $(Meta.quot(loci))) end + eval(meta_funcs) + + # loci => loci+1 + edge1 = EdgeEuclideanDistanceAutomaton2(nothing, getfield(Main, check_constraints(loci, locip1, 1)), getfield(Main, update_state!(loci, locip1, 1))) + map_edges[loci][locip1] = [edge1] + # loci => loci + edge1 = EdgeEuclideanDistanceAutomaton2([:ALL], getfield(Main, check_constraints(loci, loci, 1)), getfield(Main, update_state!(loci, loci, 1))) + map_edges[loci][loci] = [edge1] end - function generate_code_loci_edges(loci::Symbol, locip1::Symbol) - return quote - # loci => loci+1 - edge1 = $(edge_name(loci, locip1, 1))(nothing) - map_edges[$(Meta.quot(loci))][$(Meta.quot(locip1))] = [edge1] - # loci => loci - edge1 = $(edge_name(loci, loci, 1))([:ALL]) - map_edges[$(Meta.quot(loci))][$(Meta.quot(loci))] = [edge1] - end - end - - for i = 1:(nbr_observations-1) - loci = Symbol("l$(i)") - locip1 = Symbol("l$(i+1)") - @everywhere @eval $(generate_code_loci_functions(i, loci, locip1)) - @everywhere @eval $(generate_code_loci_edges(loci, locip1)) - end - ## Constants constants = Dict{Symbol,Float64}(:nbr_obs => nbr_observations) + map_edges_transitions = Dict{Symbol, Dict{Symbol,Vector{TransitionSet}}}() + map_edges_check_constraints = Dict{Symbol, Dict{Symbol,Vector{CheckConstraintsFunction}}}() + map_edges_update_state = Dict{Symbol, Dict{Symbol,Vector{UpdateStateFunction}}}() + # Updating types and simulation methods @everywhere @eval $(MarkovProcesses.generate_code_synchronized_model_type_def(model_name, lha_name)) - @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type, check_constraints, update_state!)) + @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type)) @everywhere @eval $(MarkovProcesses.generate_code_synchronized_simulation(model_name, lha_name, edge_type, m.f!, m.isabsorbing)) A = EuclideanDistanceAutomaton2(m.transitions, locations, Λ_F, locations_init, locations_final, - map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx) + map_var_automaton_idx, flow, + map_edges, map_edges_transitions, map_edges_check_constraints, map_edges_update_state, + constants, m.map_var_idx) return A end diff --git a/automata/period_automaton.jl b/automata/period_automaton.jl index 3b99d94034633d269e0f87aa5e0e8506ce8bd472..5c84347469a04f5aa8cf40c02e76b55039a06b98 100644 --- a/automata/period_automaton.jl +++ b/automata/period_automaton.jl @@ -9,7 +9,12 @@ abs(mean_tp - ref_mean_tp) # Creation of the automaton types -@everywhere @eval abstract type EdgePeriodAutomaton <: Edge end +#@everywhere @eval abstract type EdgePeriodAutomaton <: Edge end +@everywhere struct EdgePeriodAutomaton <: Edge + transitions::TransitionSet + check_constraints::CheckConstraintsFunction + update_state!::UpdateStateFunction +end @everywhere @eval $(MarkovProcesses.generate_code_lha_type_def(:PeriodAutomaton, :EdgePeriodAutomaton)) function create_period_automaton(m::ContinuousTimeModel, L::Float64, H::Float64, N::Int, sym_obs::VariableModel; @@ -66,30 +71,36 @@ function create_period_automaton(m::ContinuousTimeModel, L::Float64, H::Float64, idx_obs_var = getfield(m, :map_var_idx)[sym_obs] edge_name(from_loc::Location, to_loc::Location, edge_number::Int) = Symbol("Edge_$(lha_name)_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)") + function check_constraints(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("check_constraints_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") + end + function update_state!(from_loc::Location, to_loc::Location, edge_number::Int) + return Symbol("update_state_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)!") + end ## check_constraints & update_state! - @everywhere @eval begin + meta_funcs = quote # l0 loc # * l0 => l0 - struct $(edge_name(:l0, :l0, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l0, :l0, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l0, :l0, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l0, :l0, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(:l0, :l0, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l0, :l0, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l0) # * l0 => l0prime - struct $(edge_name(:l0, :l0prime, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l0, :l0prime, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l0, :l0prime, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l0, :l0prime, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:t))] >= $initT - $(update_state!)(edge::$(edge_name(:l0, :l0prime, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l0, :l0prime, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = Inf; :l0prime) # * l0 => low - struct $(edge_name(:l0, :low, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l0, :low, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l0, :low, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l0, :low, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:t))] >= $initT - $(update_state!)(edge::$(edge_name(:l0, :low, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l0, :low, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:t))] = 0.0; S_values[$(to_idx(:top))] = 0.0; S_values[$(to_idx(:n))] = -1; @@ -99,17 +110,17 @@ function create_period_automaton(m::ContinuousTimeModel, L::Float64, H::Float64, # l0prime # * l0prime => l0prime - struct $(edge_name(:l0prime, :l0prime, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l0prime, :l0prime, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l0prime, :l0prime, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l0prime, :l0prime, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(:l0prime, :l0prime, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l0prime, :l0prime, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l0prime) # * l0prime => low - struct $(edge_name(:l0prime, :low, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:l0prime, :low, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:l0prime, :low, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:l0prime, :low, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!)(edge::$(edge_name(:l0prime, :low, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:l0prime, :low, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:t))] = 0.0; S_values[$(to_idx(:top))] = 0.0; S_values[$(to_idx(:n))] = -1; @@ -118,61 +129,61 @@ function create_period_automaton(m::ContinuousTimeModel, L::Float64, H::Float64, # low # * low => low - struct $(edge_name(:low, :low, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:low, :low, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:low, :low, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:low, :low, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] < $N - $(update_state!)(edge::$(edge_name(:low, :low, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:low, :low, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:low) # * low => mid - struct $(edge_name(:low, :mid, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:low, :mid, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:low, :mid, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:low, :mid, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] < $N - $(update_state!)(edge::$(edge_name(:low, :mid, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:low, :mid, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:mid) # * low => final - struct $(edge_name(:low, :final, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:low, :final, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:low, :final, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:low, :final, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] == $N - $(update_state!)(edge::$(edge_name(:low, :final, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:low, :final, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (val_d = $(error_func)(S_values[$(to_idx(:mean_tp))], S_values[$(to_idx(:var_tp))], $(ref_mean_tp), $(ref_var_tp)); S_values[$(to_idx(:d))] = val_d; - :final) + :final) # mid # * mid => mid - struct $(edge_name(:mid, :mid, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:mid, :mid, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:mid, :mid, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:mid, :mid, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] < $N - $(update_state!)(edge::$(edge_name(:mid, :mid, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:mid, :mid, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:mid) # * mid => low - struct $(edge_name(:mid, :low, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:mid, :low, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:mid, :low, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:mid, :low, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] < $N && S_values[$(to_idx(:top))] == 0.0 - $(update_state!)(edge::$(edge_name(:mid, :low, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:mid, :low, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:low) - struct $(edge_name(:mid, :low, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:mid, :low, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:mid, :low, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:mid, :low, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] == -1.0 && S_values[$(to_idx(:top))] == 1.0 - $(update_state!)(edge::$(edge_name(:mid, :low, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:mid, :low, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = S_values[$(to_idx(:n))] + 1; S_values[$(to_idx(:top))] = 0.0; S_values[$(to_idx(:tp))] = 0.0; :low) - struct $(edge_name(:mid, :low, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:mid, :low, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:mid, :low, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:mid, :low, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] == 0.0) && S_values[$(to_idx(:top))] == 1.0 - $(update_state!)(edge::$(edge_name(:mid, :low, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:mid, :low, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = S_values[$(to_idx(:n))] + 1; S_values[$(to_idx(:top))] = 0.0; S_values[$(to_idx(:mean_tp))] = f_mean_tp(S_values[$(to_idx(:mean_tp))], @@ -181,11 +192,11 @@ function create_period_automaton(m::ContinuousTimeModel, L::Float64, H::Float64, S_values[$(to_idx(:tp))] = 0.0; :low) - struct $(edge_name(:mid, :low, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:mid, :low, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:mid, :low, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:mid, :low, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (1 <= S_values[$(to_idx(:n))] < $N) && S_values[$(to_idx(:top))] == 1.0 - $(update_state!)(edge::$(edge_name(:mid, :low, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:mid, :low, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = S_values[$(to_idx(:n))] + 1; S_values[$(to_idx(:top))] = 0.0; S_values[$(to_idx(:var_tp))] = g_var_tp(S_values[$(to_idx(:var_tp))], @@ -199,50 +210,51 @@ function create_period_automaton(m::ContinuousTimeModel, L::Float64, H::Float64, :low) # * mid => high - struct $(edge_name(:mid, :high, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:mid, :high, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:mid, :high, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:mid, :high, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] < $N - $(update_state!)(edge::$(edge_name(:mid, :high, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:mid, :high, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:top))] = 1.0; :high) # * mid => final - struct $(edge_name(:mid, :final, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:mid, :final, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:mid, :final, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:mid, :final, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] == $N - $(update_state!)(edge::$(edge_name(:mid, :final, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:mid, :final, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (val_d = $(error_func)(S_values[$(to_idx(:mean_tp))], S_values[$(to_idx(:var_tp))], $(ref_mean_tp), $(ref_var_tp)); S_values[$(to_idx(:d))] = val_d; - :final) + :final) # high # * high => high - struct $(edge_name(:high, :high, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:high, :high, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:high, :high, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:high, :high, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] < $N - $(update_state!)(edge::$(edge_name(:high, :high, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:high, :high, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:high) # * high => mid - struct $(edge_name(:high, :mid, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:high, :mid, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:high, :mid, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:high, :mid, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] < $N - $(update_state!)(edge::$(edge_name(:high, :mid, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:high, :mid, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:mid) # * high => final - struct $(edge_name(:high, :final, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end - $(check_constraints)(edge::$(edge_name(:high, :final, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(edge_name(:high, :final, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + @everywhere $(check_constraints(:high, :final, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_values[$(to_idx(:n))] == $N - $(update_state!)(edge::$(edge_name(:high, :final, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + @everywhere $(update_state!(:high, :final, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (val_d = $(error_func)(S_values[$(to_idx(:mean_tp))], S_values[$(to_idx(:var_tp))], $(ref_mean_tp), $(ref_var_tp)); S_values[$(to_idx(:d))] = val_d; - :final) + :final) end + eval(meta_funcs) @eval begin map_edges = Dict{Location, Dict{Location, Vector{$(edge_type)}}}() @@ -252,73 +264,80 @@ function create_period_automaton(m::ContinuousTimeModel, L::Float64, H::Float64, # l0 loc # * l0 => l0 - edge1 = $(edge_name(:l0, :l0, 1))([:ALL]) + edge1 = EdgePeriodAutomaton([:ALL], $(check_constraints(:l0, :l0, 1)), $(update_state!(:l0, :l0, 1))) map_edges[:l0][:l0] = [edge1] # * l0 => l0prime - edge1 = $(edge_name(:l0, :l0prime, 1))(nothing) + edge1 = EdgePeriodAutomaton(nothing, $(check_constraints(:l0, :l0prime, 1)), $(update_state!(:l0, :l0prime, 1))) map_edges[:l0][:l0prime] = [edge1] # * l0 => low - edge1 = $(edge_name(:l0, :low, 1))(nothing) + edge1 = EdgePeriodAutomaton(nothing, $(check_constraints(:l0, :low, 1)), $(update_state!(:l0, :low, 1))) map_edges[:l0][:low] = [edge1] # l0prime # * l0prime => l0prime - edge1 = $(edge_name(:l0prime, :l0prime, 1))([:ALL]) + edge1 = EdgePeriodAutomaton([:ALL], $(check_constraints(:l0prime, :l0prime, 1)), $(update_state!(:l0prime, :l0prime, 1))) map_edges[:l0prime][:l0prime] = [edge1] # * l0prime => low - edge1 = $(edge_name(:l0prime, :low, 1))(nothing) + edge1 = EdgePeriodAutomaton(nothing, $(check_constraints(:l0prime, :low, 1)), $(update_state!(:l0prime, :low, 1))) map_edges[:l0prime][:low] = [edge1] # low # * low => low - edge1 = $(edge_name(:low, :low, 1))([:ALL]) + edge1 = EdgePeriodAutomaton([:ALL], $(check_constraints(:low, :low, 1)), $(update_state!(:low, :low, 1))) map_edges[:low][:low] = [edge1] # * low => mid - edge1 = $(edge_name(:low, :mid, 1))([:ALL]) + edge1 = EdgePeriodAutomaton([:ALL], $(check_constraints(:low, :mid, 1)), $(update_state!(:low, :mid, 1))) map_edges[:low][:mid] = [edge1] # * low => final - edge1 = $(edge_name(:low, :final, 1))(nothing) + edge1 = EdgePeriodAutomaton(nothing, $(check_constraints(:low, :final, 1)), $(update_state!(:low, :final, 1))) map_edges[:low][:final] = [edge1] # mid # * mid => mid - edge1 = $(edge_name(:mid, :mid, 1))([:ALL]) + edge1 = EdgePeriodAutomaton([:ALL], $(check_constraints(:mid, :mid, 1)), $(update_state!(:mid, :mid, 1))) map_edges[:mid][:mid] = [edge1] # * mid => low - edge1 = $(edge_name(:mid, :low, 1))([:ALL]) - edge2 = $(edge_name(:mid, :low, 2))([:ALL]) - edge3 = $(edge_name(:mid, :low, 3))([:ALL]) - edge4 = $(edge_name(:mid, :low, 4))([:ALL]) + edge1 = EdgePeriodAutomaton([:ALL], $(check_constraints(:mid, :low, 1)), $(update_state!(:mid, :low, 1))) + edge2 = EdgePeriodAutomaton([:ALL], $(check_constraints(:mid, :low, 2)), $(update_state!(:mid, :low, 2))) + edge3 = EdgePeriodAutomaton([:ALL], $(check_constraints(:mid, :low, 3)), $(update_state!(:mid, :low, 3))) + edge4 = EdgePeriodAutomaton([:ALL], $(check_constraints(:mid, :low, 4)), $(update_state!(:mid, :low, 4))) map_edges[:mid][:low] = [edge1, edge2, edge3, edge4] # * mid => high - edge1 = $(edge_name(:mid, :high, 1))([:ALL]) + edge1 = EdgePeriodAutomaton([:ALL], $(check_constraints(:mid, :high, 1)), $(update_state!(:mid, :high, 1))) map_edges[:mid][:high] = [edge1] # * mid => final - edge1 = $(edge_name(:mid, :final, 1))(nothing) + edge1 = EdgePeriodAutomaton(nothing, $(check_constraints(:mid, :final, 1)), $(update_state!(:mid, :final, 1))) map_edges[:mid][:final] = [edge1] # high # * high => high - edge1 = $(edge_name(:high, :high, 1))([:ALL]) + edge1 = EdgePeriodAutomaton([:ALL], $(check_constraints(:high, :high, 1)), $(update_state!(:high, :high, 1))) map_edges[:high][:high] = [edge1] # * high => mid - edge1 = $(edge_name(:high, :mid, 1))([:ALL]) + edge1 = EdgePeriodAutomaton([:ALL], $(check_constraints(:high, :mid, 1)), $(update_state!(:high, :mid, 1))) map_edges[:high][:mid] = [edge1] # * high => final - edge1 = $(edge_name(:high, :final, 1))(nothing) + edge1 = EdgePeriodAutomaton(nothing, $(check_constraints(:high, :final, 1)), $(update_state!(:high, :final, 1))) map_edges[:high][:final] = [edge1] end + ## Create data separately + map_edges_transitions = Dict{Symbol, Dict{Symbol,Vector{TransitionSet}}}() + map_edges_check_constraints = Dict{Symbol, Dict{Symbol,Vector{CheckConstraintsFunction}}}() + map_edges_update_state = Dict{Symbol, Dict{Symbol,Vector{UpdateStateFunction}}}() + ## Constants constants = Dict{Symbol,Float64}(:N => N, :L => L, :H => H, :initT => initT) # Updating types and simulation methods @everywhere @eval $(MarkovProcesses.generate_code_synchronized_model_type_def(model_name, lha_name)) - @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type, check_constraints, update_state!)) + @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type)) @everywhere @eval $(MarkovProcesses.generate_code_synchronized_simulation(model_name, lha_name, edge_type, m.f!, m.isabsorbing)) A = PeriodAutomaton(m.transitions, locations, Λ_F, locations_init, locations_final, - map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx) + map_var_automaton_idx, flow, map_edges, + map_edges_transitions, map_edges_check_constraints, map_edges_update_state, + constants, m.map_var_idx) return A end diff --git a/bench/pkg/sim_sync_R6.jl b/bench/pkg/sim_sync_R6.jl index ab5984a18741f5954700ae6179ebe8c532ae9a4f..9af292a4d886eab4caa3aa826ba67e6bde7b7f82 100644 --- a/bench/pkg/sim_sync_R6.jl +++ b/bench/pkg/sim_sync_R6.jl @@ -1,6 +1,6 @@ using BenchmarkTools -using MarkovProcesses +@everywhere using MarkovProcesses using Profile load_model("ER") diff --git a/core/MarkovProcesses.jl b/core/MarkovProcesses.jl index 257be50be470f153d944f878680fb0467a245490..e9f285cf83b2695d64eee87d2231d4b64665db79 100644 --- a/core/MarkovProcesses.jl +++ b/core/MarkovProcesses.jl @@ -10,17 +10,19 @@ import Distributed: @everywhere, @distributed import Distributions: Product, Uniform, Normal import Distributions: Distribution, Univariate, Continuous, UnivariateDistribution, MultivariateDistribution, product_distribution +import FunctionWrappers: FunctionWrapper import StaticArrays: SVector, @SVector ## Exports export Distribution, Product, Uniform, Normal # Common types and constructors -export Observations, AbstractTrajectory, Trajectory, SynchronizedTrajectory export SVector, @SVector +export Observations, AbstractTrajectory, Trajectory, SynchronizedTrajectory export Model, ContinuousTimeModel, SynchronizedModel, ParametricModel export VariableModel, ParameterModel, Transition, TransitionSet export LHA, StateLHA, Edge, Location, VariableAutomaton +export InvariantPredicateFunction, CheckConstraintsFunction, UpdateStateFunction # Trajectory related methods export +, -, δ, dist_lp, euclidean_distance diff --git a/core/common.jl b/core/common.jl index 4a501df49cbc18fc0bfc4bfc8eff803b0d11246e..960c6f90d70cef1ecb9f3a14680a040cc9f8dcd5 100644 --- a/core/common.jl +++ b/core/common.jl @@ -11,8 +11,12 @@ abstract type Edge end const VariableModel = Symbol const ParameterModel = Symbol const Transition = Union{Symbol,Nothing} +const TransitionSet = Union{Vector{Symbol},Nothing} const Location = Symbol const VariableAutomaton = Symbol +const InvariantPredicateFunction = FunctionWrapper{Bool,Tuple{Vector{Int}}} +const CheckConstraintsFunction = FunctionWrapper{Bool,Tuple{Float64,Vector{Float64},Vector{Int},Vector{Float64}}} +const UpdateStateFunction = FunctionWrapper{Symbol,Tuple{Float64,Vector{Float64},Vector{Int},Vector{Float64}}} function generate_code_model_type_def(model_name::Symbol) return quote @@ -49,12 +53,15 @@ function generate_code_lha_type_def(lha_name::Symbol, edge_type::Symbol) struct $(lha_name) <: LHA transitions::Vector{Transition} locations::Vector{Location} - Λ::Dict{Location,Function} + Λ::Dict{Location,InvariantPredicateFunction} locations_init::Vector{Location} locations_final::Vector{Location} map_var_automaton_idx::Dict{VariableAutomaton,Int} # nvar keys : str_var => idx in values flow::Dict{Location,Vector{Float64}} # output of length nvar map_edges::Dict{Location, Dict{Location,Vector{$(edge_type)}}} + map_edges_transitions::Dict{Location, Dict{Location,Vector{TransitionSet}}} + map_edges_check_constraints::Dict{Location, Dict{Location,Vector{CheckConstraintsFunction}}} + map_edges_update_state::Dict{Location, Dict{Location,Vector{UpdateStateFunction}}} constants::Dict{Symbol,Float64} map_var_model_idx::Dict{VariableModel,Int} # of dim d (of a model) end @@ -129,7 +136,9 @@ end LHA(A::LHA, map_var::Dict{VariableModel,Int}) = getfield(Main, Symbol(typeof(A)))(A.transitions, A.locations, A.Λ, A.locations_init, A.locations_final, - A.map_var_automaton_idx, A.flow, A.map_edges, A.constants, map_var) + A.map_var_automaton_idx, A.flow, A.map_edges, + A.map_edges_transitions, A.map_edges_check_constraints, A.map_edges_update_state, + A.constants, map_var) function ParametricModel(am::Model, priors::Tuple{ParameterModel,UnivariateDistribution}...) m = get_proba_model(am) diff --git a/core/lha.jl b/core/lha.jl index 8f5fcc5f1d9514aae63417bee8a3c8e96071086c..fb81e59b80073ddf8eab128a68f871d837c60f89 100644 --- a/core/lha.jl +++ b/core/lha.jl @@ -90,8 +90,234 @@ function init_state(A::LHA, x0::Vector{Int}, t0::Float64) return S0 end -function generate_code_next_state(lha_name::Symbol, edge_type::Symbol, - check_constraints::Symbol, update_state!::Symbol) +function generate_code_next_state_with_dicts_lha(lha_name::Symbol, edge_type::Symbol) + + return quote + # A push! method implementend by myself because of preallocation of edge_candidates + function _push_edge!(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}, + edge_id::Int, target_loc::Symbol, nbr_candidates::Int) + if nbr_candidates < length(edge_id_candidates) + edge_id_candidates[nbr_candidates+1] = edge_id + target_loc_candidates[nbr_candidates+1] = target_loc + else + push!(edge_id_candidates, edge_id) + push!(target_loc_candidates, target_loc) + end + end + + function _find_edge_candidates!(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}, + dict_transitions_from_current_loc::Dict{Location,Vector{TransitionSet}}, + dict_check_constraints_from_current_loc::Dict{Location,Vector{Function}}, + Λ::Dict{Location,InvariantPredicateFunction}, + S_time::Float64, S_values::Vector{Float64}, + x::Vector{Int}, p::Vector{Float64}, + only_asynchronous::Bool) + nbr_candidates = 0 + for target_loc in keys(dict_transitions_from_current_loc) + if !Λ[target_loc](x) continue end + for i = eachindex(dict_transitions_from_current_loc[target_loc]) + check_constraints_edge = dict_check_constraints_from_current_loc[target_loc][i] + if check_constraints_edge(S_time, S_values, x, p) + transitions = dict_transitions_from_current_loc[target_loc][i] + if transitions == nothing + _push_edge!(edge_id_candidates, target_loc_candidates, i, target_loc, nbr_candidates) + nbr_candidates += 1 + return nbr_candidates + else + if !only_asynchronous + _push_edge!(edge_id_candidates, target_loc_candidates, i, target_loc, nbr_candidates) + nbr_candidates += 1 + end + end + end + end + end + return nbr_candidates + end + + function _get_edge_index(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}, nbr_candidates::Int, + dict_transitions_from_current_loc::Dict{Location,Vector{TransitionSet}}, + detected_event::Bool, tr_nplus1::Transition) + ind_edge = 0 + bool_event = detected_event + for i = 1:nbr_candidates + target_loc = target_loc_candidates[i] + edge_id = edge_id_candidates[i] + transitions = dict_transitions_from_current_loc[target_loc][edge_id] + # Asynchronous edge detection: we fire it + if transitions == nothing + return (i, detected_event) + end + # Synchronous detection + if !detected_event && tr_nplus1 != nothing + if (transitions[1] == :ALL) || (tr_nplus1 in transitions) + ind_edge = i + bool_event = true + end + end + end + return (ind_edge, bool_event) + end + + function next_state!(A::$(lha_name), + ptr_loc_state::Vector{Symbol}, values_state::Vector{Float64}, ptr_time_state::Vector{Float64}, + xnplus1::Vector{Int}, tnplus1::Float64, tr_nplus1::Transition, + xn::Vector{Int}, p::Vector{Float64}, + edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}; verbose::Bool = false) + # En fait d'apres observation de Cosmos, après qu'on ait lu la transition on devrait stop. + detected_event::Bool = false + turns = 0 + Λ = getfield(A, :Λ) + flow = getfield(A, :flow) + map_edges = A.map_edges + map_edges_transitions = A.map_edges_transitions + map_edges_check_constraints = A.map_edges_check_constraints + map_edges_update_state = A.map_edges_update_state + if verbose + println("##### Begin next_state!") + @show xnplus1, tnplus1, tr_nplus1 + end + # First, we check the asynchronous transitions + while true + turns += 1 + if verbose @show turns end + #edge_candidates = empty!(edge_candidates) + dict_transitions_from_current_loc = map_edges_transitions[ptr_loc_state[1]] + dict_check_constraints_from_current_loc = map_edges_check_constraints[ptr_loc_state[1]] + # Save all edges that satisfies transition predicate (asynchronous ones) + nbr_candidates = _find_edge_candidates!(edge_id_candidates, target_loc_candidates, + dict_transitions_from_current_loc, dict_check_constraints_from_current_loc, + Λ, ptr_time_state[1], values_state, xn, p, true) + # Search the one we must chose, here the event is nothing because + # we're not processing yet the next event + ind_edge, detected_event = _get_edge_index(edge_id_candidates, target_loc_candidates, nbr_candidates, + dict_transitions_from_current_loc, + detected_event, nothing) + # Update the state with the chosen one (if it exists) + # Should be xn here + #first_round = false + if ind_edge > 0 + edge_target_loc = target_loc_candidates[ind_edge] + edge_id = edge_id_candidates[ind_edge] + firing_update_state! = map_edges_update_state[ptr_loc_state[1]][edge_target_loc][edge_id] + ptr_loc_state[1] = firing_update_state!(ptr_time_state[1], values_state, xn, p) + else + if verbose + println("No edge fired:") + @show ind_edge, detected_event, nbr_candidates + end + break + end + if verbose + println("Edge fired:") + @show edge_id_candidates, target_loc_candidates + @show ind_edge, detected_event, nbr_candidates + @show ptr_loc_state[1] + @show ptr_time_state[1] + @show values_state + if turns == 500 + @warn "We've reached 500 turns" + end + end + # For debug + #= + if turns > 100 + println("Number of turns in next_state! is suspicious") + @show first_round, detected_event + @show length(edge_candidates) + @show tnplus1, tr_nplus1, xnplus1 + @show edge_candidates + error("Unpredicted behavior automaton") + end + =# + end + if verbose + println("Time flies with the flow...") + end + # Now time flies according to the flow + for i in eachindex(values_state) + coeff_deriv = flow[ptr_loc_state[1]][i] + if coeff_deriv > 0 + values_state[i] += coeff_deriv*(tnplus1 - ptr_time_state[1]) + end + end + ptr_time_state[1] = tnplus1 + if verbose + @show ptr_loc_state[1] + @show ptr_time_state[1] + @show values_state + end + # Now firing an edge according to the event + while true + turns += 1 + if verbose @show turns end + edges_from_current_loc = map_edges[ptr_loc_state[1]] + dict_transitions_from_current_loc = map_edges_transitions[ptr_loc_state[1]] + dict_check_constraints_from_current_loc = map_edges_check_constraints[ptr_loc_state[1]] + # Save all edges that satisfies transition predicate (synchronous ones) + nbr_candidates = _find_edge_candidates!(edge_id_candidates, target_loc_candidates, + dict_transitions_from_current_loc, dict_check_constraints_from_current_loc, + Λ, ptr_time_state[1], values_state, xnplus1, p, false) + # Search the one we must chose + ind_edge, detected_event = _get_edge_index(edge_id_candidates, target_loc_candidates, nbr_candidates, + dict_transitions_from_current_loc, + detected_event, tr_nplus1) + # Update the state with the chosen one (if it exists) + if ind_edge > 0 + edge_target_loc = target_loc_candidates[ind_edge] + edge_id = edge_id_candidates[ind_edge] + firing_update_state! = map_edges_update_state[ptr_loc_state[1]][edge_target_loc][edge_id] + ptr_loc_state[1] = firing_update_state!(ptr_time_state[1], values_state, xnplus1, p) + end + if ind_edge == 0 || detected_event + if verbose + if detected_event + println("Synchronized with $(tr_nplus1)") + @show edge_id_candidates, target_loc_candidates + @show ind_edge, detected_event, nbr_candidates + @show detected_event + @show ptr_loc_state[1] + @show ptr_time_state[1] + @show values_state + else + println("No edge fired") + end + end + break + end + if verbose + @show edge_id_candidates, target_loc_candidates + @show ind_edge, detected_event, nbr_candidates + @show detected_event + @show ptr_loc_state[1] + @show ptr_time_state[1] + @show values_state + if turns == 500 + @warn "We've reached 500 turns" + end + end + # For debug + #= + if turns > 100 + println("Number of turns in next_state! is suspicious") + @show detected_event + @show length(edge_candidates) + @show tnplus1, tr_nplus1, xnplus1 + @show edge_candidates + error("Unpredicted behavior automaton") + end + =# + end + if verbose + println("##### End next_state!") + end + end + end +end + +############################################################################################################ + +function generate_code_next_state(lha_name::Symbol, edge_type::Symbol) return quote # A push! method implementend by myself because of preallocation of edge_candidates @@ -105,7 +331,7 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol, function _find_edge_candidates!(edge_candidates::Vector{$(edge_type)}, edges_from_current_loc::Dict{Location,Vector{$(edge_type)}}, - Λ::Dict{Location,Function}, + Λ::Dict{Location,InvariantPredicateFunction}, S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}, only_asynchronous::Bool) @@ -113,8 +339,8 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol, for target_loc in keys(edges_from_current_loc) if !Λ[target_loc](x) continue end for edge in edges_from_current_loc[target_loc] - if $(check_constraints)(edge, S_time, S_values, x, p) - if getfield(edge, :transitions) == nothing + if edge.check_constraints(S_time, S_values, x, p) + if edge.transitions == nothing _push_edge!(edge_candidates, edge, nbr_candidates) nbr_candidates += 1 return nbr_candidates @@ -137,13 +363,12 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol, for i = 1:nbr_candidates edge = edge_candidates[i] # Asynchronous edge detection: we fire it - if getfield(edge, :transitions) == nothing + if edge.transitions == nothing return (i, detected_event) end # Synchronous detection if !detected_event && tr_nplus1 != nothing - if (getfield(edge, :transitions)[1] == :ALL) || - (tr_nplus1 in getfield(edge, :transitions)) + if (edge.transitions[1] == :ALL) || (tr_nplus1 in edge.transitions) ind_edge = i bool_event = true end @@ -184,7 +409,7 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol, #first_round = false if ind_edge > 0 firing_edge = edge_candidates[ind_edge] - ptr_loc_state[1] = $(update_state!)(firing_edge, ptr_time_state[1], values_state, xn, p) + ptr_loc_state[1] = firing_edge.update_state!(ptr_time_state[1], values_state, xn, p) else if verbose println("No edge fired") end break @@ -240,7 +465,7 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol, # Update the state with the chosen one (if it exists) if ind_edge > 0 firing_edge = edge_candidates[ind_edge] - ptr_loc_state[1] = $(update_state!)(firing_edge, ptr_time_state[1], values_state, xnplus1, p) + ptr_loc_state[1] = firing_edge.update_state!(ptr_time_state[1], values_state, xnplus1, p) end if ind_edge == 0 || detected_event if verbose diff --git a/tests/automaton_abc/distributed_R1.jl b/tests/automaton_abc/distributed_R1.jl index 5fda0e80c3ac1a5068dd964100a06ea8fc6bb859..ecbece35a684a7ff22b7e4548750a84000b46032 100644 --- a/tests/automaton_abc/distributed_R1.jl +++ b/tests/automaton_abc/distributed_R1.jl @@ -1,12 +1,12 @@ -using Distributed using MarkovProcesses -begin_procs = nprocs() -if begin_procs == 1 - addprocs(2) -end -path_module = get_module_path() * "/core" - +using Distributed +addprocs(2) +module_path = get_module_path() +@everywhere module_path = $module_path +@everywhere push!(LOAD_PATH, "$(module_path)/core") +@everywhere using MarkovProcesses +#= @everywhere begin path_module = $(path_module) push!(LOAD_PATH, path_module) @@ -14,6 +14,9 @@ path_module = get_module_path() * "/core" load_model("ER") load_automaton("automaton_F") end +=# +load_model("ER") +load_automaton("automaton_F") A_F_R1 = create_automaton_F(ER, 50.0, 75.0, 0.025, 0.05, :P) sync_ER = A_F_R1*ER pm_sync_ER = ParametricModel(sync_ER, (:k3, Uniform(0.0, 100.0))) @@ -21,9 +24,7 @@ nbr_pa = 404 r = automaton_abc(pm_sync_ER; nbr_particles = nbr_pa) -if begin_procs == 1 - rmprocs(workers()) -end +rmprocs(2) test = size(r.mat_p_end)[1] == pm_sync_ER.df && size(r.mat_p_end)[2] == nbr_pa && diff --git a/tests/run_abc_smc.jl b/tests/run_abc_smc.jl index c92284053f2411c88850fd570d0fe9d5500f2541..8848094b1460ebd2bdd87d1afc5bc88f447130d7 100644 --- a/tests/run_abc_smc.jl +++ b/tests/run_abc_smc.jl @@ -3,7 +3,7 @@ using Test @testset "ABC SMC and automaton-ABC tests" begin @test include("automaton_abc/R1.jl") - #test_distributed_R1 = include("automaton_abc/distributed_R1.jl") + @test include("automaton_abc/distributed_R1.jl") #@test test_distributed_R1 end