5#ifndef LINE_API_QSYS_QSYS_GG1_H
6#define LINE_API_QSYS_QSYS_GG1_H
60T qsys_gm1_sigma(
const T& lambda,
const T& mu,
const T& ca2) {
61 static_assert(num_traits<T>::has_transcendental,
62 "qsys_gm1_sigma requires transcendental arithmetic");
63 const T one = num_traits<T>::from_int(1);
64 const T two = num_traits<T>::from_int(2);
65 const T tiny = T(num_traits<T>::from_double(1e-6));
66 const T step_tol = T(num_traits<T>::from_double(1e-13));
69 T p = num_traits<T>::from_int(0), nu = num_traits<T>::from_int(0);
70 T p1 = num_traits<T>::from_int(0), l1 = num_traits<T>::from_int(0),
71 l2 = num_traits<T>::from_int(0);
74 p1 = (one + num_sqrt(T((ca2 - one) / (ca2 + one)))) / two;
75 l1 = two * p1 * lambda;
76 l2 = two * (one - p1) * lambda;
77 }
else if (ca2 >= tiny) {
79 const double inv = 1.0 / num_traits<T>::to_double(ca2);
80 jj =
static_cast<unsigned>(std::ceil(inv));
82 const T jt = num_traits<T>::from_int(
static_cast<long>(jj));
83 p = (jt * ca2 - num_sqrt(T(jt * (one + ca2) - jt * jt * ca2))) / (one + ca2);
84 nu = (jt - p) * lambda;
87 T sigma = lambda / mu;
88 for (
unsigned it = 0; it < 100000u; ++it) {
89 const T s = mu * (one - sigma);
92 signew = num_exp(T(-s / lambda));
93 }
else if (ca2 < one) {
94 signew = p *
num_pow_int(T(nu / (s + nu)), jj - 1) +
97 signew = p1 * l1 / (s + l1) + (one - p1) * l2 / (s + l2);
99 const bool done =
num_abs(T(signew - sigma)) < step_tol;
120 "qsys_gg1 requires transcendental arithmetic");
123 const bool ca_markov =
num_abs(T(ca2 - one)) < tol;
124 const bool cs_markov =
num_abs(T(cs2 - one)) < tol;
126 if (ca_markov && cs_markov)
return qsys_mm1(lambda, mu);
127 if (ca_markov)
return qsys_mg1(lambda, mu, T(detail::num_sqrt(cs2)));
129 const T sigma = detail::qsys_gm1_sigma(lambda, mu, ca2);
131 return {W, detail::rhohat_from_W(W, lambda)};
134 T(detail::num_sqrt(cs2)));
QsysResult< T > qsys_mm1(const T &lambda, const T &mu)
Exact mean response time of the M/M/1 queue.
T qsys_gm1(const T &sigma, const T &mu)
Exact mean response time of the G/M/1 queue.
QsysResult< T > qsys_mg1(const T &lambda, const T &mu, const T &cs)
Exact mean response time of the M/G/1 queue (Pollaczek-Khinchine).
QsysResult< T > qsys_gig1_approx_allencunneen(const T &lambda, const T &mu, const T &ca, const T &cs)
Allen-Cunneen approximation of the mean response time of a G/I/G/1 queue.
QsysResult< T > qsys_gg1(const T &lambda, const T &mu, const T &ca2, const T &cs2)
G/G/1 dispatcher: exact where a two-moment description determines the answer, Allen-Cunneen otherwise...
T num_pow_int(const T &base, unsigned e)
Integer power, valid in any field (no transcendental requirement).
Number-type abstraction for the templated API port.
Allen-Cunneen approximation of the mean response time of a G/I/G/1 queue.
Exact mean response time of the G/M/1 queue.
Exact mean response time of the M/G/1 queue (Pollaczek-Khinchine).
Exact mean response time of the M/M/1 queue.
Shared return type and arithmetic helpers for the templated qsys port.
Return value of the qsys family, mirroring MATLAB's [W,rhohat] and the JAR's Ret.qsys.