LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
toMarginal.m
1function [ni, nir, sir, kir] = toMarginal(sn, ind, state_i, phasesz, phaseshift, space_buf, space_srv, space_var) %#ok<INUSD>
2% TOMARGINAL Compute marginal distributions for a specific node
3%
4% [NI, NIR, SIR, KIR] = TOMARGINAL(SN, IND, STATE_I, PHASESZ, PHASESHIFT, SPACE_BUF, SPACE_SRV, SPACE_VAR)
5%
6% @brief Extracts marginal job statistics from global state information for a specific node
7%
8% This function processes the global network state to compute marginal
9% distributions and job counts for a specific node, considering different
10% scheduling strategies, service phases, and node types.
11%
12% @param sn Network structure or Network object
13% @param ind Node index to extract marginal information for
14% @param state_i Global state matrix or vector
15% @param phasesz Vector of phase sizes for each class
16% @param phaseshift Phase shift parameters for state extraction
17% @param space_buf Buffer space configuration
18% @param space_srv Service space configuration
19% @param space_var Variable space configuration
20%
21% @return ni Total jobs in node IND
22% @return nir Total jobs per class in node IND [matrix: states x classes]
23% @return sir Total jobs in service per class in node IND [matrix: states x classes]
24% @return kir Total jobs in service per class and per phase in node IND [3D array: states x classes x phases]
25
26% Copyright (c) 2012-2026, Imperial College London
27% All rights reserved.
28
29if ~isstruct(sn) % the input can be a Network object too
30 sn=sn.getStruct();
31end
32
33% ind: node index
34if ~sn.isstation(ind) && sn.isstateful(ind) % if stateful node
35 if sn.nodetype(ind) == NodeType.Transition
36 R = sn.nodeparam{ind}.nmodes;
37 if nargin < 5
38 % Initialize phasesz/phaseshift for Transition nodes from firingphases
39 phasesz = sn.nodeparam{ind}.firingphases;
40 if any(isnan(phasesz))
41 phasesz = zeros(1, R);
42 for m = 1:R
43 if iscell(sn.nodeparam{ind}.firingproc) && ~isempty(sn.nodeparam{ind}.firingproc{m})
44 phasesz(m) = size(sn.nodeparam{ind}.firingproc{m}{1}, 1);
45 else
46 phasesz(m) = 1;
47 end
48 end
49 end
50 phaseshift = [0,cumsum(phasesz(1:end-1))];
51 end
52 if nargin < 8
53 nmodes = R;
54 space_buf = state_i(:,1:nmodes);
55 space_srv = state_i(:,(nmodes+1):(nmodes+sum(phasesz)));
56 space_var = state_i(:,(nmodes+sum(phasesz)+1):end);
57 end
58 sir = zeros(size(state_i,1),R); % class-r jobs in service
59 kir = zeros(size(state_i,1),R,max(phasesz)); % class-r jobs in service in phase k
60 for r=1:R
61 for k=1:phasesz(r)
62 kir(:,r,k) = space_srv(:,phaseshift(r)+k);
63 sir(:,r) = sir(:,r) + kir(:,r,k);
64 end
65 end
66 nir = sir;
67 ni = sum(nir);
68 else
69 ni = sum(state_i(1:(end-sum(sn.nvars(ind,:)))));
70 nir = state_i(1:(end-sum(sn.nvars(ind,:))));
71 sir = nir; % jobs in service
72 kir = sir; % jobs per phase
73 end
74 return
75end
76
77R = sn.nclasses;
78
79ist = sn.nodeToStation(ind);
80isf = sn.nodeToStateful(ind);
81
82if nargin < 3
83 state_i = sn.state{isf};
84end
85
86if nargin < 5
87 phasesz = sn.phasessz(ist,:);
88 phaseshift = sn.phaseshift(ist,:);
89end
90
91if sn.sched(ist) == SchedStrategy.PAS
92 % PAS/OI: the state is the ordered list of class indices (no server split).
93 Vp = sum(sn.nvars(ind,:));
94 listcols = state_i(:,1:(end-Vp));
95 nir = zeros(size(state_i,1),R);
96 for r=1:R
97 nir(:,r) = sum(listcols==r,2);
98 end
99 % Jobs in service = positions receiving a nonzero rate increment
100 % Delta_mu(c1..cp) > 0 (the rest wait); utilization derives from this.
101 muFun = sn.nodeparam{ind}.svcRateFun;
102 sir = zeros(size(state_i,1),R);
103 if ~isempty(muFun)
104 for row=1:size(listcols,1)
105 c = listcols(row, listcols(row,:)>0);
106 muPrev = 0;
107 for p=1:numel(c)
108 muCur = muFun(c(1:p));
109 if muCur - muPrev > 0
110 sir(row,c(p)) = sir(row,c(p)) + 1;
111 end
112 muPrev = muCur;
113 end
114 end
115 else
116 sir = nir;
117 end
118 kir = zeros(size(state_i,1),R,max(phasesz));
119 kir(:,:,1) = sir;
120 ni = sum(nir,2);
121 return
122end
123
124isExponential = false;
125if max(phasesz)==1
126 isExponential = true;
127end
128
129if nargin < 8
130 space_var = state_i(:,(end-sum(sn.nvars(ind,:))+1):end); % local variables
131 space_srv = state_i(:,(end-sum(phasesz)-sum(sn.nvars(ind,:))+1):(end-sum(sn.nvars(ind,:)))); % server state
132 space_buf = state_i(:,1:(end-sum(phasesz)-sum(sn.nvars(ind,:)))); % buffer state
133end
134
135if isExponential
136 sir = space_srv;
137 kir = space_srv;
138else
139 nir = zeros(size(state_i,1),R);
140 sir = zeros(size(state_i,1),R); % class-r jobs in service
141 kir = zeros(size(state_i,1),R,max(phasesz)); % class-r jobs in service in phase k
142 for r=1:R
143 for k=1:phasesz(r)
144 kir(:,r,k) = space_srv(:,phaseshift(r)+k);
145 sir(:,r) = sir(:,r) + kir(:,r,k);
146 end
147 end
148end
149
150switch sn.sched(ist)
151 case SchedStrategy.INF
152 for r=1:R
153 nir(:,r) = sir(:,r); % class-r jobs in station
154 end
155 case {SchedStrategy.PS, SchedStrategy.PSPRIO}
156 for r=1:R
157 nir(:,r) = sir(:,r) ; % class-r jobs in station
158 end
159 case SchedStrategy.EXT
160 for r=1:R
161 nir(:,r) = Inf;
162 end
163 case {SchedStrategy.FCFS, SchedStrategy.FCFSPRIO, SchedStrategy.HOL}
164 for r=1:R
165 nir(:,r) = sir(:,r) + sum(space_buf==r,2); % class-r jobs in station
166 end
167 case {SchedStrategy.DPS, SchedStrategy.DPSPRIO}
168 for r=1:R
169 nir(:,r) = sir(:,r) ; % class-r jobs in station
170 end
171 case {SchedStrategy.GPS, SchedStrategy.GPSPRIO}
172 for r=1:R
173 nir(:,r) = sir(:,r) ; % class-r jobs in station
174 end
175 case {SchedStrategy.LCFS, SchedStrategy.LCFSPRIO}
176 for r=1:R
177 nir(:,r) = sir(:,r) + sum(space_buf==r,2); % class-r jobs in station
178 end
179 case {SchedStrategy.FCFSPI, SchedStrategy.FCFSPIPRIO, SchedStrategy.FCFSPR, SchedStrategy.FCFSPRPRIO, SchedStrategy.LCFSPI, SchedStrategy.LCFSPIPRIO, SchedStrategy.LCFSPR, SchedStrategy.LCFSPRPRIO}
180 if length(space_buf)>1
181 space_buf = space_buf(1:2:end);
182 %space_bufphase = space_buf(2:2:end);
183 for r=1:R
184 nir(:,r) = sir(:,r) + sum(space_buf==r,2); % class-r jobs in station
185 end
186 else
187 nir = sir;
188 end
189 case SchedStrategy.SIRO
190 for r=1:R
191 nir(:,r) = sir(:,r) + space_buf(:,r); % class-r jobs in station
192 end
193 case SchedStrategy.SEPT
194 for r=1:R
195 nir(:,r) = sir(:,r) + space_buf(:,r); % class-r jobs in station
196 end
197 case SchedStrategy.LEPT
198 for r=1:R
199 nir(:,r) = sir(:,r) + space_buf(:,r); % class-r jobs in station
200 end
201 case SchedStrategy.SRPT
202 for r=1:R
203 nir(:,r) = sir(:,r) + space_buf(:,r); % class-r jobs in station
204 end
205 case SchedStrategy.SRPTPRIO
206 for r=1:R
207 nir(:,r) = sir(:,r) + space_buf(:,r); % class-r jobs in station
208 end
209 otherwise % possibly other stateful nodes
210 for r=1:R
211 nir(:,r) = sir(:,r) ; % class-r jobs in station
212 end
213end
214
215if sn.nodetype(ind) == NodeType.Place
216 % set all service and phase data to 0
217 for r=1:R
218 if isnan(sn.rates(ist,r)) % if disabled station
219 for k=1:phasesz(r)
220 kir(:,r,k) = 0;
221 end
222 sir(:,r)=0;
223 end
224 end
225else
226 for r=1:R
227 if isnan(sn.rates(ist,r)) % if disabled station
228 nir(:,r) = 0;
229 for k=1:phasesz(r)
230 kir(:,r,k) = 0;
231 end
232 sir(:,r)=0;
233 end
234 end
235end
236
237ni = sum(nir,2); % total jobs in station
238end
Definition mmt.m:124