LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
pfqn_sens_mva.m
1%{
2%{
3 % @file pfqn_sens_mva.m
4 % @brief Exact per-station queue-length variances and covariances for closed
5 % product-form queueing networks, computed by an MVA-like moment
6 % recursion that does not require the full sensitivity Jacobian.
7%}
8%}
9
10function mom = pfqn_sens_mva(L,N,Z,mi)
11%{
12%{
13 % @brief Exact second moments (variances and per-station covariances) of the
14 % queue lengths of a closed product-form (BCMP) queueing network. The
15 % moments are obtained by an MVA-type recursion evaluated on the same
16 % population lattice as pfqn_mva, so no derivative of the model is ever
17 % formed and the cost is O(M*R^2) per lattice point rather than the
18 % O(M^2*R^2) of the differentiated-MVA kernel used by pfqn_sens.
19 %
20 % The recursion is obtained by differentiating the Reiser-Lavenberg MVA
21 % equation Q(j,v|N) = X(v|N) * L(j,v) * (mi(j) + Qtot(j|N-e_v)) with
22 % respect to the visit ratio theta(i,k) of class k at station i and
23 % rescaling. Writing W(k,i;v,j|N) = Cov[n(i,k),n(j,v)] at population N,
24 %
25 % W(k,i;v,j|N) = Q(j,v|N) * ( Q(i,k|N-e_v) - Q(i,k|N) )
26 % + [i==j & k==v] * Q(j,v|N)
27 % + X(v|N) * L(j,v) * sum_t W(k,i;t,j|N-e_v)
28 %
29 % with W(.|0) = 0. This routine evaluates the same-station case i==j,
30 % which is self-contained: the inner sum then only involves same-station
31 % terms, so a single scalar Ssum(j,k|N) = sum_t W(k,j;t,j|N) carried
32 % along the lattice closes the recursion. The cross-station case i~=j is
33 % not self-contained (it couples every station pair) and costs as much as
34 % the full Jacobian, so it is left to pfqn_sens.
35 %
36 % Setting i==j and mi==1 reproduces Corollary 1 of the reference below,
37 % i.e. its equations (2.9a) for the variance and (2.10) for the
38 % covariance; the station multiplicity mi cancels identically because
39 % X(v|N)*L(j,v)*(mi(j)+Qtot(j|N-e_v)) = Q(j,v|N) is the MVA equation for
40 % any mi. The equivalent statement for an infinite-server station,
41 % equation (2.9b) of the reference, is recovered automatically because
42 % LINE folds the delay into the think time Z, which enters only through
43 % X(v|N) and carries no queue-length moment of its own.
44 %
45 % Reference: E. de Souza e Silva and R. R. Muntz, "Simple Relationships
46 % Among Moments of Queue Lengths in Product Form Queueing Networks",
47 % IEEE Trans. Computers 37(9):1125-1129, 1988 (Theorems 1-2 and
48 % Corollary 1). The underlying identity Cov[n(i,k),n(j,v)] =
49 % theta(i,k) * dQ(j,v)/dtheta(i,k) is the k=2 case of Theorem 1 of
50 % I. F. Akyildiz and J. C. Strelen, "Moment Analysis for Load-Dependent
51 % Mixed Product Form Queueing Networks", IEEE Trans. Communications
52 % 39(6):828-832, 1991.
53 %
54 % @fn pfqn_sens_mva(L, N, Z, mi)
55 % @param L Service demand matrix (M x R), L(i,r) = visits_ir / rate_ir.
56 % @param N Population vector (1 x R).
57 % @param Z Think time vector (1 x R). Default: zeros.
58 % @param mi (Optional) Server multiplicity vector (1 x M). Default: ones.
59 % @return mom A struct with the base measures and their second moments:
60 % .X (1 x R), .Q (M x R), .U (M x R), .R (M x R) base MVA measures,
61 % identical to pfqn_mva(L,N,Z,mi).
62 % .QCov (M x R x R) QCov(i,r,s) = Cov[n(i,r),n(i,s)], the queue-length
63 % covariance of classes r and s at station i. Symmetric in (r,s).
64 % .QVar (M x R) QVar(i,r) = QCov(i,r,r) = Var[n(i,r)].
65 % .QTotVar (M x 1) QTotVar(i) = Var[sum_r n(i,r)], the variance of the
66 % total queue length at station i, i.e. sum_{r,s} QCov(i,r,s). This is
67 % Theorem 3 of the reference, obtained here without a capacity
68 % derivative.
69 % .QCovAsym (scalar) max |W(r,s) - W(s,r)| over the covariance entries
70 % before symmetrization. The two triangles come from differentiating two
71 % different classes' MVA equations, so this is an independent residual of
72 % the recursion and should sit at roundoff; a large value signals a bug.
73 %
74 % Notes:
75 % - Restricted to closed populations. Mixed and load-dependent models are
76 % handled by pfqn_sens_mvaldmx.
77 % - For a station of multiplicity mi(i)>1, which LINE treats as mi(i)
78 % identical replicas sharing the demand row L(i,:), the moments returned are
79 % those of the aggregate queue length over the replicas.
80%}
81%}
82[M,R] = size(L);
83N = ceil(N(:)');
84if nargin < 3 || isempty(Z)
85 Z = zeros(1,R);
86end
87Z = Z(:)';
88if nargin < 4 || isempty(mi)
89 mi = ones(1,M);
90end
91mi = mi(:)';
92if length(N) ~= R
93 line_error(mfilename,'demand matrix and population vector have different number of classes');
94end
95if any(isinf(N))
96 line_error(mfilename,'pfqn_sens_mva requires a closed population; use pfqn_sens_mvaldmx for mixed models');
97end
98
99X = zeros(1,R); Q = zeros(M,R); U = zeros(M,R); C = zeros(M,R);
100QCov = zeros(M,R,R);
101
102if ~any(N > 0)
103 mom = pack(X,Q,U,C,QCov);
104 return;
105end
106
107% population-lattice odometer, identical to pfqn_mva and to the sens_mva kernel
108% of pfqn_sens so that the base measures agree entry by entry
109prods = zeros(1,R-1);
110for w = 1:R-1
111 prods(w) = prod(ones(1,R-(w+1)+1) + N(w+1:R));
112end
113firstnonempty = R;
114while N(firstnonempty) == 0
115 firstnonempty = firstnonempty - 1;
116end
117totpop = prod(N+1);
118ctr = totpop;
119Qtot = zeros(totpop,M); % Qtot(m,i) = sum_r Q(i,r) at population m
120Qcls = zeros(totpop,M,R); % Qcls(m,i,r) = Q(i,r) at population m
121Xall = zeros(totpop,R); % Xall(m,r) = X(r) at population m
122Ssum = zeros(totpop,M,R); % Ssum(m,j,k) = sum_t Cov[n(j,k),n(j,t)] at pop m
123currentpop = 2;
124n = zeros(1,R);
125n(firstnonempty) = 1;
126rows = ones(1,R); % rows(s) = lattice index of n - e_s
127
128while ctr
129 % ---- mean value analysis step at population n -----------------------
130 s = 1;
131 while s <= R
132 pos = 0;
133 if n(s) > 0
134 n(s) = n(s) - 1;
135 pos = n(R);
136 w = 1;
137 while w <= R-1
138 pos = pos + n(w)*prods(w);
139 w = w + 1;
140 end
141 n(s) = n(s) + 1;
142 end
143 % when n(s)==0 the index collapses to the empty population, whose
144 % stored moments are zero; X(s) is then zero and every term that reads
145 % rows(s) is annihilated, so no guard is needed
146 row = 1 + pos;
147 rows(s) = row;
148 CNtot = 0;
149 for i = 1:M
150 C(i,s) = L(i,s) * (mi(i) + Qtot(row,i));
151 CNtot = CNtot + C(i,s);
152 end
153 den = Z(s) + CNtot;
154 X(s) = n(s) / den;
155 Xall(currentpop,s) = X(s);
156 for i = 1:M
157 Q(i,s) = X(s) * C(i,s);
158 Qcls(currentpop,i,s) = Q(i,s);
159 Qtot(currentpop,i) = Qtot(currentpop,i) + Q(i,s);
160 end
161 s = s + 1;
162 end
163
164 % ---- moment step at population n ------------------------------------
165 % W(k,j;t,j|n) = Q(j,t|n)*(Q(j,k|n-e_t) - Q(j,k|n)) + [k==t]*Q(j,t|n)
166 % + X(t|n)*L(j,t)*Ssum(j,k|n-e_t)
167 for j = 1:M
168 for k = 1:R
169 Qjk = Qcls(currentpop,j,k);
170 sk = 0;
171 for t = 1:R
172 Qjt = Qcls(currentpop,j,t);
173 wkt = Qjt * (Qcls(rows(t),j,k) - Qjk);
174 if k == t
175 wkt = wkt + Qjt;
176 end
177 wkt = wkt + Xall(currentpop,t) * L(j,t) * Ssum(rows(t),j,k);
178 QCov(j,k,t) = wkt;
179 sk = sk + wkt;
180 end
181 Ssum(currentpop,j,k) = sk;
182 end
183 end
184
185 % ---- odometer advance ------------------------------------------------
186 s = R;
187 while (s>0 && n(s)==N(s)) || s>firstnonempty
188 s = s - 1;
189 end
190 if s == 0
191 break;
192 end
193 n(s) = n(s) + 1;
194 s = s + 1;
195 while s <= R
196 n(s) = 0;
197 s = s + 1;
198 end
199 ctr = ctr - 1;
200 currentpop = currentpop + 1;
201end
202
203% utilization
204for i = 1:M
205 for r = 1:R
206 U(i,r) = X(r) * L(i,r);
207 end
208end
209
210mom = pack(X,Q,U,C,QCov);
211end
212
213% =========================================================================
214function mom = pack(X,Q,U,C,QCov)
215[M,R] = size(Q);
216mom.X = X; mom.Q = Q; mom.U = U; mom.R = C;
217% Symmetrize. The recursion obtains W(k,j;t,j) by differentiating class t's MVA
218% equation and W(t,j;k,j) by differentiating class k's, so the two triangles are
219% numerically distinct expressions that agree only up to roundoff. Averaging
220% them keeps QCov exactly symmetric, as a covariance matrix must be. The raw
221% discrepancy is reported in .QCovAsym rather than discarded, so that a genuine
222% disagreement cannot hide behind the averaging.
223QCovRaw = QCov;
224QCov = (QCov + permute(QCov,[1 3 2])) / 2;
225mom.QCovAsym = max(max(max(abs(QCovRaw - permute(QCovRaw,[1 3 2])))));
226if isempty(mom.QCovAsym)
227 mom.QCovAsym = 0;
228end
229QVar = zeros(M,R);
230QTotVar = zeros(M,1);
231for i = 1:M
232 for r = 1:R
233 QVar(i,r) = QCov(i,r,r);
234 end
235 QTotVar(i) = sum(sum(QCov(i,:,:)));
236end
237mom.QCov = QCov;
238mom.QVar = QVar;
239mom.QTotVar = QTotVar;
240end
Definition Station.m:245