LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
npfqn_traffic_idc.m
1function ctx = npfqn_traffic_idc(lambda0, P, c2a0, a0IdcFun, mu, cs2, sIdcFun, corrections)
2% ctx = NPFQN_TRAFFIC_IDC(lambda0,P,c2a0,a0IdcFun,mu,cs2,sIdcFun)
3%
4% Traffic variability equations for the Robust Queueing Network Analyzer
5% (RQNA) of W. Whitt and W. You (2018), "A Robust Queueing Network Analyzer
6% Based on Indices of Dispersion". Assembles and solves:
7% - the limiting variability equations (eq. 42/44) for the asymptotic
8% total-arrival variability parameters c2_{a,i} = I_{a,i}(Inf);
9% - a solver (handle ctx.IaFun) for the time-dependent index of dispersion
10% for counts (IDC) equations (eq. 40/43), returning I_{a,i}(t) for all
11% internal arrival flows, using the default correction terms alpha_{i,j}
12% (eq. 34) and beta_i (eqs. 38-39) and tuning function h(rho)=rho^2.
13%
14% This models a single-class open queueing network of K single-server FCFS
15% queues with Markovian routing P (P(i,j)=p_{i,j}).
16%
17% Inputs (all K-vectors are column vectors, K = number of queues):
18% lambda0 : external arrival rate into each queue
19% P : KxK routing matrix among queues
20% c2a0 : asymptotic IDC (SCV) of each external arrival process
21% a0IdcFun : handle, a0IdcFun(t) -> Kx1 external arrival IDC I_{a,0,i}(t)
22% mu : service rate at each queue
23% cs2 : service SCV c2_{s,i}
24% sIdcFun : handle, sIdcFun(t) -> Kx1 service IDC I_{s,i}(t)
25%
26% Output ctx: struct with fields
27% lambda,rho,Xi,c2a,c2d,c2aij,c2x and function handle IaFun(t) returning the
28% Kx1 vector of total arrival IDCs I_{a,i}(t).
29
30K = numel(mu);
31lambda0 = lambda0(:); mu = mu(:); cs2 = cs2(:); c2a0 = c2a0(:);
32if nargin < 8 || isempty(corrections)
33 corrections = struct();
34end
35if ~isfield(corrections,'alpha'), corrections.alpha = true; end
36if ~isfield(corrections,'beta'), corrections.beta = true; end
37useAlpha = corrections.alpha; useBeta = corrections.beta;
38
39% ----- traffic rate equations (eq. 20-21) -----
40Xi = inv(eye(K) - P'); % fundamental matrix (I-P')^{-1}
41lambda = Xi * lambda0; % total arrival rate at each queue
42rho = lambda ./ mu;
43lam_ji = (lambda(:) * ones(1,K)) .* P; % lam_ji(j,i) = lambda_j p_{j,i}
44
45% ----- correction terms (asymptotic, w*(Inf)=1) -----
46% alpha: c2alpha_{i,j} = 2 Xi_{i,j} p_{i,j} (1-p_{i,j})
47c2alpha = 2 * Xi .* P .* (1 - P); % KxK
48if ~useAlpha, c2alpha = zeros(K,K); end
49
50% beta: zeta_{j,i;k,i} from eq. (39), then c2beta_i = (2/lambda_i) sum_{j<k} zeta
51Sigma = cell(K,1); % splitting covariance at each station l
52for l = 1:K
53 pl = P(l,:); % 1xK routing out of l
54 Sl = -(pl' * pl) * lambda(l);
55 Sl(1:K+1:end) = pl .* (1 - pl) * lambda(l);
56 Sigma{l} = Sl;
57end
58Amat = diag(c2a0 .* lambda0); % external arrival Brownian variance-rate
59for l = 1:K
60 Amat = Amat + Sigma{l};
61end
62% zetaAll{i} is KxK with entry (j,k) = zeta_{j,i;k,i}
63zetaAll = cell(K,1);
64c2beta = zeros(K,1);
65for i = 1:K
66 nu = (P(:,i) * ones(1,K)) .* Xi; % nu(l,:) = p_{l,i} * Xi(l,:) (row l)
67 Z = nu * Amat * nu'; % first term for all (j,k)
68 % add cross terms nu_k*Sigma_j*e_i + nu_j*Sigma_k*e_i
69 for j = 1:K
70 for k = 1:K
71 Z(j,k) = Z(j,k) + nu(k,:)*Sigma{j}(:,i) + nu(j,:)*Sigma{k}(:,i);
72 end
73 end
74 zetaAll{i} = Z;
75 s = 0;
76 for j = 1:K
77 for k = j+1:K
78 s = s + Z(j,k);
79 end
80 end
81 if lambda(i) > 0
82 c2beta(i) = (2/lambda(i)) * s;
83 end
84end
85if ~useBeta, c2beta = zeros(K,1); zetaAll = repmat({zeros(K,K)},K,1); end
86
87% ----- limiting variability equations (eq. 44): (E - Minf) c = binf -----
88% variable ordering: [c2a(1..K), c2aij(i,j) row-major, c2d(1..K)]
89Na = K; Naij = K*K; Nd = K;
90N = Na + Naij + Nd;
91ia = @(i) i;
92iaij= @(i,j) Na + (i-1)*K + j;
93id = @(i) Na + Naij + i;
94
95Minf = zeros(N,N);
96binf = zeros(N,1);
97for i = 1:K
98 % c2a_i = sum_j (lam_ji/lambda_i) c2aij_{j,i} + (lambda0_i/lambda_i) c2a0_i + c2beta_i
99 if lambda(i) > 0
100 for j = 1:K
101 Minf(ia(i), iaij(j,i)) = lam_ji(j,i) / lambda(i);
102 end
103 binf(ia(i)) = (lambda0(i)/lambda(i)) * c2a0(i) + c2beta(i);
104 end
105 for j = 1:K
106 % c2aij_{i,j} = p_{i,j} c2d_i + (1-p_{i,j}) + c2alpha_{i,j}
107 Minf(iaij(i,j), id(i)) = P(i,j);
108 binf(iaij(i,j)) = (1 - P(i,j)) + c2alpha(i,j);
109 end
110 % c2d_i = c2a_i
111 Minf(id(i), ia(i)) = 1;
112end
113csol = (eye(N) - Minf) \ binf;
114c2a = csol(1:K);
115c2aij= reshape(csol(Na+1:Na+Naij), K, K)'; % c2aij(i,j)
116c2d = csol(Na+Naij+1:end);
117c2x = c2a + cs2; % c2_{x,i} = I_{a,i}(Inf)+c2_{s,i}
118
119% ----- assemble context and time-dependent solver -----
120ctx = struct();
121ctx.K = K; ctx.lambda = lambda; ctx.lambda0 = lambda0; ctx.mu = mu;
122ctx.rho = rho; ctx.Xi = Xi; ctx.P = P; ctx.cs2 = cs2;
123ctx.c2a = c2a; ctx.c2aij = c2aij; ctx.c2d = c2d; ctx.c2x = c2x;
124ctx.c2a0 = c2a0; ctx.lam_ji = lam_ji;
125ctx.zetaAll = zetaAll; ctx.c2alpha = c2alpha;
126ctx.a0IdcFun = a0IdcFun; ctx.sIdcFun = sIdcFun;
127ctx.IaFun = @(t) local_idc_at(ctx, t);
128end
129
130function Ia = local_idc_at(ctx, t)
131% Solve the time-dependent IDC equations (43) at a single time t; return the
132% Kx1 vector of total arrival IDCs I_{a,i}(t).
133K = ctx.K; P = ctx.P; lambda = ctx.lambda; rho = ctx.rho;
134c2x = ctx.c2x; lam_ji = ctx.lam_ji; Xi = ctx.Xi;
135h = rho.^2; % tuning function h(rho)=rho^2
136
137% departure weights w_i(t) = w*((1-rho_i)^2 lambda_i t /(h_i c2x_i))
138warg = zeros(K,1);
139for i = 1:K
140 if h(i) > 0 && c2x(i) > 0
141 warg(i) = (1-rho(i))^2 * lambda(i) * t / (h(i) * c2x(i));
142 else
143 warg(i) = Inf;
144 end
145end
146w = npfqn_rqna_weight(warg);
147
148Ia0 = ctx.a0IdcFun(t); Ia0 = Ia0(:);
149Is = ctx.sIdcFun(rho .* t); Is = Is(:); % service IDC at scaled time rho*t
150
151% time-dependent correction terms
152% alpha_{i,j}(t) = c2alpha_{i,j} * w_i(t)
153alpha_t = ctx.c2alpha .* (w * ones(1,K)); % row i scaled by w(i)
154% beta_i(t) = (1/lambda_i) sum_{j~=k} zeta_{j,i;k,i} w*(arg_j), where the weight
155% for source station j feeding i uses arg_j = (1-rho_j)^2 p_{j,i} lambda_j t/(h_j c2x_j)
156beta_t = zeros(K,1);
157for i = 1:K
158 Z = ctx.zetaAll{i};
159 % weight for source station j feeding i:
160 wj = zeros(K,1);
161 for j = 1:K
162 if h(j) > 0 && c2x(j) > 0 && P(j,i) > 0
163 aj = (1-rho(j))^2 * P(j,i) * lambda(j) * t / (h(j) * c2x(j));
164 wj(j) = npfqn_rqna_weight(aj);
165 end
166 end
167 s = 0;
168 for j = 1:K
169 for k = 1:K
170 if j ~= k
171 s = s + Z(j,k) * wj(j);
172 end
173 end
174 end
175 if lambda(i) > 0
176 beta_t(i) = s / lambda(i);
177 end
178end
179
180% assemble (E - M(t)) I = b(t)
181Na = K; Naij = K*K; Nd = K; N = Na+Naij+Nd;
182ia = @(i) i; iaij= @(i,j) Na+(i-1)*K+j; idd = @(i) Na+Naij+i;
183M = zeros(N,N); b = zeros(N,1);
184for i = 1:K
185 if lambda(i) > 0
186 for j = 1:K
187 M(ia(i), iaij(j,i)) = lam_ji(j,i)/lambda(i);
188 end
189 b(ia(i)) = (ctx.lambda0(i)/lambda(i))*Ia0(i) + beta_t(i);
190 end
191 for j = 1:K
192 M(iaij(i,j), idd(i)) = P(i,j);
193 b(iaij(i,j)) = (1 - P(i,j)) + alpha_t(i,j);
194 end
195 M(idd(i), ia(i)) = w(i);
196 b(idd(i)) = (1 - w(i)) * Is(i);
197end
198sol = (eye(N) - M) \ b;
199Ia = sol(1:K);
200end
Definition Station.m:245