5#ifndef LINE_API_QSYS_QSYS_BMAPPHNN_RETRIAL_H
6#define LINE_API_QSYS_QSYS_BMAPPHNN_RETRIAL_H
140inline std::vector<std::vector<int>> retrial_compositions(
int n,
int M) {
141 std::vector<std::vector<int>> out;
142 if (M <= 0)
return out;
144 out.push_back(std::vector<int>(1, n));
147 for (
int m1 = n; m1 >= 0; --m1) {
148 const std::vector<std::vector<int>> sub = retrial_compositions(n - m1, M - 1);
149 for (std::size_t s = 0; s < sub.
size(); ++s) {
150 std::vector<int> row;
151 row.reserve(
static_cast<std::size_t
>(M));
153 row.insert(row.end(), sub[s].begin(), sub[s].end());
161inline int retrial_find(
const std::vector<std::vector<int>>& comps,
const std::vector<int>& key) {
162 for (std::size_t j = 0; j < comps.size(); ++j)
163 if (comps[j] == key)
return static_cast<int>(j);
170 std::vector<Matrix<T>> D;
174 int M = 0, N = 0, V = 0, K = 0;
176 std::vector<std::size_t> Tn;
179 std::vector<std::vector<std::vector<int>>> comps;
184std::size_t retrial_offset(
const RetrialCtx<T>& c,
int n) {
186 for (
int i = 0; i < n; ++i) off += c.Tn[
static_cast<std::size_t
>(i)];
192Matrix<T> retrial_L(
const RetrialCtx<T>& c,
int n) {
193 const T zero = num_traits<T>::from_int(0);
195 Matrix<T> L(c.Tn[
static_cast<std::size_t
>(n)], c.Tn[
static_cast<std::size_t
>(n - 1)], zero);
196 const std::vector<std::vector<int>>& cn = c.comps[
static_cast<std::size_t
>(n)];
197 const std::vector<std::vector<int>>& cm = c.comps[
static_cast<std::size_t
>(n - 1)];
198 for (std::size_t i = 0; i < cn.size(); ++i)
199 for (
int l = 0; l < c.M; ++l) {
200 if (cn[i][
static_cast<std::size_t
>(l)] <= 0)
continue;
201 std::vector<int> mp = cn[i];
202 --mp[
static_cast<std::size_t
>(l)];
203 const int j = retrial_find(cm, mp);
205 L(i,
static_cast<std::size_t
>(j)) +=
206 num_traits<T>::from_int(cn[i][
static_cast<std::size_t
>(l)]) *
207 c.S0[
static_cast<std::size_t
>(l)];
214Matrix<T> retrial_A(
const RetrialCtx<T>& c,
int n) {
215 const T zero = num_traits<T>::from_int(0);
216 if (n == 0)
return Matrix<T>(1, 1, zero);
217 Matrix<T> A(c.Tn[
static_cast<std::size_t
>(n)], c.Tn[
static_cast<std::size_t
>(n)], zero);
218 const std::vector<std::vector<int>>& cn = c.comps[
static_cast<std::size_t
>(n)];
219 for (std::size_t i = 0; i < cn.size(); ++i)
220 for (
int l = 0; l < c.M; ++l) {
221 if (cn[i][
static_cast<std::size_t
>(l)] <= 0)
continue;
222 for (
int lp = 0; lp < c.M; ++lp) {
223 if (lp == l)
continue;
224 if (!(c.S(
static_cast<std::size_t
>(l),
static_cast<std::size_t
>(lp)) > zero))
226 std::vector<int> mp = cn[i];
227 --mp[
static_cast<std::size_t
>(l)];
228 ++mp[
static_cast<std::size_t
>(lp)];
229 const int j = retrial_find(cn, mp);
231 A(i,
static_cast<std::size_t
>(j)) +=
232 num_traits<T>::from_int(cn[i][
static_cast<std::size_t
>(l)]) *
233 c.S(
static_cast<std::size_t
>(l),
static_cast<std::size_t
>(lp));
241Matrix<T> retrial_P(
const RetrialCtx<T>& c,
int n) {
242 const T zero = num_traits<T>::from_int(0);
244 Matrix<T> P(c.Tn[
static_cast<std::size_t
>(n)], c.Tn[
static_cast<std::size_t
>(n + 1)], zero);
245 const std::vector<std::vector<int>>& cn = c.comps[
static_cast<std::size_t
>(n)];
246 const std::vector<std::vector<int>>& cp = c.comps[
static_cast<std::size_t
>(n + 1)];
247 for (std::size_t i = 0; i < cn.size(); ++i)
248 for (
int l = 0; l < c.M; ++l) {
249 if (!(c.beta[
static_cast<std::size_t
>(l)] > zero))
continue;
250 std::vector<int> mp = cn[i];
251 ++mp[
static_cast<std::size_t
>(l)];
252 const int j = retrial_find(cp, mp);
254 P(i,
static_cast<std::size_t
>(j)) += c.beta[
static_cast<std::size_t
>(l)];
261Matrix<T> retrial_Delta(
const RetrialCtx<T>& c,
int n) {
262 const T zero = num_traits<T>::from_int(0);
263 if (n == 0)
return Matrix<T>(1, 1, zero);
264 Matrix<T> D(c.Tn[
static_cast<std::size_t
>(n)], c.Tn[
static_cast<std::size_t
>(n)], zero);
265 const std::vector<std::vector<int>>& cn = c.comps[
static_cast<std::size_t
>(n)];
266 for (std::size_t i = 0; i < cn.size(); ++i) {
268 for (
int l = 0; l < c.M; ++l)
269 total += num_traits<T>::from_int(cn[i][
static_cast<std::size_t
>(l)]) *
270 T(-c.S(
static_cast<std::size_t
>(l),
static_cast<std::size_t
>(l)));
278Matrix<T> retrial_Gamma(
const RetrialCtx<T>& c,
int nu) {
279 const T zero = num_traits<T>::from_int(0), one = num_traits<T>::from_int(1);
280 Matrix<T> G(c.d, c.d, zero);
282 for (
int n = 0; n <= c.N; ++n) {
283 const std::size_t width = c.Tn[
static_cast<std::size_t
>(n)];
284 if (
static_cast<long>(n) > c.R[
static_cast<std::size_t
>(nu)])
285 for (std::size_t t = 0; t < width; ++t) G(off + t, off + t) = one;
293T retrial_G_scalar(
const RetrialCtx<T>& c,
int n,
int nu,
int nuPrime) {
294 const T zero = num_traits<T>::from_int(0);
295 if (n <= c.N - c.K)
return zero;
297 for (
int k = c.N - n + 1; k <= c.K; ++k)
299 total += c.D[
static_cast<std::size_t
>(k)](
static_cast<std::size_t
>(nu),
300 static_cast<std::size_t
>(nuPrime));
301 return T(c.p * total);
309Matrix<T> retrial_Pprod(
const RetrialCtx<T>& c,
const std::vector<Matrix<T>>& P,
int n,
int upto) {
310 Matrix<T> prod =
eye<T>(c.Tn[
static_cast<std::size_t
>(n)]);
311 for (
int j = n; j < upto; ++j)
312 if (j < c.N) prod =
matmul(prod, P[
static_cast<std::size_t
>(j)]);
318Matrix<T> retrial_B(
const RetrialCtx<T>& c,
const std::vector<Matrix<T>>& L,
319 const std::vector<Matrix<T>>& A,
const std::vector<Matrix<T>>& P,
320 const std::vector<Matrix<T>>& Delta,
int nu) {
321 const T zero = num_traits<T>::from_int(0);
322 Matrix<T> B(c.d, c.d, zero);
323 for (
int n = 0; n <= c.N; ++n) {
324 const std::size_t rs = retrial_offset(c, n);
325 const std::size_t w = c.Tn[
static_cast<std::size_t
>(n)];
326 const T g = retrial_G_scalar(c, n, nu, nu);
330 for (std::size_t a = 0; a < w; ++a)
331 for (std::size_t b = 0; b < w; ++b)
332 B(rs + a, rs + b) = A[
static_cast<std::size_t
>(n)](a, b) +
333 Delta[
static_cast<std::size_t
>(n)](a, b) +
337 const std::size_t cs = retrial_offset(c, n - 1);
338 for (std::size_t a = 0; a < w; ++a)
339 for (std::size_t b = 0; b < c.Tn[
static_cast<std::size_t
>(n - 1)]; ++b)
340 B(rs + a, cs + b) = L[
static_cast<std::size_t
>(n)](a, b);
342 for (
int k = 1; k <= c.K; ++k) {
343 if (n + k > c.N)
continue;
344 const std::size_t cs = retrial_offset(c, n + k);
345 const T dk = c.D[
static_cast<std::size_t
>(k)](
static_cast<std::size_t
>(nu),
346 static_cast<std::size_t
>(nu));
347 const Matrix<T> pp = retrial_Pprod(c, P, n, n + k);
348 for (std::size_t a = 0; a < w; ++a)
349 for (std::size_t b = 0; b < c.Tn[
static_cast<std::size_t
>(n + k)]; ++b)
350 B(rs + a, cs + b) = dk * pp(a, b);
358Matrix<T> retrial_Bbar(
const RetrialCtx<T>& c,
const std::vector<Matrix<T>>& P,
int nu) {
359 const T zero = num_traits<T>::from_int(0);
360 Matrix<T> B(c.d, c.d, zero);
361 const long cap = c.R[
static_cast<std::size_t
>(nu)] <
static_cast<long>(c.N - 1)
362 ? c.R[
static_cast<std::size_t
>(nu)]
363 : static_cast<long>(c.N - 1);
364 for (
long n = 0; n <= cap; ++n) {
365 const std::size_t rs = retrial_offset(c,
static_cast<int>(n));
366 const std::size_t cs = retrial_offset(c,
static_cast<int>(n) + 1);
367 const Matrix<T>& Pn = P[
static_cast<std::size_t
>(n)];
368 for (std::size_t a = 0; a < Pn.rows(); ++a)
369 for (std::size_t b = 0; b < Pn.cols(); ++b) B(rs + a, cs + b) = Pn(a, b);
376Matrix<T> retrial_Btilde(
const RetrialCtx<T>& c,
const std::vector<Matrix<T>>& P,
int nu,
378 const T zero = num_traits<T>::from_int(0);
379 Matrix<T> B(c.d, c.d, zero);
380 for (
int n = 0; n <= c.N; ++n) {
381 const std::size_t rs = retrial_offset(c, n);
382 const std::size_t w = c.Tn[
static_cast<std::size_t
>(n)];
383 const T g = retrial_G_scalar(c, n, nu, nuPrime);
384 for (std::size_t a = 0; a < w; ++a) B(rs + a, rs + a) = g;
385 for (
int k = 1; k <= c.K; ++k) {
386 if (n + k > c.N)
continue;
387 const std::size_t cs = retrial_offset(c, n + k);
388 const T dk = c.D[
static_cast<std::size_t
>(k)](
static_cast<std::size_t
>(nu),
389 static_cast<std::size_t
>(nuPrime));
390 const Matrix<T> pp = retrial_Pprod(c, P, n, n + k);
391 for (std::size_t a = 0; a < w; ++a)
392 for (std::size_t b = 0; b < c.Tn[
static_cast<std::size_t
>(n + k)]; ++b)
393 B(rs + a, cs + b) = dk * pp(a, b);
405Matrix<T> retrial_C(
const RetrialCtx<T>& c,
const std::vector<Matrix<T>>& P,
int n,
int k,
int nu,
407 const T zero = num_traits<T>::from_int(0), one = num_traits<T>::from_int(1);
408 if (n < c.N - c.K + k)
return Matrix<T>();
410 const int batch = c.N - n + k;
411 if (batch < 1 || batch > c.K)
return Matrix<T>();
412 const T db = c.D[
static_cast<std::size_t
>(batch)](
static_cast<std::size_t
>(nu),
413 static_cast<std::size_t
>(nuPrime));
414 Matrix<T> pp = retrial_Pprod(c, P, n, c.N);
415 for (std::size_t a = 0; a < pp.rows(); ++a)
416 for (std::size_t b = 0; b < pp.cols(); ++b) pp(a, b) = T(one - c.p) * db * pp(a, b);
419 if (k < 1 || k > c.K)
return Matrix<T>();
420 const T dk = c.D[
static_cast<std::size_t
>(k)](
static_cast<std::size_t
>(nu),
421 static_cast<std::size_t
>(nuPrime));
422 Matrix<T> out(c.Tn[
static_cast<std::size_t
>(c.N)], c.Tn[
static_cast<std::size_t
>(c.N)], zero);
423 for (std::size_t a = 0; a < out.rows(); ++a) out(a, a) = T(one - c.p) * dk;
445 const std::vector<T>& beta,
const Matrix<T>& S,
446 int N,
const T& alpha,
const T& gamma,
const T& p,
447 const std::vector<long>& R,
450 if (D.size() < 2)
throw InputError(
"qsys_bmapphnn_retrial: the BMAP needs D0 and at least D1");
451 if (N < 1)
throw InputError(
"qsys_bmapphnn_retrial: at least one server is required");
452 const int V =
static_cast<int>(D[0].rows());
453 if (V < 1)
throw InputError(
"qsys_bmapphnn_retrial: empty BMAP");
454 for (std::size_t k = 0; k < D.size(); ++k)
455 if (D[k].rows() !=
static_cast<std::size_t
>(V) || D[k].cols() !=
static_cast<std::size_t
>(V))
456 throw InputError(
"qsys_bmapphnn_retrial: every BMAP matrix must be V x V");
457 const int M =
static_cast<int>(S.
rows());
458 if (M < 1 || S.
cols() !=
static_cast<std::size_t
>(M) ||
459 beta.size() !=
static_cast<std::size_t
>(M))
460 throw InputError(
"qsys_bmapphnn_retrial: the PH service is malformed");
461 if (R.empty())
throw InputError(
"qsys_bmapphnn_retrial: no admission threshold given");
463 detail::RetrialCtx<T> c;
470 c.K =
static_cast<int>(D.size()) - 1;
474 c.R.assign(
static_cast<std::size_t
>(V), R[0]);
476 if (R.size() !=
static_cast<std::size_t
>(V))
477 throw InputError(
"qsys_bmapphnn_retrial: R must be a scalar or one entry per BMAP "
483 c.S0.assign(
static_cast<std::size_t
>(M), zero);
484 for (
int i = 0; i < M; ++i) {
486 for (
int j = 0; j < M; ++j)
487 s += S(
static_cast<std::size_t
>(i),
static_cast<std::size_t
>(j));
488 c.S0[
static_cast<std::size_t
>(i)] = -s;
492 c.Tn.assign(
static_cast<std::size_t
>(N) + 1, 0);
493 c.comps.resize(
static_cast<std::size_t
>(N) + 1);
495 for (
int n = 0; n <= N; ++n) {
496 c.comps[
static_cast<std::size_t
>(n)] = detail::retrial_compositions(n, M);
497 c.Tn[
static_cast<std::size_t
>(n)] = c.comps[
static_cast<std::size_t
>(n)].size();
498 c.d += c.Tn[
static_cast<std::size_t
>(n)];
502 Matrix<T> Dsum(
static_cast<std::size_t
>(V),
static_cast<std::size_t
>(V), zero);
503 Matrix<T> DkSum(
static_cast<std::size_t
>(V),
static_cast<std::size_t
>(V), zero);
504 for (std::size_t k = 0; k < D.size(); ++k)
505 for (std::size_t i = 0; i < Dsum.
rows(); ++i)
506 for (std::size_t j = 0; j < Dsum.
cols(); ++j) {
507 Dsum(i, j) += D[k](i, j);
513 for (std::size_t j = 0; j < A.
cols(); ++j) A(A.
rows() - 1, j) = one;
514 std::vector<T> rhs(A.
rows(), zero);
515 rhs[A.
rows() - 1] = one;
516 const std::vector<T> theta =
solve(A, rhs);
518 for (std::size_t i = 0; i < theta.size(); ++i)
519 for (std::size_t j = 0; j < DkSum.
cols(); ++j) lambda += theta[i] * DkSum(i, j);
522 for (std::size_t i = 0; i < negS.
rows(); ++i)
523 for (std::size_t j = 0; j < negS.
cols(); ++j) negS(i, j) = -negS(i, j);
526 for (
int i = 0; i < M; ++i) b1 += beta[static_cast<std::size_t>(i)] * tau[
static_cast<std::size_t
>(i)];
527 if (!(b1 > zero))
throw InputError(
"qsys_bmapphnn_retrial: the mean service time must be positive");
530 std::size_t truncLevel =
opt.maxLevel;
531 if (truncLevel == 0) {
533 const double capped = rho < 0.99 ? rho : 0.99;
534 const double lv = std::ceil(50.0 / (1.0 - capped));
535 truncLevel = lv > 100.0 ?
static_cast<std::size_t
>(lv) :
static_cast<std::size_t
>(100);
540 std::vector<Matrix<T>> L(
static_cast<std::size_t
>(N) + 1), Am(
static_cast<std::size_t
>(N) + 1),
541 P(
static_cast<std::size_t
>(N) + 1), Delta(
static_cast<std::size_t
>(N) + 1);
542 for (
int n = 0; n <= N; ++n) {
543 L[
static_cast<std::size_t
>(n)] = detail::retrial_L(c, n);
544 Am[
static_cast<std::size_t
>(n)] = detail::retrial_A(c, n);
545 P[
static_cast<std::size_t
>(n)] = detail::retrial_P(c, n);
546 Delta[
static_cast<std::size_t
>(n)] = detail::retrial_Delta(c, n);
548 std::vector<Matrix<T>> B(
static_cast<std::size_t
>(V)), Bbar(
static_cast<std::size_t
>(V)),
549 Gam(
static_cast<std::size_t
>(V));
550 for (
int nu = 0; nu < V; ++nu) {
551 B[
static_cast<std::size_t
>(nu)] = detail::retrial_B(c, L, Am, P, Delta, nu);
552 Bbar[
static_cast<std::size_t
>(nu)] = detail::retrial_Bbar(c, P, nu);
553 Gam[
static_cast<std::size_t
>(nu)] = detail::retrial_Gamma(c, nu);
555 std::vector<std::vector<Matrix<T>>> Btilde(
556 static_cast<std::size_t
>(V), std::vector<
Matrix<T>>(
static_cast<std::size_t
>(V)));
557 for (
int nu = 0; nu < V; ++nu)
558 for (
int nup = 0; nup < V; ++nup)
559 if (nu != nup) Btilde[
static_cast<std::size_t
>(nu)][
static_cast<std::size_t
>(nup)] =
560 detail::retrial_Btilde(c, P, nu, nup);
562 const std::size_t Vd =
static_cast<std::size_t
>(V) * c.d;
563 const std::size_t total = (truncLevel + 1) * Vd;
566 for (std::size_t i = 0; i <= truncLevel; ++i) {
569 for (
int nu = 0; nu < V; ++nu) {
570 const std::size_t rs = i * Vd +
static_cast<std::size_t
>(nu) * c.d;
571 for (
int nup = 0; nup < V; ++nup) {
572 const std::size_t cs = i * Vd +
static_cast<std::size_t
>(nup) * c.d;
573 const T d0 = D[0](
static_cast<std::size_t
>(nu),
static_cast<std::size_t
>(nup));
575 for (std::size_t a = 0; a < c.d; ++a)
576 for (std::size_t b = 0; b < c.d; ++b) {
577 T v = B[
static_cast<std::size_t
>(nu)](a, b) +
578 iT * alpha * Gam[
static_cast<std::size_t
>(nu)](a, b);
579 if (a == b) v += d0 - iT * T(gamma + alpha);
580 Q(rs + a, cs + b) = v;
584 Btilde[
static_cast<std::size_t
>(nu)][
static_cast<std::size_t
>(nup)];
585 for (std::size_t a = 0; a < c.d; ++a)
586 for (std::size_t b = 0; b < c.d; ++b)
587 Q(rs + a, cs + b) = bt(a, b) + (a == b ? d0 : zero);
593 for (
int nu = 0; nu < V; ++nu) {
594 const std::size_t rs = i * Vd +
static_cast<std::size_t
>(nu) * c.d;
595 const std::size_t cs = (i - 1) * Vd +
static_cast<std::size_t
>(nu) * c.d;
596 for (std::size_t a = 0; a < c.d; ++a)
597 for (std::size_t b = 0; b < c.d; ++b) {
598 T v = iT * alpha * Bbar[
static_cast<std::size_t
>(nu)](a, b);
599 if (a == b) v += iT * gamma;
600 Q(rs + a, cs + b) = v;
605 for (
int k = 1; k <= c.K; ++k) {
606 const std::size_t j = i +
static_cast<std::size_t
>(k);
607 if (j > truncLevel)
break;
608 for (
int nu = 0; nu < V; ++nu) {
609 const std::size_t rs = i * Vd +
static_cast<std::size_t
>(nu) * c.d;
610 for (
int nup = 0; nup < V; ++nup) {
611 const std::size_t cs = j * Vd +
static_cast<std::size_t
>(nup) * c.d;
612 const std::size_t ncol = detail::retrial_offset(c, N);
613 for (
int n = 0; n <= N; ++n) {
614 const Matrix<T> Cnk = detail::retrial_C(c, P, n, k, nu, nup);
615 if (Cnk.
rows() == 0)
continue;
616 if (Cnk.
cols() != c.Tn[
static_cast<std::size_t
>(N)])
continue;
617 const std::size_t nrow = detail::retrial_offset(c, n);
618 for (std::size_t a = 0; a < Cnk.
rows(); ++a)
619 for (std::size_t b = 0; b < Cnk.
cols(); ++b)
620 Q(rs + nrow + a, cs + ncol + b) += Cnk(a, b);
628 for (std::size_t i = 0; i < total; ++i) {
630 for (std::size_t j = 0; j < total; ++j) s += Q(i, j);
631 Q(i, i) = Q(i, i) - s;
635 for (std::size_t i = 0; i < total; ++i) Q(i, total - 1) = one;
637 std::vector<T> rhs2(total, zero);
638 rhs2[total - 1] = one;
639 std::vector<T> pi =
solve(QT, rhs2);
644 for (std::size_t i = 0; i < total; ++i) {
651 if (!(mass > zero))
throw NumericError(
"qsys_bmapphnn_retrial: the solution has no mass");
652 for (std::size_t i = 0; i < total; ++i) pi[i] = pi[i] / mass;
655 for (std::size_t i = 0; i <= truncLevel; ++i)
656 for (std::size_t j = 0; j < Vd; ++j) r.
pi(i, j) = pi[i * Vd + j];
659 for (std::size_t i = 1; i <= truncLevel; ++i) {
661 for (std::size_t j = 0; j < Vd; ++j) lv += r.
pi(i, j);
666 for (std::size_t i = 0; i <= truncLevel; ++i)
667 for (
int nu = 0; nu < V; ++nu) {
668 const std::size_t base =
static_cast<std::size_t
>(nu) * c.d;
669 for (
int n = 0; n <= N; ++n) {
670 const std::size_t off = base + detail::retrial_offset(c, n);
671 for (std::size_t t = 0; t < c.Tn[
static_cast<std::size_t
>(n)]; ++t)
679 for (
int nu = 0; nu < V; ++nu) r.
P_empty_system += r.
pi(0,
static_cast<std::size_t
>(nu) * c.d);
681 for (std::size_t j = 0; j < Vd; ++j) r.
topLevelMass += r.
pi(truncLevel, j);
693 const std::vector<T>& beta,
const Matrix<T>& S,
694 int N,
const T& alpha,
const T& gamma,
const T& p,
NumericError(const std::string &what)
The exception types the port throws.
Dense linear algebra over the templated number type: products, identity, inverse, and powers.
LU factorization with partial pivoting, templated on the number type.
Dense matrix and non-owning view.
BmapPhNnRetrialResult< T > qsys_bmapphnn_retrial(const std::vector< Matrix< T > > &D, const std::vector< T > &beta, const Matrix< T > &S, int N, const T &alpha, const T &gamma, const T &p, const std::vector< long > &R, const BmapPhNnRetrialOptions &opt)
The BMAP/PH/N/N bufferless retrial queue.
Matrix< T > inverse(const Matrix< T > &A)
Inverse by LU with one factorization and n back substitutions.
Matrix< T > matmul(const Matrix< T > &A, const Matrix< T > &B)
Matrix product A B.
std::vector< T > mulvec(const Matrix< T > &A, const std::vector< T > &v)
Matrix times column vector, A v.
std::vector< T > solve(const Matrix< T > &A, const std::vector< T > &b)
Convenience: solve Ax = b, leaving A and b untouched.
std::vector< T > ones(std::size_t n)
Column vector of ones, the ubiquitous e in MAP algebra.
Matrix< T > eye(std::size_t n)
Identity of order n.
Number-type abstraction for the templated API port.
Options of qsys_bmapphnn_retrial.
std::size_t maxLevel
Orbit truncation level; 0 selects the reference's automatic choice.
Result of qsys_bmapphnn_retrial.
T P_empty_orbit
probability that the orbit is empty
T L_orbit
mean number of customers in orbit
std::size_t truncLevel
truncation level used
T utilization
N_server / N.
T throughput
N_server / b1.
T P_idle
probability that every server is idle
Matrix< T > pi
stationary law, (truncLevel + 1) x (V d)
T topLevelMass
mass at the highest retained level; see defect 2
T P_empty_system
probability that the system is empty
T L_system
L_orbit + N_server.
T N_server
mean number of busy servers
bool clipped
a negative probability had to be clipped to zero