3 % @file pfqn_sens_mvaldmx.m
4 % @brief Exact queue-length variances and covariances
for mixed open/closed
5 % product-form queueing networks with limited load dependence.
9function mom = pfqn_sens_mvaldmx(lambda,D,N,Z,mu,S)
12 % @brief Exact second moments (variances and covariances) of
the queue lengths
13 % of a mixed open/closed product-form queueing network with limited
14 % load-dependent service rates. This
is the load-dependent and mixed
15 % counterpart of pfqn_sens_mva, which
is restricted to closed
16 % load-independent models.
18 % The method
is the moment analysis of Akyildiz and Strelen. Their
19 % Theorem 1, equation (11), states that multiplying a queue-length
20 % moment by one further
factor Q_jT costs one derivative with respect to
21 % a parameter y_j that scales
the service demands s_ir of
the classes
22 % r in T at station j:
24 % E[Q_jT^k ...] = d/dy_j E[Q_jT^(k-1) ...]|_{y_j=1}
25 % + nbar_jT E[Q_jT^(k-1) ...]
27 % Taking k=2 and T={s} gives
the second moment, hence
29 % Cov[n(i,r),n(j,s)] = d nbar(i,r) / dy_(j,s) |_{y=1}
31 % which
is evaluated here by forward-mode differentiation of
the mixed
32 % load-dependent MVA of Bruell-Balbo-Afshari, i.e. of exactly
the
33 % recursion implemented by pfqn_mvaldmx. The differentiated equations
34 % are (13) for
the residence times, (15)-(17) for
the conditional
35 % marginal probabilities, (18) for
the throughputs, (19) and (24)-(31)
36 % for
the effective capacities (delegated to pfqn_sens_ldmx_ec), (32) for
37 %
the closed-class queue lengths and (33) for
the open-class ones.
39 % Because a demand-scaling parameter perturbs
the whole network through
40 %
the closed-class throughputs,
the derivatives must be propagated for
41 % every parameter, so
the cross-station covariances come out at no extra
42 % cost and are returned in .QCovFull. This
is unlike pfqn_sens_mva, whose
43 % cheaper same-station recursion cannot reach them.
45 % Reference: I. F. Akyildiz and J. C. Strelen, "Moment Analysis for
46 % Load-Dependent Mixed Product Form Queueing Networks", IEEE Trans.
47 % Communications 39(6):828-832, 1991. The closed load-independent case
48 % reduces to E. de Souza e Silva and R. R. Muntz, IEEE Trans. Computers
49 % 37(9):1125-1129, 1988, which pfqn_sens_mva implements directly.
51 % @fn pfqn_sens_mvaldmx(lambda, D, N, Z, mu, S)
52 % @param lambda Arrival rate vector (1 x R). Must be zero on closed classes.
53 % @param D Service demand matrix (M x R).
54 % @param N Population vector (1 x R). Inf entries denote open classes.
55 % @param Z Think time vector (1 x R).
56 % @param mu Load-dependent rate matrix (M x sum(N)), limited load dependence.
57 % @param S Number of servers per station (M x 1). Accepted for signature
58 % compatibility with pfqn_mvaldmx, which likewise does not read it:
the
59 % multiserver behaviour
is carried entirely by
the rates mu.
60 % @return mom A struct with
the base measures and their second moments:
61 % .X (1 x R), .Q (M x R), .U (M x R), .R (M x R) base measures, identical
62 % to pfqn_mvaldmx(lambda,D,N,Z,mu,S).
63 % .QCov (M x R x R) QCov(i,r,s) = Cov[n(i,r),n(i,s)], same-station.
64 % .QCovFull (M x R x M x R) QCovFull(i,r,j,s) = Cov[n(i,r),n(j,s)].
65 % .QVar (M x R) QVar(i,r) = Var[n(i,r)].
66 % .QTotVar (M x 1) QTotVar(i) = Var[sum_r n(i,r)].
67 % .QCovAsym (scalar) max |QCovFull(i,r,j,s) - QCovFull(j,s,i,r)| before
68 % symmetrization. The two entries are produced by differentiating two
69 % different classes' equations, so this residual
is an independent check
70 % of
the recursion and should sit at roundoff.
73 % - Open classes are supported: an open class contributes to
the load Lo(i)
74 % that drives
the effective capacities, and equation (21) supplies
the
75 % corresponding dLo/dy.
76 % - The moments of an open class are those of its queue length at a station,
77 % which
is finite even though its population
is infinite.
81 mu=ones(size(D,1),sum(N(isfinite(N))));
82 S=ones(size(D,1),1); %
#ok<NASGU>
85 S=ones(size(D,1),1); %#ok<NASGU>
87if size(mu,2) < sum(N(isfinite(N)))
88 line_error(mfilename,
'PFQN_SENS_MVALDMX requires to specify the load-dependent rates with one job more than the maximum closed population.');
90if any(N(find(lambda))>0 & isfinite(N(find(lambda)))) %#ok<*FNDSB>
91 line_error(mfilename,
'Arrival rate cannot be specified on closed classes.');
97openClasses = find(isinf(N));
98closedClasses = setdiff(1:length(N), openClasses);
99C = length(closedClasses);
101 line_error(mfilename,'pfqn_sens_mvaldmx requires at least one closed class; use
the open-
class formulas directly otherwise.');
104mu = [mu, mu(:,size(mu,2))]; % up to sum(N)+1, limited load dependence
105[EC,E,Eprime,~,dEC_dLo] = pfqn_sens_ldmx_ec(lambda,D,mu);
107Dc = D(:,closedClasses);
108Nc = N(closedClasses);
109Zc = Z(closedClasses);
112% ---- parameter list: y(j,r) multiplies
the demand D(j,r) -----------------
115pj = zeros(1,
P); pr = zeros(1,
P);
120 pidx(j,r) = p; pj(p) = j; pr(p) = r;
123% eq. (21): Lo(i) = sum_o lambda(o)*D(i,o), so only an open-class parameter at
124% station i perturbs Lo(i), and no parameter perturbs Lo at another station
128 dLo(pj(p),p) = lambda(pr(p)) * D(pj(p),pr(p));
132% ---- population recursion ------------------------------------------------
135 prods(r) = prod(Nc(1:r-1)+1);
138Pc = zeros(M,1+NCtot,NT);
139dPc = zeros(M,1+NCtot,NT,
P);
147 Pc(ist, 1+0, hashpop(nvec,Nc,C,prods)) = 1.0; % eq. (16)
151 hnvec = hashpop(nvec,Nc,C,prods);
154 % ---- residence times, eq. (12) and its derivative eq. (13) ----------
158 hnvec_c = hashpop(oner(nvec,c),Nc,C,prods);
159 cls = closedClasses(c);
163 Pprev = Pc(ist, 1+(n-1), hnvec_c);
164 acc = acc + n * EC(ist,n) * Pprev;
166 dacc(q) = dacc(q) + n * ( dEC_dLo(ist,n)*dLo(ist,q)*Pprev ...
167 + EC(ist,n)*dPc(ist,1+(n-1),hnvec_c,q) );
170 w(ist,c,hnvec) = Dc(ist,c) * acc;
172 dwq = Dc(ist,c) * dacc(q);
173 if pj(q) == ist && pr(q) == cls
174 dwq = dwq + Dc(ist,c) * acc; % d(D*y)/dy = D
176 dw(ist,c,hnvec,q) = dwq;
182 % ---- throughputs, eq. (18) ------------------------------------------
184 den = Zc(c) + sum(w(1:M,c,hnvec));
185 x(c,hnvec) = nvec(c) / den;
190 sdw = sdw + dw(ist,c,hnvec,q);
192 dx(c,hnvec,q) = -nvec(c) / den^2 * sdw;
197 % ---- conditional marginal probabilities, eq. (14)-(15) --------------
202 hnvec_c = hashpop(oner(nvec,c),Nc,C,prods);
203 cls = closedClasses(c);
204 Pprev = Pc(ist, 1+(n-1), hnvec_c);
205 Pc(ist, 1+n, hnvec) = Pc(ist, 1+n, hnvec) ...
206 + Dc(ist,c) * EC(ist,n) * x(c,hnvec) * Pprev;
208 dt = Dc(ist,c) * ( dEC_dLo(ist,n)*dLo(ist,q)*x(c,hnvec)*Pprev ...
209 + EC(ist,n)*dx(c,hnvec,q)*Pprev ...
210 + EC(ist,n)*x(c,hnvec)*dPc(ist,1+(n-1),hnvec_c,q) );
211 if pj(q) == ist && pr(q) == cls
212 dt = dt + Dc(ist,c) * EC(ist,n) * x(c,hnvec) * Pprev;
214 dPc(ist,1+n,hnvec,q) = dPc(ist,1+n,hnvec,q) + dt;
219 % eq. (17). The primal keeps pfqn_mvaldmx
's max(eps,.) floor so that the
220 % base measures agree entry by entry; the derivative is the exact
221 % -sum of the derivatives, since the floor is a numerical guard and not
223 Pc(ist, 1+0, hnvec) = max(eps, 1-sum(Pc(ist, 1+(1:nc), hnvec)));
225 dPc(ist,1+0,hnvec,q) = -sum(dPc(ist,1+(1:nc),hnvec,q));
229 nvec = pprod(nvec, Nc);
232% ---- measures and their derivatives at the full population ---------------
233hnvec = hashpop(Nc,Nc,C,prods);
234XN = zeros(1,R); QN = zeros(M,R); UN = zeros(M,R); CN = zeros(M,R);
237% closed classes, eq. (32)
239 cls = closedClasses(c);
240 XN(cls) = x(c,hnvec);
241 hnvec_c = hashpop(oner(Nc,c),Nc,C,prods);
243 CN(ist,cls) = w(ist,c,hnvec);
244 QN(ist,cls) = XN(cls) * CN(ist,cls);
246 dQN(ist,cls,q) = dx(c,hnvec,q)*w(ist,c,hnvec) + x(c,hnvec)*dw(ist,c,hnvec,q);
250 uacc = uacc + Dc(ist,c) * x(c,hnvec) * Eprime(ist,1+n-1) / E(ist,1+n-1) ...
251 * Pc(ist, 1+n-1, hnvec_c);
257% open classes, eq. (33)
258for ridx = 1:length(openClasses)
259 r = openClasses(ridx);
265 Pn = Pc(ist, 1+n, hnvec);
266 acc = acc + (n+1) * EC(ist,n+1) * Pn;
268 dacc(q) = dacc(q) + (n+1) * ( dEC_dLo(ist,n+1)*dLo(ist,q)*Pn ...
269 + EC(ist,n+1)*dPc(ist,1+n,hnvec,q) );
272 QN(ist,r) = lambda(r) * D(ist,r) * acc;
273 CN(ist,r) = QN(ist,r) / lambda(r);
275 dq = lambda(r) * D(ist,r) * dacc(q);
276 if pj(q) == ist && pr(q) == r
277 dq = dq + lambda(r) * D(ist,r) * acc;
283 uacc = uacc + lambda(r) * Eprime(ist,1+n+1) / E(ist,1+n+1) * Pc(ist, 1+n, hnvec);
289% ---- moments -------------------------------------------------------------
290% Cov[n(i,r),n(j,s)] = d nbar(i,r) / dy_(j,s)
291QCovFull = zeros(M,R,M,R);
296 QCovFull(i,r,j,s) = dQN(i,r,pidx(j,s));
302QCovFull = (QCovFull + permute(QCovFull,[3 4 1 2])) / 2;
303mom.QCovAsym = max(abs(QCovRaw(:) - reshape(permute(QCovRaw,[3 4 1 2]),[],1)));
304if isempty(mom.QCovAsym)
314 QCov(i,r,s) = QCovFull(i,r,i,s);
316 QVar(i,r) = QCov(i,r,r);
318 QTotVar(i) = sum(sum(QCov(i,:,:)));
321mom.X = XN; mom.Q = QN; mom.U = UN; mom.R = CN;
323mom.QCovFull = QCovFull;
325mom.QTotVar = QTotVar;