LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_ssa_findenabled.m
1function [enabled_next_states,enabled_rates,enabled_sync,gctr_start,depRatesSamples,arvRatesSamples,outprob_a,outprob_p,rate_a,eventCache] = solver_ssa_findenabled(sn,node_a,enabled_next_states,cur_state,outprob_a,event_a,class_a,isSimulation,node_p,local,outprob_p,event_p,class_p,sync,gsync,depRatesSamples,samples_collected,arvRatesSamples,last_node_a,last_node_p,eventCache)
2enabled_sync = []; % row is action label, col1=rate, col2=new state
3enabled_rates = [];
4ctr = 1;
5A = length(sync);
6G = length(gsync);
7for act=1:A
8 isf_a = sn.nodeToStateful(node_a{act});
9 % try
10 % isf_p = sn.nodeToStateful(node_p{act});
11 % %update_cond_a = true;
12 % %enabled_next_states{act} = cur_state;
13 % if isempty(enabled_next_states{act}) || ...
14 % isempty(enabled_next_states{act}{isf_a})|| ...
15 % isempty(enabled_next_states{act}{isf_p}) || ...
16 % length(cur_state) < max(isf_a,isf_p)
17 % % no data or a lot has changed
18 % enabled_next_states{act} = cur_state;
19 % update_cond_a = true;
20 % elseif sn.nodetype(node_p{act}) == NodeType.Cache
21 % enabled_next_states{act} = cur_state;
22 % update_cond_a = true;
23 % elseif (isf_a == isf_p) || (length(cur_state{isf_a}) == length(cur_state_1{isf_a}) && ...
24 % length(cur_state{isf_p}) == length(cur_state_1{isf_p}) && ...
25 % all(cur_state{isf_a}==cur_state_1{isf_a}) && ...
26 % all(cur_state{isf_p}==cur_state_1{isf_p}))
27 % % active is unchanged
28 % enabled_next_states{act}{isf_p} = cur_state{isf_p};
29 % update_cond_a = false;
30 % else
31 % enabled_next_states{act} = cur_state;
32 % update_cond_a = true;
33 % end
34 % catch
35 % enabled_next_states{act} = cur_state;
36 % update_cond_a = true;
37 % end
38 enabled_next_states{act} = cur_state;
39 update_cond_a = true;
40 if update_cond_a
41 [enabled_next_states{act}{isf_a}, rate_a{act}, outprob_a{act}, eventCache] = State.afterEvent(sn, node_a{act}, cur_state{isf_a}, event_a{act}, class_a{act}, isSimulation, eventCache);
42 end
43
44 if isempty(enabled_next_states{act}{isf_a}) || isempty(rate_a{act})
45 continue
46 end
47
48 for ia=1:size(enabled_next_states{act}{isf_a},1) % for all possible new states, check if they are enabled
49 % if the transition cannot occur
50 if isnan(rate_a{act}(ia)) || rate_a{act}(ia) == 0 % handles degenerate rate values
51 % set the transition with a zero rate so that it is
52 % never selected
53 rate_a{act}(ia) = 1e-38; % ~ zero in 32-bit precision
54 end
55
56 if enabled_next_states{act}{isf_a}(ia,:) == -1 % hash not found
57 continue
58 end
59 update_cond_p = true; %samples_collected == 1 || ((node_p{act} == last_node_a || node_p{act} == last_node_p)) || isempty(outprob_a{act}) || isempty(outprob_p{act});
60
61 if rate_a{act}(ia)>0
62 if node_p{act} ~= local
63 if node_p{act} == node_a{act} %self-loop, active and passive are the same
64 isf_p = isf_a;
65 if update_cond_p
66 [enabled_next_states{act}{isf_p}, ~, outprob_p{act}, eventCache] = State.afterEvent(sn, node_p{act}, enabled_next_states{act}{isf_p}, event_p{act}, class_p{act}, isSimulation, eventCache);
67 end
68 else % departure
69 isf_p = sn.nodeToStateful(node_p{act});
70 if update_cond_p
71 [enabled_next_states{act}{isf_p}, ~, outprob_p{act}, eventCache] = State.afterEvent(sn, node_p{act}, enabled_next_states{act}{isf_p}, event_p{act}, class_p{act}, isSimulation, eventCache);
72 end
73 end
74 if ~isempty(enabled_next_states{act}{isf_p})
75 if sn.isstatedep(node_a{act},3)
76 prob_sync_p{act} = sync{act}.passive{1}.prob(cur_state, enabled_next_states{act}); %state-dependent
77 else
78 prob_sync_p{act} = sync{act}.passive{1}.prob;
79 end
80 else
81 prob_sync_p{act} = 0;
82 end
83 end
84 if ~isempty(enabled_next_states{act}{isf_a})
85 if node_p{act} == local
86 prob_sync_p{act} = 1;
87 end
88 if ~isnan(rate_a{act})
89 if all(~cellfun(@isempty,enabled_next_states{act}))
90 if event_a{act} == EventType.DEP
91 node_a_sf{act} = isf_a;
92 node_p_sf{act} = isf_p;
93 depRatesSamples(samples_collected,node_a_sf{act},class_a{act}) = depRatesSamples(samples_collected,node_a_sf{act},class_a{act}) + outprob_a{act} * outprob_p{act} * rate_a{act}(ia) * prob_sync_p{act};
94 arvRatesSamples(samples_collected,node_p_sf{act},class_p{act}) = arvRatesSamples(samples_collected,node_p_sf{act},class_p{act}) + outprob_a{act} * outprob_p{act} * rate_a{act}(ia) * prob_sync_p{act};
95 end
96 % simulate also self-loops as we need to log them
97 %if any(~cellfun(@isequal,new_state{act},cur_state))
98 if node_p{act} < local && ~sn.csmask(class_a{act}, class_p{act}) && sn.nodetype(node_p{act})~=NodeType.Source && (rate_a{act}(ia) * prob_sync_p{act} >0)
99 line_error(mfilename,sprintf('Error: state-dependent routing at node %d (%s) violates the class switching mask (node %d -> node %d, class %d -> class %d).', node_a{act}, sn.nodenames{node_a{act}}, node_a{act}, node_p{act}, class_a{act}, class_p{act}));
100 end
101 enabled_rates(ctr) = rate_a{act}(ia) * prob_sync_p{act};
102 enabled_sync(ctr) = act;
103 ctr = ctr + 1;
104 end
105 end
106 end
107 end
108 end
109end
110gctr_start = ctr;
111
112for gact=1:G % event at node ind with global side-effects
113 gind = gsync{gact}.active{1}.node; % get the active node (transition) from the gsync event
114 [enabled_next_states{A+gact}, outrate, outprob] = State.afterGlobalEvent(sn, gind, cur_state, gsync{gact}, isSimulation);
115 for ia=find(outrate .* outprob)
116 enabled_rates(ctr) = outrate(ia) * outprob(ia);
117 enabled_sync(ctr) = A+gact;
118 ctr = ctr + 1;
119 end
120end
121end