LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
afterEvent.m
1function [outspace, outrate, outprob, eventCache] = afterEvent(sn, ind, inspace, event, class, isSimulation, eventCache)
2% [OUTSPACE, OUTRATE, OUTPROB] = AFTEREVENT(QN, IND, INSPACE, EVENT, CLASS, ISSIMULATION, EVENTCACHE)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6
7% Event cache for faster simulation
8if isSimulation && nargin >= 7 && isobject(eventCache)
9 vector = [ind, event, class, inspace];
10 key = mat2str(vector);
11 if eventCache.isKey(key)
12 cachedResult = eventCache(key);
13 outprob = cachedResult{1};
14 outspace = cachedResult{2};
15 outrate = cachedResult{3};
16 if size(outspace,1) > 1
17 tot_rate = sum(outrate);
18 cum_rate = cumsum(outrate) / tot_rate;
19 firing_ctr = 1 + max([0,find( rand > cum_rate' )]); % select action
20 outspace = outspace(firing_ctr,:);
21 outrate = sum(outrate);
22 outprob = outprob(firing_ctr,:);
23 end
24 return
25 end
26else
27 key = NaN;
28 eventCache = [];
29end
30% Else continue to main body below
31M = sn.nstations;
32R = sn.nclasses;
33S = sn.nservers;
34phasessz = sn.phasessz;
35phaseshift = sn.phaseshift;
36pie = sn.pie;
37
38% ind: node index
39isf = sn.nodeToStateful(ind);
40
41if sn.isstation(ind)
42 ismkvmod = any(sn.procid(sn.nodeToStation(ind),:)==ProcessType.MAP | sn.procid(sn.nodeToStation(ind),:)==ProcessType.MMPP2);
43 ismkvmodclass = zeros(R,1);
44 for r=1:R
45 ismkvmodclass(r) = any(sn.procid(sn.nodeToStation(ind),r)==ProcessType.MAP | sn.procid(sn.nodeToStation(ind),r)==ProcessType.MMPP2);
46 end
47end
48
49lldscaling = sn.lldscaling;
50if isempty(lldscaling)
51 lldlimit = max(sum(sn.nclosedjobs),1);
52 lldscaling = ones(M,lldlimit);
53else
54 lldlimit = size(lldscaling,2);
55end
56
57cdscaling = sn.cdscaling;
58if isempty(cdscaling)
59 cdscaling = cell(M,1);
60 cdscaling{1} = @(ni) 1;
61 for i=2:M % faster this way
62 cdscaling{i} = cdscaling{1};
63 end
64end
65
66hasOnlyExp = false; % true if all service processes are exponential
67if sn.isstation(ind)
68 ist = sn.nodeToStation(ind);
69 K = phasessz(ist,:);
70 Ks = phaseshift(ist,:);
71 if max(K)==1
72 hasOnlyExp = true;
73 end
74 mu = sn.mu;
75 phi = sn.phi;
76 proc = sn.proc;
77 capacity = sn.cap;
78 classcap = sn.classcap;
79 if K(class) == 0 % if this class is not accepted at the resource
80 eventCache(key) = {outprob, outspace,outrate};
81 return
82 end
83 V = sum(sn.nvars(ind,:));
84 % Place nodes: state format is [buffer(R), server(sum(K))] after ARV
85 if sn.nodetype(ind) == NodeType.Place
86 space_var = zeros(size(inspace,1), 0); % proper dimensions for concatenation
87 state_len = size(inspace, 2);
88 expected_len = R + sum(K);
89 if state_len == expected_len
90 % State already has [buffer, server] format
91 space_buf = inspace(:, 1:R);
92 space_srv = inspace(:, (R+1):end);
93 elseif state_len == R
94 % Initial state: just buffer counts
95 space_buf = inspace;
96 space_srv = zeros(size(inspace,1), sum(K));
97 else
98 % Fallback for unexpected formats
99 space_buf = inspace;
100 space_srv = zeros(size(inspace,1), sum(K));
101 end
102 else
103 if sn.sched(ist) == SchedStrategy.EXT
104 % Source state layout from fromMarginal: [Inf_buffer, phases...]
105 % No variable columns despite nvars>0 for MAP arrivals
106 space_buf = inspace(:, 1:(size(inspace,2)-sum(K)));
107 space_srv = inspace(:, (size(inspace,2)-sum(K)+1):end);
108 space_var = zeros(size(inspace,1), 0);
109 V = 0;
110 else
111 space_var = inspace(:,(end-V+1):end); % local state variables
112 space_srv = inspace(:,(end-sum(K)-V+1):(end-V)); % server state
113 space_buf = inspace(:,1:(end-sum(K)-V)); % buffer state
114 end
115 end
116elseif sn.isstateful(ind)
117 V = sum(sn.nvars(ind,:));
118 % in this case service is always immediate so sum(K)=1
119 space_var = inspace(:,(end-V+1):end); % local state variables
120 if sn.nodetype(ind) == NodeType.Transition
121 K = sn.nodeparam{ind}.firingphases;
122 nmodes = sn.nodeparam{ind}.nmodes;
123 % Handle NaN firingphases (non-phase-type distributions like Pareto)
124 % Infer phase count from D0 matrix size
125 if any(isnan(K))
126 K = zeros(1, nmodes);
127 for m = 1:nmodes
128 if iscell(sn.nodeparam{ind}.firingproc) && ~isempty(sn.nodeparam{ind}.firingproc{m})
129 K(m) = size(sn.nodeparam{ind}.firingproc{m}{1}, 1);
130 else
131 K(m) = 1;
132 end
133 end
134 end
135 Ks = [0,cumsum(K,2)];
136 space_buf = inspace(:,1:nmodes); % idle servers count put in buf
137 space_srv = inspace(:,(nmodes+1):(nmodes+sum(K))); % enabled servers' phases
138 % Handle both state formats: with and without fired component
139 expected_len_with_fired = 2*nmodes + sum(K);
140 expected_len_without_fired = nmodes + sum(K);
141 if size(inspace, 2) >= expected_len_with_fired
142 space_fired = inspace(:,(nmodes+sum(K)+1):(2*nmodes+sum(K))); % servers that just fired
143 elseif size(inspace, 2) == expected_len_without_fired
144 % Legacy format without fired component - initialize to zeros
145 space_fired = zeros(size(inspace,1), nmodes);
146 else
147 line_error(mfilename, 'Unexpected state vector length for Transition node');
148 end
149 else
150 space_buf = []; % buffer state
151 space_srv = inspace(:,(end-R-V+1):(end-V)); % server state
152 space_fired = []; % only for Transition nodes
153 end
154else % stateless node
155 space_var = [];
156 space_srv = [];
157 space_buf = [];
158end
159
160if sn.isstation(ind)
161 [outspace, outrate, outprob, eventCache] = State.afterEventStation(sn, ind, inspace, event, class, isSimulation, eventCache, ...
162 M, R, S, phasessz, phaseshift, pie, isf, ismkvmod, ismkvmodclass, lldscaling, lldlimit, cdscaling, ...
163 hasOnlyExp, ist, K, Ks, mu, phi, proc, capacity, classcap, V, space_buf, space_srv, space_var, key);
164elseif sn.isstateful(ind)
165 switch sn.nodetype(ind)
166 case NodeType.Router
167 [outspace, outrate, outprob, eventCache] = State.afterEventRouter(sn, ind, event, class, isSimulation, eventCache, space_buf, space_srv, space_var, key);
168 case NodeType.Cache
169 [outspace, outrate, outprob, eventCache] = State.afterEventCache(sn, ind, event, class, isSimulation, eventCache, R, space_buf, space_srv, space_var, key);
170 case NodeType.Transition
171 [outspace, outrate, outprob, eventCache] = State.afterEventTransition(sn, ind, inspace, K, Ks, event, class, isSimulation, eventCache, R, space_buf, space_srv, space_fired, space_var, key);
172 end % switch nodeType
173end
174end
Definition mmt.m:124