diff --git a/automata/automaton_G_and_F.jl b/automata/automaton_G_and_F.jl index ba05cabdd66c062687176f6d69d57c1c12d32697..b1e65c3df47bafab38f60d1ceef7dbddb6af1499 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::Function + update_state!::Function +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, @@ -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) ## 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 + $(check_constraints(:l0G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(check_constraints(:l3G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(check_constraints(:l4G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(check_constraints(:l2G, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + $(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,77 +244,77 @@ 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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(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}) = + $(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 + $(check_constraints(:l3F, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + $(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 + $(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}) = + $(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 @@ -320,91 +327,113 @@ 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{Function}}}() + map_edges_update_state = Dict{Symbol, Dict{Symbol,Vector{Function}}}() + 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{Function}}() + map_edges_update_state[from_loc] = Dict{Symbol,Vector{Function}}() + 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] = Function[] + map_edges_update_state[from_loc][to_loc] = Function[] + 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.new_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 = 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/bench/pkg/abstract_array.jl b/bench/pkg/abstract_array.jl new file mode 100644 index 0000000000000000000000000000000000000000..2e163eeacad214bee3c34ae01238ff512a5f04c8 --- /dev/null +++ b/bench/pkg/abstract_array.jl @@ -0,0 +1,103 @@ + +using Profile +using StaticArrays +using BenchmarkTools + +println("Cost of tests:") +f_test(a::Int) = a == 2 +@btime for i = 1:20 + f_test(3) +end + +# First container type +abstract type SuperType end +for i = 1:10 + include_string(Main, "struct Type$i <: SuperType v::Symbol end") + include_string(Main, "f(item::Type$i, a::Int) = a == $(i)") +end +vec_types = SuperType[] +for i = 1:20 + rand_number_type = rand(1:10) + @eval item = $(Symbol("Type$(rand_number_type)"))(:test) + push!(vec_types, item) +end +println("First super type") +function read(vec_types::Vector{SuperType}, a::Int) + for item in vec_types + f(item, a) + end +end +@btime read(vec_types, 3) + +# Second container type +struct AnotherSuperType{T<:Function} + v::Symbol + f::T +end +vec_others_types = AnotherSuperType[] +for i = 1:20 + rand_number_type = rand(1:10) + include_string(Main, "f_other_$(i)(a::Int) = a == $(i)") + sym_func = Symbol("f_other_$i") + @eval push!(vec_others_types, AnotherSuperType(:test, $(sym_func))) +end +println("Second super type") +function read(vec_others_types::Vector{AnotherSuperType}, a::Int) + for item in vec_others_types + item.f(a) + end +end +@btime read(vec_others_types, 3) + +# With vectors +println("Transitions first:") +vec_tr = Union{Nothing,Symbol}[] +vec_func = Function[] +for i = 1:20 + rand_number_type = rand(1:10) + include_string(Main, "f_vec_$(i)(a::Int) = a == $(i)") + sym_func = Symbol("f_vec_$i") + push!(vec_tr, :test) + @eval push!(vec_func, $(sym_func)) +end +function read(vec_tr::Vector{Union{Nothing,Symbol}}, vec_func::Vector{Function}, a::Int) + for i = eachindex(vec_tr) + my_func = vec_func[i] + my_func(a) + end +end +@btime read(vec_tr, vec_func, 3) + +println("Transitions second:") +vec_tr = Union{Nothing,Symbol}[] +vec_func = Function[] +for i = 1:20 + rand_number_type = rand(1:10) + name_func = Symbol("f_vec2_$(i)") + str_func = "$(name_func)(a::Int) = a == $(rand_number_type)" + include_string(Main, str_func) + push!(vec_tr, :test) + @eval push!(vec_func, $(name_func)) +end +@btime read(vec_tr, vec_func, 3) + + +# How to store and read efficiently abstract types ? +d = Dict{Symbol,Dict{Symbol,Vector{Float64}}}() +for i = 1:10 + sym_a = Symbol("a$i") + sym_b = Symbol("a$i") + d[sym_a] = Dict{Symbol,Vector{Float64}}() + d[sym_a][sym_b] = zeros(4) +end +function f(dict::Dict) + for key in keys(dict) + for key2 in keys(dict[key]) + for i = eachindex(dict[key][key2]) + dict[key][key2][i] + end + end + end +end +@btime f(d) + diff --git a/bench/pkg/check_constraints_sync_R6.jl b/bench/pkg/check_constraints_sync_R6.jl new file mode 100644 index 0000000000000000000000000000000000000000..2f1976e62bb31a0ed7536f5a7c4397f44b845c5b --- /dev/null +++ b/bench/pkg/check_constraints_sync_R6.jl @@ -0,0 +1,222 @@ + +using StaticArrays +using BenchmarkTools +using MarkovProcesses +using Profile + +load_model("ER") +observe_all!(ER) +set_param!(ER, [:k1, :k2], [0.2, 40.0]) +set_time_bound!(ER, 0.9) + +load_automaton("automaton_G_and_F") +x1, x2, t1, t2 = 50.0, 100.0, 0.0, 0.8 +x3, x4, t3, t4 = 30.0, 100.0, 0.8, 0.9 +A_G_F = create_automaton_G_and_F(ER, x1, x2, t1, t2, :E, + x3, x4, t3, t4, :P) +sync_ER = ER * A_G_F + +S = init_state(A_G_F, ER.x0, ER.t0) +time = 0.1 +values = S.values +x, p = ER.x0, ER.p +for loc_from in keys(A_G_F.map_edges) + for loc_to in keys(A_G_F.map_edges[loc_from]) + println("$loc_from => $loc_to") + for i = eachindex(A_G_F.map_edges[loc_from][loc_to]) + println("edge $i:") + global global_edge = A_G_F.map_edges[loc_from][loc_to][i] + #@btime check_constraints_AutomatonGandF(global_edge, time, $(copy(values)), x, p) + #b = @benchmark check_constraints_AutomatonGandF(global_edge, time, $(copy(values)), x, p) + #@show mean(b).time, mean(b).memory + end + end +end + +function my_find_edge_candidates!(edge_candidates::Vector{EdgeAutomatonGandF}, + edges_from_current_loc::Dict{Location,Vector{EdgeAutomatonGandF}}, + Λ::Dict{Location,Function}, + S_time::Float64, S_values::Vector{Float64}, + x::Vector{Int}, p::Vector{Float64}, + only_asynchronous::Bool) + nbr_candidates = 0 + for target_loc in keys(edges_from_current_loc) + if !Λ[target_loc](x) continue end + for i = eachindex(edges_from_current_loc[target_loc]) + edge = edges_from_current_loc[target_loc][i] + test_cc = check_constraints_AutomatonGandF(edge, S_time, S_values, x, p) + if test_cc + if edge.transitions == nothing + _push_edge!(edge_candidates, edge, nbr_candidates) + nbr_candidates += 1 + return nbr_candidates + else + if !only_asynchronous + _push_edge!(edge_candidates, edge, nbr_candidates) + nbr_candidates += 1 + end + end + end + end + end + return nbr_candidates +end + +function svector_find_edge_candidates!(edge_candidates::Vector{EdgeAutomatonGandF}, + edges_from_current_loc::Dict, + Λ::Dict{Location,Function}, + S_time::Float64, S_values::Vector{Float64}, + x::Vector{Int}, p::Vector{Float64}, + only_asynchronous::Bool) + nbr_candidates = 0 + for target_loc in keys(edges_from_current_loc) + if !Λ[target_loc](x) continue end + for edge in edges_from_current_loc[target_loc] + test_cc = check_constraints_AutomatonGandF(edge, S_time, S_values, x, p) + if test_cc + if edge.transitions == nothing + _push_edge!(edge_candidates, edge, nbr_candidates) + nbr_candidates += 1 + return nbr_candidates + else + if !only_asynchronous + _push_edge!(edge_candidates, edge, nbr_candidates) + nbr_candidates += 1 + end + end + end + end + end + return nbr_candidates +end + + +edge_candidates = Vector{EdgeAutomatonGandF}(undef, 2) +edges_from_current_loc = getfield(A_G_F, :map_edges)[:l1G] +Λ = A_G_F.Λ + +function transform_dict_tuple(dict::Dict{Symbol,Dict{Symbol,Vector{EdgeAutomatonGandF}}}) + new_dict = Dict() + for from_loc in keys(dict) + for to_loc in keys(dict[from_loc]) + new_dict[from_loc] = (to_loc, dict[from_loc][to_loc]) + end + end + return new_dict +end +function transform_dict_static(dict::Dict{Symbol,Dict{Symbol,Vector{EdgeAutomatonGandF}}}) + new_dict = Dict{Symbol,Dict{Symbol,SVector}}() + for from_loc in keys(dict) + new_dict[from_loc] = Dict{Symbol,SVector}() + for to_loc in keys(dict[from_loc]) + d = dict[from_loc][to_loc] + new_dict[from_loc][to_loc] = SVector{length(d)}(d) + end + end + return new_dict +end +new_map_edges = transform_dict_tuple(A_G_F.map_edges) +new_edges_from_current_loc = new_map_edges[:l1G] +vec_edges = new_map_edges[:l1G][2] +#concrete_vec_edges = Vector{typeof(vec_edges[1])}(vec_edges) +svector_map_edges = transform_dict_static(A_G_F.map_edges) +svector_edges_from_current_loc = svector_map_edges[:l1G] +static_vec_edges = SVector{length(vec_edges)}(vec_edges) +tuple_edges = Tuple(vec_edges) + +println("Test of the current implementation") +@btime begin + for target_loc in keys(edges_from_current_loc) + for edge in edges_from_current_loc[target_loc] + test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p) + end + end +end +println("Test with pairs") +@btime begin + for pair_target_loc_edges in edges_from_current_loc + for edge in pair_target_loc_edges.second + test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p) + end + end +end +println("New map") +@btime begin + for target_loc_edges in new_edges_from_current_loc + for edge in new_edges_from_current_loc[2] + test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p) + end + end +end +println("Read of a edge vector 1 (collection iteration)") +@btime begin + for edge in vec_edges + test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p) + end +end +println("Read of a edge vector 2 (eachindex)") +@btime begin + for i = eachindex(vec_edges) + test_cc = check_constraints_AutomatonGandF(vec_edges[i], time, values, x, p) + end +end +println("Read of a edge vector 3 (steprange)") +@btime begin + for i = 1:length(vec_edges) + test_cc = check_constraints_AutomatonGandF(vec_edges[i], time, values, x, p) + end +end +println("Read of a edge vector 4 (steprange 2)") +nb_edges = length(vec_edges) +@btime begin + for i = 1:nb_edges + test_cc = check_constraints_AutomatonGandF(vec_edges[i], time, values, x, p) + end +end +println("Read of an edge vector 5 (static vectors)") +@btime begin + for i = eachindex(static_vec_edges) + test_cc = check_constraints_AutomatonGandF(static_vec_edges[i], time, values, x, p) + end +end +println("Read of an edge vector 6 (tuples)") +@show typeof(tuple_edges) +@btime begin + for i = eachindex(tuple_edges) + test_cc = check_constraints_AutomatonGandF(tuple_edges[i], time, values, x, p) + end +end +#= +println("Read of an edge vector 7 (concrete type)") +@show typeof(vec_edges) +@show typeof(concrete_vec_edges) +@btime begin + for edge in concrete_vec_edges + #test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p) + end +end +=# +println("Read of an edge vector 8 (concrete type v2)") +@show vec_edges +concrete_2_vec_edges = Vector{Union{Nothing,Vector{Symbol}}}([e.transitions for e in vec_edges]) +@btime begin + for i = eachindex(concrete_2_vec_edges) + concrete_2_vec_edges[i] + #test_cc = check_constraints_AutomatonGandF(edge, time, values, x, p) + end +end + +b_find = @benchmark _find_edge_candidates!(edge_candidates, edges_from_current_loc, Λ, time, values, x, p, false) +@show mean(b_find).time, mean(b_find).memory + +b_svector_find = @benchmark svector_find_edge_candidates!(edge_candidates, svector_edges_from_current_loc, Λ, time, values, x, p, false) +@show mean(b_svector_find).time, mean(b_svector_find).memory + +Profile.clear_malloc_data() +b_myfind = @benchmark my_find_edge_candidates!(edge_candidates, edges_from_current_loc, Λ, time, values, x, p, false) +@show mean(b_myfind).time, mean(b_myfind).memory + +#= +The problem is that in each step of these benchmarks, an abstract type is involved +=# + diff --git a/core/MarkovProcesses.jl b/core/MarkovProcesses.jl index 65f1a583a19a5f9e8bd02261500d1061aebda1b9..e848313a7be9671b38ee0dffe0eb9f9b9200dbf0 100644 --- a/core/MarkovProcesses.jl +++ b/core/MarkovProcesses.jl @@ -18,7 +18,7 @@ export Distribution, Product, Uniform, Normal # Common types and constructors export Observations, AbstractTrajectory, Trajectory, SynchronizedTrajectory export Model, ContinuousTimeModel, SynchronizedModel, ParametricModel -export VariableModel, ParameterModel, Transition +export VariableModel, ParameterModel, Transition, TransitionSet export LHA, StateLHA, Edge, Location, VariableAutomaton # Trajectory related methods diff --git a/core/common.jl b/core/common.jl index 4a501df49cbc18fc0bfc4bfc8eff803b0d11246e..c22a5837a5d29bee0bda72624af2abb8dd6a2f8b 100644 --- a/core/common.jl +++ b/core/common.jl @@ -11,6 +11,7 @@ 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 @@ -55,6 +56,9 @@ function generate_code_lha_type_def(lha_name::Symbol, edge_type::Symbol) 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{Function}}} + map_edges_update_state::Dict{Location, Dict{Location,Vector{Function}}} constants::Dict{Symbol,Float64} map_var_model_idx::Dict{VariableModel,Int} # of dim d (of a model) end diff --git a/core/lha.jl b/core/lha.jl index 8f5fcc5f1d9514aae63417bee8a3c8e96071086c..30fd1ec66047173409e082a96cc655aa51ec1a67 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,Function}, + 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 @@ -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/core/model.jl b/core/model.jl index ef32b376a21b8addc241cab52d2ac0af2c7124f4..9be33af0b5753618e4a1adb2b282781f6a979963 100644 --- a/core/model.jl +++ b/core/model.jl @@ -145,7 +145,9 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym time_bound = getfield(m, :time_bound) buffer_size = getfield(m, :buffer_size) estim_min_states = getfield(m, :estim_min_states) - edge_candidates = Vector{$(edge_type)}(undef, 2) + #edge_candidates = Vector{$(edge_type)}(undef, 2) + edge_id_candidates = zeros(Int, 2) + target_loc_candidates = Vector{Symbol}(undef, 2) # First alloc full_values = Vector{Vector{Int}}(undef, getfield(m, :dim_state)) for i = eachindex(full_values) full_values[i] = zeros(Int, estim_min_states) end @@ -164,7 +166,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym xn = copy(x0) tn = copy(t0) next_state!(A, ptr_loc_state, values_state, ptr_time_state, - x0, t0, nothing, x0, p_sim, edge_candidates; verbose = verbose) + x0, t0, nothing, x0, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) isabsorbing::Bool = $(isabsorbing)(p_sim,xn) isacceptedLHA::Bool = isaccepted(ptr_loc_state[1], A) # Alloc of vectors where we stock n+1 values @@ -180,7 +182,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym end if isabsorbing && !isacceptedLHA next_state!(A, ptr_loc_state, values_state, ptr_time_state, - xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose) + xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) end setfield!(S, :loc, ptr_loc_state[1]) setfield!(S, :time, ptr_time_state[1]) @@ -195,7 +197,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym break end n += 1 - next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose) + next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) copyto!(xn, vec_x) tn = l_t[1] tr_n = l_tr[1] @@ -214,7 +216,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym end if isabsorbing && !isacceptedLHA next_state!(A, ptr_loc_state, values_state, ptr_time_state, - xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose) + xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) end setfield!(S, :loc, ptr_loc_state[1]) setfield!(S, :time, ptr_time_state[1]) @@ -239,7 +241,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym i -= 1 break end - next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose) + next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) copyto!(xn, vec_x) tn = l_t[1] tr_n = l_tr[1] @@ -265,7 +267,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym end if isabsorbing && !isacceptedLHA next_state!(A, ptr_loc_state, values_state, ptr_time_state, - xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose) + xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) end setfield!(S, :loc, ptr_loc_state[1]) setfield!(S, :time, ptr_time_state[1]) @@ -280,13 +282,15 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym ptr_loc_state = [S.loc] values_state = S.values ptr_time_state = [S.time] - edge_candidates = Vector{$(edge_type)}(undef, 2) + #edge_candidates = Vector{$(edge_type)}(undef, 2) + edge_id_candidates = zeros(Int, 2) + target_loc_candidates = Vector{Symbol}(undef, 2) # Values at time n n = 1 xn = copy(x0) tn = copy(t0) next_state!(A, ptr_loc_state, values_state, ptr_time_state, - x0, t0, nothing, x0, p_sim, edge_candidates; verbose = verbose) + x0, t0, nothing, x0, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) isabsorbing::Bool = $(isabsorbing)(p_sim,xn) isacceptedLHA::Bool = isaccepted(ptr_loc_state[1], A) # Alloc of vectors where we stock n+1 values @@ -297,7 +301,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym if isabsorbing || isacceptedLHA if !isacceptedLHA next_state!(A, ptr_loc_state, values_state, ptr_time_state, - xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose) + xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) end setfield!(S, :loc, ptr_loc_state[1]) setfield!(S, :time, ptr_time_state[1]) @@ -314,7 +318,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym break end next_state!(A, ptr_loc_state, values_state, ptr_time_state, - vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose) + vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) copyto!(xn, vec_x) tn = l_t[1] tr_n = l_tr[1] @@ -323,7 +327,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym end if isabsorbing && !isacceptedLHA next_state!(A, ptr_loc_state, values_state, ptr_time_state, - xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose) + xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) end setfield!(S, :loc, ptr_loc_state[1]) setfield!(S, :time, ptr_time_state[1])