From 33319d9b443ec35ae59e19282b77efc7e101f02c Mon Sep 17 00:00:00 2001 From: Mahmoud Bentriou <mahmoud.bentriou@centralesupelec.fr> Date: Sun, 29 Nov 2020 19:10:57 +0100 Subject: [PATCH] Small improvment perf for next_state! of LHA --- core/lha.jl | 90 ++++++++++++++++++++++++++++----------------------- core/model.jl | 4 +-- 2 files changed, 51 insertions(+), 43 deletions(-) diff --git a/core/lha.jl b/core/lha.jl index e6f6680..3d670e3 100644 --- a/core/lha.jl +++ b/core/lha.jl @@ -33,9 +33,44 @@ function init_state(A::LHA, x0::Vector{Int}, t0::Float64) return S0 end +function _find_edge_candidates!(edge_candidates::Vector{Edge}, current_loc::Location, + A::LHA, Snplus1::StateLHA) + + for loc in A.l_loc + tuple_edges = (current_loc, loc) + if haskey(A.map_edges, tuple_edges) + for edge in A.map_edges[tuple_edges] + if edge.check_constraints(A, Snplus1) + push!(edge_candidates, edge) + end + end + end + end +end + +function _get_edge_index(edge_candidates::Vector{Edge}, first_round::Bool, + detected_event::Bool, tr_nplus1::Transition) + ind_edge = 0 + bool_event = detected_event + for i in eachindex(edge_candidates) + edge = edge_candidates[i] + if edge.transitions[1] == nothing + return (i, bool_event) + end + if first_round || !detected_event + if (length(edge.transitions) == 1 && tr_nplus1 != nothing && edge.transitions[1] == "ALL") || + (tr_nplus1 in edge.transitions) + ind_edge = i + bool_event = true + end + end + end + return (ind_edge, bool_event) +end + function next_state!(Snplus1::StateLHA, A::LHA, xnplus1::Vector{Int}, tnplus1::Float64, tr_nplus1::Transition, - Sn::StateLHA; verbose = false) + Sn::StateLHA; verbose::Bool = false) for i in eachindex(Snplus1.l_var) Snplus1.l_var[i] += (A.l_flow[Sn.loc])[i]*(tnplus1 - Sn.time) end @@ -43,61 +78,34 @@ function next_state!(Snplus1::StateLHA, A::LHA, # En fait d'apres observation de Cosmos, après qu'on ait lu la transition on devrait stop. edge_candidates = Edge[] - tuple_candidates = Tuple{Location, Location}[] - first_round = true - detected_event = (tr_nplus1 == nothing) ? true : false + first_round::Bool = true + detected_event::Bool = (tr_nplus1 == nothing) ? true : false turns = 1 while first_round || !detected_event || length(edge_candidates) > 0 - edge_candidates = Edge[] - tuple_candidates = Tuple{Location,Location}[] + edge_candidates = empty!(edge_candidates) current_loc = Snplus1.loc - if verbose - @show turns - end + if verbose @show turns end # Save all edges that satisfies transition predicate (synchronous or autonomous) - for loc in A.l_loc - tuple_edges = (current_loc, loc) - if haskey(A.map_edges, tuple_edges) - for edge in A.map_edges[tuple_edges] - if edge.check_constraints(A, Snplus1) - push!(edge_candidates, edge) - push!(tuple_candidates, tuple_edges) - end - end - end - end + _find_edge_candidates!(edge_candidates, current_loc, A, Snplus1) # Search the one we must chose - ind_edge = 0 - for (i, edge) in enumerate(edge_candidates) - if edge.transitions[1] == nothing - ind_edge = i - break - end - if first_round || !detected_event - if (length(edge.transitions) == 1 && tr_nplus1 != nothing && edge.transitions[1] == "ALL") || - (tr_nplus1 in edge.transitions) - detected_event = true - ind_edge = i - end - end - end + ind_edge, detected_event = _get_edge_index(edge_candidates, first_round, detected_event, tr_nplus1) # Update the state with the chosen one (if it exists) if ind_edge > 0 edge_candidates[ind_edge].update_state!(A, Snplus1, xnplus1) # Should add something like if edges_candidates[ind_edge].transition != nohting break end ?? end + if ind_edge == 0 break end if verbose - @show first_round, detected_event - @show tnplus1, tr_nplus1, xnplus1 + @show first_round detected_event + @show tnplus1 tr_nplus1 xnplus1 @show ind_edge @show edge_candidates @show tuple_candidates @show Snplus1 end - if ind_edge == 0 break end # For debug - if turns > 10 - println("Turns, Bad behavior of region2 automaton") + 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 @@ -105,14 +113,14 @@ function next_state!(Snplus1::StateLHA, A::LHA, for edge in edge_candidates @show edge.check_constraints(A, Snplus1) end - error("Unpredicted behavior automaton F v2") + error("Unpredicted behavior automaton") end turns += 1 first_round = false end end -# For debug purposes +# For tests purposes function read_trajectory(A::LHA, σ::Trajectory; verbose = false) A_new = LHA(A, (σ.m)._map_obs_var_idx) l_t = times(σ) diff --git a/core/model.jl b/core/model.jl index c1e39b1..eb95321 100644 --- a/core/model.jl +++ b/core/model.jl @@ -46,7 +46,7 @@ function simulate(m::ContinuousTimeModel; p::Union{Nothing,AbstractVector{Float6 transitions[1] = nothing # Values at time n n = 1 - xn = m.x0 # View for type stability + xn = m.x0 tn = m.t0 # at time n+1 isabsorbing::Bool = m.isabsorbing(p_sim,xn) @@ -144,7 +144,7 @@ function simulate(product::SynchronizedModel; p::Union{Nothing,AbstractVector{Fl S0 = init_state(A, m.x0, m.t0) # Values at time n n = 1 - xn = m.x0 # View for type stability + xn = m.x0 tn = m.t0 Sn = copy(S0) isabsorbing::Bool = m.isabsorbing(p_sim,xn) -- GitLab