5#ifndef LINE_API_QSYS_QSYS_MG1K_LOSS_H
6#define LINE_API_QSYS_QSYS_MG1K_LOSS_H
73void dtmc_makestochastic_inplace(
Matrix<T>& P) {
75 for (std::size_t i = 0; i < P.rows(); ++i) {
77 for (std::size_t j = 0; j < P.cols(); ++j) s += P(i, j);
79 for (std::size_t j = 0; j < P.cols(); ++j) P(i, j) /= s;
81 for (std::size_t j = 0; j < P.cols(); ++j)
82 if (j != i) off += P(i, j);
84 if (d < zero) d = zero;
88 for (std::size_t j = 0; j < P.cols(); ++j) P(i, j) = zero;
104template <
class T,
class Density>
107 "qsys_mg1k_loss requires transcendental arithmetic");
108 if (K < 2)
throw InputError(
"qsys_mg1k_loss: K must be at least 2");
114 const T meanS = detail::num_integral<T>([&](
const T& t) {
return t * density(t); }, zero, tmax,
116 if (meanS <= zero)
throw NumericError(
ErrorKind{
"Degenerate"},
"qsys_mg1k_loss: non-positive mean service time");
117 const T mu = one / meanS;
120 std::vector<T> a(K - 1, zero);
122 for (
unsigned j = 0; j <= 1000u; ++j) {
123 const T aj = detail::num_integral<T>(
125 return detail::num_exp(T(-lambda * t)) *
128 zero, tmax, reltol, abstol) /
134 if (aj < stop)
break;
138 const std::size_t n = K - 1;
140 const std::size_t last = n - 1;
141 P(0, 0) = a[0] + (a.size() > 1 ? a[1] : zero);
142 for (std::size_t i = 1; i + 2 <= n; ++i) P(0, i) = i + 1 < a.size() ? a[i + 1] : zero;
144 for (std::size_t i = 0; i + 1 < n; ++i) P(1, i) = i < a.size() ? a[i] : zero;
146 for (std::size_t r = 2; r < n; ++r)
147 for (std::size_t col = r - 1; col + 1 < n; ++col) {
148 const std::size_t j = col - r + 1;
149 P(r, col) = j < a.size() ? a[j] : zero;
152 for (std::size_t r = 0; r < n; ++r) {
154 for (std::size_t col = 0; col + 1 < n; ++col) s += P(r, col);
155 P(r, last) = one - s;
157 detail::dtmc_makestochastic_inplace(P);
163 if (carried == zero)
throw NumericError(
ErrorKind{
"Degenerate"},
"qsys_mg1k_loss: degenerate renewal cycle");
NumericError(const std::string &what)
Equilibrium distribution of a discrete-time Markov chain, and stochastic complementation.
The exception types the port throws.
Dense matrix and non-owning view.
std::vector< T > dtmc_solve(const Matrix< T > &P)
Stationary distribution of a stochastic matrix P.
Mg1kLossResult< T > qsys_mg1k_loss(const T &lambda, Density &&density, unsigned K)
Exact M/G/1/K loss probability, via the chain embedded at service-start epochs.
Conservation laws of a layered queueing network, enumerated from its structure.
T num_factorial(unsigned n)
Factorial as a value of T.
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.
Adaptive quadrature for the qsys functions whose MATLAB originals call integral(),...
Shared return type and arithmetic helpers for the templated qsys port.
The <kind> part of a LINE:<category>:<kind> identifier (see _kb/17-error-vocabulary....
T utilization
rho = lambda/mu with mu the reciprocal mean service time