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 % Immediate-feedback self-loop: a departure that routes back to the same
41 % FCFS-family station and arrives as a class flagged in sn.immfeed must
42 % hold the server instead of re-queueing behind the waiting jobs. The
43 % departure half is computed with noPromote (see State.afterEventStation).
44 immfeed_selfloop_act = false;
45 if event_a{act}==EventType.DEP && node_p{act}==node_a{act} ...
46 && node_a{act}>=1 && node_a{act}<=sn.nnodes && sn.isstation(node_a{act}) ...
47 && isfield(sn,'immfeed') && ~isempty(sn.immfeed)
48 istA_if = sn.nodeToStation(node_a{act});
49 if istA_if>=1 && istA_if<=size(sn.immfeed,1) ...
50 && class_p{act}>=1 && class_p{act}<=size(sn.immfeed,2) ...
51 && sn.immfeed(istA_if, class_p{act})
52 immfeed_selfloop_act = true;
53 end
54 end
55 if update_cond_a
56 [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, [], immfeed_selfloop_act);
57 end
58
59 if isempty(enabled_next_states{act}{isf_a}) || isempty(rate_a{act})
60 continue
61 end
62
63 for ia=1:size(enabled_next_states{act}{isf_a},1) % for all possible new states, check if they are enabled
64 % if the transition cannot occur
65 if isnan(rate_a{act}(ia)) || rate_a{act}(ia) == 0 % handles degenerate rate values
66 % set the transition with a zero rate so that it is
67 % never selected
68 rate_a{act}(ia) = 1e-38; % ~ zero in 32-bit precision
69 end
70
71 if enabled_next_states{act}{isf_a}(ia,:) == -1 % hash not found
72 continue
73 end
74 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});
75
76 if rate_a{act}(ia)>0
77 if node_p{act} ~= local
78 if node_p{act} == node_a{act} %self-loop, active and passive are the same
79 isf_p = isf_a;
80 if update_cond_p
81 [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);
82 end
83 else % departure
84 isf_p = sn.nodeToStateful(node_p{act});
85 if update_cond_p
86 [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);
87 end
88 end
89 if ~isempty(enabled_next_states{act}{isf_p})
90 if sn.isstatedep(node_a{act},3)
91 prob_sync_p{act} = sync{act}.passive{1}.prob(cur_state, enabled_next_states{act}); %state-dependent
92 else
93 prob_sync_p{act} = sync{act}.passive{1}.prob;
94 end
95 else
96 prob_sync_p{act} = 0;
97 end
98 end
99 if ~isempty(enabled_next_states{act}{isf_a})
100 if node_p{act} == local
101 prob_sync_p{act} = 1;
102 end
103 if ~isnan(rate_a{act})
104 if all(~cellfun(@isempty,enabled_next_states{act}))
105 if event_a{act} == EventType.DEP
106 node_a_sf{act} = isf_a;
107 node_p_sf{act} = isf_p;
108 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};
109 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};
110 end
111 % simulate also self-loops as we need to log them
112 %if any(~cellfun(@isequal,new_state{act},cur_state))
113 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)
114 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}));
115 end
116 enabled_rates(ctr) = rate_a{act}(ia) * prob_sync_p{act};
117 enabled_sync(ctr) = act;
118 ctr = ctr + 1;
119 end
120 end
121 end
122 end
123 end
124end
125gctr_start = ctr;
126
127for gact=1:G % event at node ind with global side-effects
128 gind = gsync{gact}.active{1}.node; % get the active node (transition) from the gsync event
129 [enabled_next_states{A+gact}, outrate, outprob] = State.afterGlobalEvent(sn, gind, cur_state, gsync{gact}, isSimulation);
130 for ia=find(outrate .* outprob)
131 enabled_rates(ctr) = outrate(ia) * outprob(ia);
132 enabled_sync(ctr) = A+gact;
133 ctr = ctr + 1;
134 end
135end
136end
Definition Station.m:245