LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
pfqn_sens_respt.m
1%{
2%{
3 % @file pfqn_sens_respt.m
4 % @brief Exact moments of the sojourn time of a job at FCFS multiserver
5 % centers of a closed product-form queueing network.
6%}
7%}
8
9function res = pfqn_sens_respt(S,V,N,Z,b,tmax)
10%{
11%{
12 % @brief Exact raw moments E[W_(i,l)^t], t = 1..tmax, of the sojourn time of a
13 % class-l job at an FCFS b-server center i of a closed product-form
14 % queueing network, together with the variance of that sojourn time.
15 %
16 % This is Theorem 4.1 of the reference. Its mechanism is the arrival
17 % theorem of Lavenberg-Reiser and Sevcik-Mitrani: a class-l job arriving
18 % at center i finds j jobs already there with probability
19 % p_i(j, N - 1_l). Conditioning the sojourn time on j and inverting the
20 % Laplace transform of the conditional density gives
21 %
22 % E[W_(i,l)^t] = t!/mu^t + sum_{tau=0..t} a_(t,tau)(0) E[Qt_i^tau]
23 % - sum_{j=0..b-1} p_i(j,N-1_l) sum_{tau=0..t} a_(t,tau)(0) j^tau
24 %
25 % where mu = 1/S(i) is the rate of each of the b servers, Qt_i is the
26 % total queue length at center i at population N - 1_l (so its moments
27 % are those of pfqn_sens_mom evaluated one job down in class l), and the
28 % coefficients a_(t,tau)(0) depend only on b and mu, not on the network
29 % (Remark 4.3 of the reference). The moments E[Qt_i^tau] up to tau = 3
30 % need the second derivative of the MVA recursion, so this routine
31 % carries a second-order forward-mode pass exactly as pfqn_sens_mom
32 % does, but over the b-server recursion (4.1)-(4.2) rather than the
33 % single-server one.
34 %
35 % For b = 1 the coefficients a_(t,0)(0) vanish identically and the
36 % double-sum correction disappears, so no marginal probabilities are
37 % needed (Remark 4.2 of the reference); the routine still evaluates the
38 % general expression, which reduces to that case on its own.
39 %
40 % Only FCFS centers are covered. The reference is explicit that the
41 % sojourn-time distribution at PS and LCFS centers is in general not
42 % known, so no analogue exists there. FCFS in a BCMP network further
43 % requires the service time to be exponential and class-independent,
44 % which is why this routine takes a per-station service time S(i) and a
45 % separate visit-ratio matrix V rather than a demand matrix: the sojourn
46 % time is per visit, so the per-visit rate mu = 1/S(i) must be known and
47 % cannot be recovered from the demand L(i,l) = S(i)*V(i,l) alone.
48 %
49 % Reference: J. C. Strelen, "Moment Analysis for Closed Queuing Networks
50 % and its Linearizer", Performance Evaluation 11:127-142, 1990,
51 % Theorem 4.1 with equations (4.1)-(4.5) and Remarks 4.2-4.3.
52 %
53 % @fn pfqn_sens_respt(S, V, N, Z, b, tmax)
54 % @param S Service time at each station (M x 1), common to all classes.
55 % @param V Visit ratio matrix (M x R). The demand is L(i,r) = S(i)*V(i,r).
56 % @param N Population vector (1 x R).
57 % @param Z Think time vector (1 x R). Default: zeros.
58 % @param b Number of servers at each station (M x 1). Default: ones.
59 % @param tmax Highest sojourn-time moment to return, 1..3. Default: 3. The
60 % coefficients a_(t,tau)(0) are tabulated in the reference up to t = 3.
61 % @return res A struct with:
62 % .X (1 x R), .Q (M x R), .U (M x R) base measures at population N.
63 % .W (M x R) W(i,l) = E[W_(i,l)], the mean sojourn time per visit of
64 % a class-l job at station i. Zero where class l does not visit i.
65 % .WM (M x R x tmax) WM(i,l,t) = E[W_(i,l)^t].
66 % .WVar (M x R) Var[W_(i,l)] = E[W^2] - E[W]^2. Requires tmax >= 2.
67 % .WSkew (M x R) skewness of W_(i,l). Requires tmax >= 3; NaN if the
68 % variance is zero.
69 % .m (M x 1) E[Q_i] at population N, the total queue length.
70 % .Var (M x 1) Var[Q_i] at population N.
71 % .p (M x max(b)) p(i,1+j) = P[Q_i = j] at population N, for j = 0..b_i-1.
72 % These are the only marginal probabilities the b-server recursion needs,
73 % so the matrix is RAGGED: row i is meaningful only up to column b_i and
74 % is zero-padded out to max(b). A padded entry is not P[Q_i = j]; it is
75 % simply not computed. Read row i as p(i,1:b(i)).
76 % .Wresid (M x R) the residence time w_i(l) of the MVA recursion. The
77 % identity W(i,l) = w_i(l)/V(i,l) is an independent check of the t = 1
78 % case of (4.5) and is asserted by pfqn_sens_respt_validate.
79 %
80 % Notes:
81 % - Restricted to closed populations.
82 % - Load-dependent rates are not covered here; the b-server dependence is the
83 % only state dependence, and it is carried exactly by (4.1)-(4.2).
84%}
85%}
86[M,R] = size(V);
87S = S(:);
88N = ceil(N(:)');
89if nargin < 4 || isempty(Z)
90 Z = zeros(1,R);
91end
92Z = Z(:)';
93if nargin < 5 || isempty(b)
94 b = ones(M,1);
95end
96b = round(b(:));
97if nargin < 6 || isempty(tmax)
98 tmax = 3;
99end
100if tmax < 1 || tmax > 3
101 line_error(mfilename,'tmax must be 1, 2 or 3: the coefficients a_{t,tau}(0) are tabulated in the reference up to order three.');
102end
103if length(N) ~= R
104 line_error(mfilename,'visit matrix and population vector have different number of classes');
105end
106if any(isinf(N))
107 line_error(mfilename,'pfqn_sens_respt requires a closed population');
108end
109if any(b < 1)
110 line_error(mfilename,'the number of servers must be at least one at every station');
111end
112if any(S <= 0)
113 line_error(mfilename,'every FCFS station must have a strictly positive service time');
114end
115
116rho = zeros(M,R);
117for i = 1:M
118 for l = 1:R
119 rho(i,l) = S(i) * V(i,l);
120 end
121end
122mu = 1 ./ S;
123bmax = max(b);
124
125X = zeros(1,R); Q = zeros(M,R); U = zeros(M,R);
126m = zeros(M,1);
127W = zeros(M,R); WM = zeros(M,R,tmax); Wresid = zeros(M,R);
128pN = zeros(M,bmax);
129
130if ~any(N > 0)
131 res = pack(X,Q,U,m,zeros(M,1),pN,W,WM,Wresid,tmax);
132 return;
133end
134
135% ---- population lattice --------------------------------------------------
136prods = zeros(1,R-1);
137for w = 1:R-1
138 prods(w) = prod(ones(1,R-(w+1)+1) + N(w+1:R));
139end
140firstnonempty = R;
141while N(firstnonempty) == 0
142 firstnonempty = firstnonempty - 1;
143end
144totpop = prod(N+1);
145ctr = totpop;
146
147% state carried along the lattice: the mean total queue length at each station,
148% the marginal probabilities p_i(j) for j = 0..bmax-1, and the first and second
149% derivatives of both with respect to y_h, a scaling of station h's service
150% time. At y = 1 the y-derivatives are the scaled x-derivatives of (3.2).
151Mrow = zeros(totpop,M);
152D1m = zeros(totpop,M,M);
153D2m = zeros(totpop,M,M);
154Prow = zeros(totpop,M,bmax);
155D1p = zeros(totpop,M,bmax,M);
156D2p = zeros(totpop,M,bmax,M);
157Prow(1,:,1) = 1; % empty population: every station holds zero jobs
158
159currentpop = 2;
160n = zeros(1,R);
161n(firstnonempty) = 1;
162rows = ones(1,R);
163
164while ctr
165 hnvec = currentpop;
166 % ---- residence times, eq. (4.1), and their first two derivatives ----
167 wv = zeros(M,R); d1w = zeros(M,R,M); d2w = zeros(M,R,M);
168 for s = 1:R
169 pos = 0;
170 if n(s) > 0
171 n(s) = n(s) - 1;
172 pos = n(R);
173 w = 1;
174 while w <= R-1
175 pos = pos + n(w)*prods(w);
176 w = w + 1;
177 end
178 n(s) = n(s) + 1;
179 end
180 row = 1 + pos;
181 rows(s) = row;
182 if n(s) == 0
183 continue; % w and every derivative stay zero, as does X(s)
184 end
185 for i = 1:M
186 % bracket = 1 + m_i(n-e_s) + sum_{j=0}^{b_i-2} (b_i-1-j) p_i(j,n-e_s)
187 brk = 1 + Mrow(row,i);
188 for j = 0:(b(i)-2)
189 brk = brk + (b(i)-1-j) * Prow(row,i,1+j);
190 end
191 wv(i,s) = (rho(i,s)/b(i)) * brk;
192 for h = 1:M
193 dbrk = D1m(row,i,h);
194 d2brk = D2m(row,i,h);
195 for j = 0:(b(i)-2)
196 dbrk = dbrk + (b(i)-1-j) * D1p(row,i,1+j,h);
197 d2brk = d2brk + (b(i)-1-j) * D2p(row,i,1+j,h);
198 end
199 % w = y_i * (rho/b) * brk
200 if i == h
201 d1w(i,s,h) = (rho(i,s)/b(i)) * (brk + dbrk);
202 d2w(i,s,h) = (rho(i,s)/b(i)) * (2*dbrk + d2brk);
203 else
204 d1w(i,s,h) = (rho(i,s)/b(i)) * dbrk;
205 d2w(i,s,h) = (rho(i,s)/b(i)) * d2brk;
206 end
207 end
208 end
209 end
210
211 % ---- throughputs and their derivatives ------------------------------
212 lam = zeros(1,R); d1lam = zeros(R,M); d2lam = zeros(R,M);
213 for s = 1:R
214 if n(s) == 0
215 continue;
216 end
217 den = Z(s) + sum(wv(:,s));
218 lam(s) = n(s) / den;
219 for h = 1:M
220 dden = sum(d1w(:,s,h));
221 d2den = sum(d2w(:,s,h));
222 d1lam(s,h) = -n(s) * dden / den^2;
223 d2lam(s,h) = -n(s) * d2den / den^2 + 2*n(s) * dden^2 / den^3;
224 end
225 end
226
227 % ---- mean queue lengths ---------------------------------------------
228 for i = 1:M
229 acc = 0;
230 for s = 1:R
231 if n(s) == 0, continue; end
232 acc = acc + lam(s) * wv(i,s);
233 end
234 Mrow(hnvec,i) = acc;
235 for h = 1:M
236 d1acc = 0; d2acc = 0;
237 for s = 1:R
238 if n(s) == 0, continue; end
239 d1acc = d1acc + d1lam(s,h)*wv(i,s) + lam(s)*d1w(i,s,h);
240 d2acc = d2acc + d2lam(s,h)*wv(i,s) + 2*d1lam(s,h)*d1w(i,s,h) ...
241 + lam(s)*d2w(i,s,h);
242 end
243 D1m(hnvec,i,h) = d1acc;
244 D2m(hnvec,i,h) = d2acc;
245 end
246 end
247
248 % ---- marginal probabilities, eq. (4.2), and their derivatives --------
249 nc = sum(n);
250 for i = 1:M
251 % p_i(j,n) = (1/j) sum_l lam(l) * rho_i(l)*y_i * p_i(j-1, n-e_l)
252 for j = 1:(b(i)-1)
253 if j > nc
254 Prow(hnvec,i,1+j) = 0;
255 continue;
256 end
257 acc = 0;
258 for l = 1:R
259 if n(l) == 0, continue; end
260 acc = acc + lam(l) * rho(i,l) * Prow(rows(l),i,1+(j-1));
261 end
262 Prow(hnvec,i,1+j) = acc / j;
263 for h = 1:M
264 d1acc = 0; d2acc = 0;
265 for l = 1:R
266 if n(l) == 0, continue; end
267 pprev = Prow(rows(l),i,1+(j-1));
268 d1prev = D1p(rows(l),i,1+(j-1),h);
269 d2prev = D2p(rows(l),i,1+(j-1),h);
270 % g = rho * u * v with u = lam, v = y_i * pprev
271 if i == h
272 v1 = pprev + d1prev;
273 v2 = 2*d1prev + d2prev;
274 else
275 v1 = d1prev;
276 v2 = d2prev;
277 end
278 d1acc = d1acc + rho(i,l) * (d1lam(l,h)*pprev + lam(l)*v1);
279 d2acc = d2acc + rho(i,l) * (d2lam(l,h)*pprev + 2*d1lam(l,h)*v1 ...
280 + lam(l)*v2);
281 end
282 D1p(hnvec,i,1+j,h) = d1acc / j;
283 D2p(hnvec,i,1+j,h) = d2acc / j;
284 end
285 end
286 % u_i = sum_l lam(l) * rho_i(l)*y_i (mean number of busy servers)
287 ui = 0; d1ui = zeros(1,M); d2ui = zeros(1,M);
288 for l = 1:R
289 if n(l) == 0, continue; end
290 ui = ui + lam(l) * rho(i,l);
291 for h = 1:M
292 if i == h
293 d1ui(h) = d1ui(h) + rho(i,l) * (d1lam(l,h) + lam(l));
294 d2ui(h) = d2ui(h) + rho(i,l) * (d2lam(l,h) + 2*d1lam(l,h));
295 else
296 d1ui(h) = d1ui(h) + rho(i,l) * d1lam(l,h);
297 d2ui(h) = d2ui(h) + rho(i,l) * d2lam(l,h);
298 end
299 end
300 end
301 % p_i(0,n) = 1 - (1/b)(u_i + sum_{j=1}^{b-1} (b-j) p_i(j,n))
302 acc0 = ui;
303 for j = 1:(b(i)-1)
304 acc0 = acc0 + (b(i)-j) * Prow(hnvec,i,1+j);
305 end
306 Prow(hnvec,i,1) = 1 - acc0/b(i);
307 for h = 1:M
308 d1acc0 = d1ui(h); d2acc0 = d2ui(h);
309 for j = 1:(b(i)-1)
310 d1acc0 = d1acc0 + (b(i)-j) * D1p(hnvec,i,1+j,h);
311 d2acc0 = d2acc0 + (b(i)-j) * D2p(hnvec,i,1+j,h);
312 end
313 D1p(hnvec,i,1,h) = -d1acc0/b(i);
314 D2p(hnvec,i,1,h) = -d2acc0/b(i);
315 end
316 end
317
318 % keep the measures of the last (full) population
319 X = lam;
320 for i = 1:M
321 for s = 1:R
322 Wresid(i,s) = wv(i,s);
323 Q(i,s) = lam(s) * wv(i,s);
324 U(i,s) = lam(s) * rho(i,s);
325 end
326 end
327
328 % ---- odometer advance ------------------------------------------------
329 s = R;
330 while (s>0 && n(s)==N(s)) || s>firstnonempty
331 s = s - 1;
332 end
333 if s == 0
334 break;
335 end
336 n(s) = n(s) + 1;
337 s = s + 1;
338 while s <= R
339 n(s) = 0;
340 s = s + 1;
341 end
342 ctr = ctr - 1;
343 currentpop = currentpop + 1;
344end
345
346lastrow = currentpop;
347for i = 1:M
348 m(i) = Mrow(lastrow,i);
349 for j = 0:(bmax-1)
350 pN(i,1+j) = Prow(lastrow,i,1+j);
351 end
352end
353Var = zeros(M,1);
354for i = 1:M
355 Var(i) = D1m(lastrow,i,i);
356end
357
358% ---- sojourn-time moments, eq. (4.5) -------------------------------------
359% index of N - e_l on the lattice
360rowsN = ones(1,R);
361for l = 1:R
362 if N(l) > 0
363 nn = N; nn(l) = nn(l) - 1;
364 pos = nn(R);
365 for w = 1:R-1
366 pos = pos + nn(w)*prods(w);
367 end
368 rowsN(l) = 1 + pos;
369 end
370end
371
372for i = 1:M
373 for l = 1:R
374 if N(l) == 0 || V(i,l) <= 0
375 continue;
376 end
377 rl = rowsN(l);
378 % moments of the queue length seen by an arriving class-l job, i.e. of
379 % the total queue at station i at population N - e_l, from (3.2)
380 mt = Mrow(rl,i);
381 d1t = D1m(rl,i,i);
382 d2t = D2m(rl,i,i);
383 EQ = zeros(1,4); % EQ(1+tau) = E[Qt_i^tau]
384 EQ(1) = 1;
385 EQ(2) = mt;
386 EQ(3) = d1t + mt^2;
387 EQ(4) = d2t + (1 + 3*mt)*d1t + mt^3;
388 acoef = strelen_a(b(i), mu(i), tmax);
389 for t = 1:tmax
390 val = factorial(t) / mu(i)^t;
391 for tau = 0:t
392 val = val + acoef(t,1+tau) * EQ(1+tau);
393 end
394 % correction over the states in which a server is idle
395 for j = 0:(b(i)-1)
396 inner = 0;
397 for tau = 0:t
398 inner = inner + acoef(t,1+tau) * jpow(j,tau);
399 end
400 val = val - Prow(rl,i,1+j) * inner;
401 end
402 WM(i,l,t) = val;
403 end
404 W(i,l) = WM(i,l,1);
405 end
406end
407
408res = pack(X,Q,U,m,Var,pN,W,WM,Wresid,tmax);
409end
410
411% =========================================================================
412function v = jpow(j,tau)
413% j^tau with the convention j^0 = 1, so that 0^0 = 1 as the reference states.
414if tau == 0
415 v = 1;
416else
417 v = j^tau;
418end
419end
420
421% =========================================================================
422function a = strelen_a(b,mu,tmax)
423% Coefficients a_{t,tau}(0) of Remark 4.3 of the reference. They depend only on
424% the number of servers b and on the per-server rate mu, not on the network.
425a = zeros(3,4);
426a(1,1) = (1-b)/(b*mu);
427a(1,2) = 1/(b*mu);
428if tmax >= 2
429 a(2,1) = (2 - b - b^2)/(b^2*mu^2);
430 a(2,2) = 3/(b^2*mu^2);
431 a(2,3) = 1/(b^2*mu^2);
432end
433if tmax >= 3
434 a(3,1) = (6 - 5*b + 3*b^2 - 4*b^3)/(b^3*mu^3);
435 a(3,2) = (11 - 3*b + 3*b^2)/(b^3*mu^3);
436 a(3,3) = 6/(b^3*mu^3);
437 a(3,4) = 1/(b^3*mu^3);
438end
439end
440
441% =========================================================================
442function res = pack(X,Q,U,m,Var,p,W,WM,Wresid,tmax)
443[M,R] = size(Q);
444res.X = X; res.Q = Q; res.U = U;
445res.m = m; res.Var = Var; res.p = p;
446res.W = W; res.WM = WM; res.Wresid = Wresid;
447WVar = zeros(M,R); WSkew = zeros(M,R);
448if tmax >= 2
449 for i = 1:M
450 for l = 1:R
451 WVar(i,l) = WM(i,l,2) - WM(i,l,1)^2;
452 end
453 end
454end
455if tmax >= 3
456 for i = 1:M
457 for l = 1:R
458 mu3 = WM(i,l,3) - 3*WM(i,l,1)*WM(i,l,2) + 2*WM(i,l,1)^3;
459 if WVar(i,l) > 0
460 WSkew(i,l) = mu3 / WVar(i,l)^1.5;
461 else
462 WSkew(i,l) = NaN;
463 end
464 end
465 end
466end
467res.WVar = WVar; res.WSkew = WSkew;
468end
Definition Station.m:245