89 const std::vector<int>& N,
const std::vector<T>& Z,
90 const std::vector<int>& b,
int tmax) {
91 const std::size_t M = V.
rows();
92 const std::size_t R = N.size();
94 throw InputError(
"pfqn_sens_respt: visit matrix and population vector disagree on the class count");
95 if (S.size() != M)
throw InputError(
"pfqn_sens_respt: service-time vector has the wrong length");
96 if (!Z.empty() && Z.size() != R)
97 throw InputError(
"pfqn_sens_respt: think-time vector has the wrong length");
98 if (!b.empty() && b.size() != M)
99 throw InputError(
"pfqn_sens_respt: server-count vector has the wrong length");
100 if (tmax < 1 || tmax > 3)
102 "pfqn_sens_respt: tmax must be 1, 2 or 3, the orders at which the coefficients "
103 "a_{t,tau}(0) are tabulated in the reference");
108 std::vector<int> bv = b.empty() ? std::vector<int>(M, 1) : b;
109 std::size_t bmax = 1;
110 for (std::size_t i = 0; i < M; ++i) {
112 throw InputError(
"pfqn_sens_respt: every station must have at least one server");
113 if (
static_cast<std::size_t
>(bv[i]) > bmax) bmax =
static_cast<std::size_t
>(bv[i]);
115 throw InputError(
"pfqn_sens_respt: every FCFS station needs a strictly positive service time");
119 res.
XN.assign(R, zero);
123 res.
WM.assign(
static_cast<std::size_t
>(tmax),
Matrix<T>(M, R, zero));
126 res.
m.assign(M, zero);
127 res.
Var.assign(M, zero);
131 bool anyPositive =
false;
133 if (v < 0)
throw InputError(
"pfqn_sens_respt: negative population");
134 if (v > 0) anyPositive =
true;
136 if (!anyPositive || M == 0 || R == 0)
return res;
139 for (std::size_t i = 0; i < M; ++i)
140 for (std::size_t l = 0; l < R; ++l) rho(i, l) = S[i] * V(i, l);
141 std::vector<T> mu(M, zero);
142 for (std::size_t i = 0; i < M; ++i) mu[i] = one / S[i];
144 const auto Zr = [&](std::size_t r) -> T {
return Z.empty() ? zero : Z[r]; };
151 std::vector<Matrix<T>> D1m(totpop,
Matrix<T>(M, M, zero));
152 std::vector<Matrix<T>> D2m(totpop,
Matrix<T>(M, M, zero));
153 std::vector<Matrix<T>> Prow(totpop,
Matrix<T>(M, bmax, zero));
154 std::vector<std::vector<Matrix<T>>> D1p(totpop, std::vector<
Matrix<T>>(M,
Matrix<T>(bmax, M, zero)));
155 std::vector<std::vector<Matrix<T>>> D2p(totpop, std::vector<
Matrix<T>>(M,
Matrix<T>(bmax, M, zero)));
156 for (std::size_t i = 0; i < M; ++i) Prow[0](i, 0) = one;
158 std::vector<std::size_t> rows(R, 0);
161 std::vector<T> lam(R, zero);
162 Matrix<T> d1lam(R, M, zero), d2lam(R, M, zero);
164 for (std::size_t k = 1; k < totpop; ++k) {
167 for (std::size_t i = 0; i < M; ++i) {
172 for (std::size_t s = 0; s < R; ++s) {
173 const std::size_t row = n[s] > 0 ? k - radix[s] : 0;
175 if (n[s] == 0)
continue;
176 for (std::size_t i = 0; i < M; ++i) {
178 T brk = one + Mrow(row, i);
179 for (
int j = 0; j + 2 <= bv[i]; ++j)
181 wv(i, s) = rho(i, s) / bi * brk;
182 for (std::size_t h = 0; h < M; ++h) {
183 T dbrk = D1m[row](i, h);
184 T d2brk = D2m[row](i, h);
185 for (
int j = 0; j + 2 <= bv[i]; ++j) {
187 dbrk += c * D1p[row][i](
static_cast<std::size_t
>(j), h);
188 d2brk += c * D2p[row][i](
static_cast<std::size_t
>(j), h);
191 d1w[i](s, h) = rho(i, s) / bi * (brk + dbrk);
194 d1w[i](s, h) = rho(i, s) / bi * dbrk;
195 d2w[i](s, h) = rho(i, s) / bi * d2brk;
202 for (std::size_t s = 0; s < R; ++s) {
204 for (std::size_t h = 0; h < M; ++h) {
208 if (n[s] == 0)
continue;
210 for (std::size_t i = 0; i < M; ++i) sw += wv(i, s);
211 const T den = Zr(s) + sw;
214 const T den2 = den * den;
215 const T den3 = den2 * den;
216 for (std::size_t h = 0; h < M; ++h) {
217 T dden = zero, d2den = zero;
218 for (std::size_t i = 0; i < M; ++i) {
219 dden += d1w[i](s, h);
220 d2den += d2w[i](s, h);
222 d1lam(s, h) = -nsT * dden / den2;
223 d2lam(s, h) = -nsT * d2den / den2 +
229 for (std::size_t i = 0; i < M; ++i) {
231 for (std::size_t s = 0; s < R; ++s)
232 if (n[s] > 0) acc += lam[s] * wv(i, s);
234 for (std::size_t h = 0; h < M; ++h) {
235 T d1acc = zero, d2acc = zero;
236 for (std::size_t s = 0; s < R; ++s) {
237 if (n[s] == 0)
continue;
238 d1acc += d1lam(s, h) * wv(i, s) + lam[s] * d1w[i](s, h);
239 d2acc += d2lam(s, h) * wv(i, s) +
241 lam[s] * d2w[i](s, h);
243 D1m[k](i, h) = d1acc;
244 D2m[k](i, h) = d2acc;
250 for (std::size_t s = 0; s < R; ++s)
nc += n[s];
251 for (std::size_t i = 0; i < M; ++i) {
252 for (
int j = 1; j <= bv[i] - 1; ++j) {
253 const std::size_t ju =
static_cast<std::size_t
>(j);
254 if (j >
nc)
continue;
257 for (std::size_t l = 0; l < R; ++l) {
258 if (n[l] == 0)
continue;
259 acc += lam[l] * rho(i, l) * Prow[rows[l]](i, ju - 1);
261 Prow[k](i, ju) = acc / jT;
262 for (std::size_t h = 0; h < M; ++h) {
263 T d1acc = zero, d2acc = zero;
264 for (std::size_t l = 0; l < R; ++l) {
265 if (n[l] == 0)
continue;
266 const T pprev = Prow[rows[l]](i, ju - 1);
267 const T d1prev = D1p[rows[l]][i](ju - 1, h);
268 const T d2prev = D2p[rows[l]][i](ju - 1, h);
277 d1acc += rho(i, l) * (d1lam(l, h) * pprev + lam[l] * v1);
278 d2acc += rho(i, l) * (d2lam(l, h) * pprev +
282 D1p[k][i](ju, h) = d1acc / jT;
283 D2p[k][i](ju, h) = d2acc / jT;
288 std::vector<T> d1ui(M, zero), d2ui(M, zero);
289 for (std::size_t l = 0; l < R; ++l) {
290 if (n[l] == 0)
continue;
291 ui += lam[l] * rho(i, l);
292 for (std::size_t h = 0; h < M; ++h) {
294 d1ui[h] += rho(i, l) * (d1lam(l, h) + lam[l]);
297 d1ui[h] += rho(i, l) * d1lam(l, h);
298 d2ui[h] += rho(i, l) * d2lam(l, h);
304 for (
int j = 1; j <= bv[i] - 1; ++j)
306 Prow[k](i, 0) = one - acc0 / biT;
307 for (std::size_t h = 0; h < M; ++h) {
308 T d1acc0 = d1ui[h], d2acc0 = d2ui[h];
309 for (
int j = 1; j <= bv[i] - 1; ++j) {
311 d1acc0 += c * D1p[k][i](
static_cast<std::size_t
>(j), h);
312 d2acc0 += c * D2p[k][i](
static_cast<std::size_t
>(j), h);
314 D1p[k][i](0, h) = -d1acc0 / biT;
315 D2p[k][i](0, h) = -d2acc0 / biT;
320 for (std::size_t s = 0; s < R; ++s) res.
XN[s] = lam[s];
321 for (std::size_t i = 0; i < M; ++i)
322 for (std::size_t s = 0; s < R; ++s) {
323 res.
Wresid(i, s) = wv(i, s);
324 res.
QN(i, s) = lam[s] * wv(i, s);
325 res.
UN(i, s) = lam[s] * rho(i, s);
329 const std::size_t last = totpop - 1;
330 for (std::size_t i = 0; i < M; ++i) {
331 res.
m[i] = Mrow(last, i);
332 for (std::size_t j = 0; j < bmax; ++j) res.
p(i, j) = Prow[last](i, j);
333 res.
Var[i] = D1m[last](i, i);
337 std::vector<std::size_t> rowsN(R, 0);
338 for (std::size_t l = 0; l < R; ++l)
339 if (N[l] > 0) rowsN[l] = last - radix[l];
341 for (std::size_t i = 0; i < M; ++i) {
346 a(0, 0) = (one - bT) / (bT * mT);
347 a(0, 1) = one / (bT * mT);
349 const T d = bT * bT * mT * mT;
355 const T d = bT * bT * bT * mT * mT * mT;
363 for (std::size_t l = 0; l < R; ++l) {
364 if (N[l] == 0 || V(i, l) <= zero)
continue;
365 const std::size_t rl = rowsN[l];
366 const T mt = Mrow(rl, i);
367 const T d1t = D1m[rl](i, i);
368 const T d2t = D2m[rl](i, i);
372 EQ[2] = d1t + mt * mt;
374 for (
int t = 1; t <= tmax; ++t) {
377 for (
int tau = 0; tau <= t; ++tau)
378 val += a(
static_cast<std::size_t
>(t - 1),
static_cast<std::size_t
>(tau)) *
381 for (
int j = 0; j <= bv[i] - 1; ++j) {
383 for (
int tau = 0; tau <= t; ++tau) {
385 const T jp = tau == 0 ? one
387 static_cast<unsigned>(tau));
388 inner += a(
static_cast<std::size_t
>(t - 1),
static_cast<std::size_t
>(tau)) * jp;
390 val -= Prow[rl](i,
static_cast<std::size_t
>(j)) * inner;
392 res.
WM[
static_cast<std::size_t
>(t - 1)](i, l) = val;
394 res.
W(i, l) = res.
WM[0](i, l);
399 for (std::size_t i = 0; i < M; ++i)
400 for (std::size_t l = 0; l < R; ++l)
401 res.
WVar(i, l) = res.
WM[1](i, l) - res.
WM[0](i, l) * res.
WM[0](i, l);
403 for (std::size_t i = 0; i < M; ++i)
404 for (std::size_t l = 0; l < R; ++l) {
405 const T mu3 = res.
WM[2](i, l) -