5#ifndef LINE_API_MAM_QBD_SETUPDELAYOFF_H
6#define LINE_API_MAM_QBD_SETUPDELAYOFF_H
84 "coxian_phase_subgen requires transcendental arithmetic");
88 if (rate <= zero)
throw InputError(
"coxian_phase_subgen: the rate must be positive");
89 if (scv <= zero)
throw InputError(
"coxian_phase_subgen: the SCV must be positive");
99 const T mean = one / rate;
100 std::vector<T> mu, phi;
101 if (scv >= one - tol && scv <= one + tol) {
102 mu.push_back(one / mean);
104 }
else if (scv > T(one / two) + tol && scv < one - tol) {
106 const T s = T(sqrt(T(one + two * (scv - one))));
107 mu.push_back(two / mean / (one + s));
108 mu.push_back(two / mean / (one - s));
111 }
else if (scv <= T(one / two) + tol) {
113 const long n =
static_cast<long>(std::ceil(inv));
115 for (
long k = 0; k < n; ++k) {
116 mu.push_back(lambda);
119 phi[
static_cast<std::size_t
>(n) - 1] = one;
121 const T mu1 = two / mean;
122 const T mu2 = mu1 / (two * scv);
125 phi.push_back(T(one - mu2 / mu1));
130 const std::size_t n = mu.size();
132 for (std::size_t i = 0; i < n; ++i) {
134 if (i + 1 < n) D0(i, i + 1) = mu[i] * (one - phi[i]);
152 const T& betarate,
const T& betascv) {
154 "qbd_setupdelayoff requires transcendental arithmetic");
155 using namespace qbd_detail;
159 const std::size_t na = Ta.
rows();
160 std::vector<T> ta(na, zero);
161 for (std::size_t i = 0; i < na; ++i) {
163 for (std::size_t j = 0; j < na; ++j) s += Ta(i, j);
168 const std::size_t nb = Tb.
rows();
169 std::vector<T> tb(nb, zero);
170 for (std::size_t i = 0; i < nb; ++i) {
172 for (std::size_t j = 0; j < nb; ++j) s += Tb(i, j);
176 const std::size_t n = na + nb;
177 Matrix<T> F(n, n, zero), B(n, n, zero), L(n, n, zero), L0(n, n, zero);
179 for (std::size_t i = 0; i < na; ++i) F(i, i) = lambda;
180 for (std::size_t i = 0; i < nb; ++i) F(na + i, na) = lambda;
184 for (std::size_t i = 0; i < na; ++i) {
186 for (std::size_t j = 0; j < na; ++j) L(i, j) = Ta(i, j);
190 L(na, na) = -mu - lambda;
191 for (std::size_t i = 1; i < nb; ++i) L(na + i, na + i) = -lambda;
193 for (std::size_t i = 0; i < na; ++i) L0(i, i) = -lambda;
194 for (std::size_t i = 0; i < nb; ++i) {
195 for (std::size_t j = 0; j < nb; ++j) L0(na + i, na + j) = Tb(i, j);
196 L0(na + i, na + i) -= lambda;
197 L0(na + i, 0) = tb[i];
206 for (std::size_t k = 1; k < pn.
rows(); ++k) {
208 for (std::size_t j = 0; j < n; ++j) s += pn(k, j);
262 const T& alpharate,
const T& alphascv,
263 const T& betarate,
const T& betascv) {
265 "qbd_setupdelayoff_closed requires transcendental arithmetic");
277 const std::size_t na = Ta.
rows();
278 std::vector<T> ta(na, zero);
279 for (std::size_t i = 0; i < na; ++i) {
281 for (std::size_t j = 0; j < na; ++j) s += Ta(i, j);
285 const std::size_t nb = Tb.
rows();
286 std::vector<T> tb(nb, zero);
287 for (std::size_t i = 0; i < nb; ++i) {
289 for (std::size_t j = 0; j < nb; ++j) s += Tb(i, j);
293 const std::size_t off = 0;
294 const std::size_t base = 1 + nb;
295 const std::size_t P = na + 1;
296 const std::size_t m = base +
static_cast<std::size_t
>(pop) * P;
300 std::vector<T> lam(
static_cast<std::size_t
>(pop) + 1, zero);
301 for (
long n = 0; n < pop; ++n)
305 for (std::size_t j = 0; j < nb; ++j) {
306 const std::size_t rj = 1 + j;
307 for (std::size_t j2 = 0; j2 < nb; ++j2)
308 if (j2 != j) Q(rj, 1 + j2) += Tb(j, j2);
313 for (
long n = 1; n <= pop; ++n) {
314 const std::size_t lvl = base +
static_cast<std::size_t
>(n - 1) * P;
315 const std::size_t up = base +
static_cast<std::size_t
>(n) * P;
316 const T&
ln = lam[
static_cast<std::size_t
>(n)];
317 const bool rising = n < pop && num_traits<T>::to_double(
ln) > 0;
318 for (std::size_t i = 0; i < na; ++i) {
319 for (std::size_t i2 = 0; i2 < na; ++i2)
320 if (i2 != i) Q(lvl + i, lvl + i2) += Ta(i, i2);
321 Q(lvl + i, lvl + na) += ta[i];
324 if (rising) Q(lvl + i, up + i) +=
ln;
326 if (rising) Q(lvl + na, up + na) +=
ln;
328 const std::size_t down = n - 1 >= 1 ? base +
static_cast<std::size_t
>(n - 2) * P + na : 1;
329 Q(lvl + na, down) += mu;
331 for (std::size_t i = 0; i < m; ++i) {
333 for (std::size_t j = 0; j < m; ++j)
334 if (j != i) s += Q(i, j);
340 for (std::size_t i = 0; i < pi.size(); ++i)
342 if (total <= 0)
return out;
344 T QN = zero, pbusy = zero;
345 for (
long n = 1; n <= pop; ++n) {
346 const std::size_t lvl = base +
static_cast<std::size_t
>(n - 1) * P;
347 T level = pi[lvl + na];
348 for (std::size_t i = 0; i < na; ++i) level += pi[lvl + i];
350 pbusy += pi[lvl + na];
353 out.
QN = T(QN / norm);
354 out.
XN = T(mu * pbusy / norm);
Steady-state distribution of a continuous-time Markov chain.
The exception types the port throws.
Enumerations and the minimal distribution descriptor shared by the model layer of the C++ port.
Dense linear algebra over the templated number type: products, identity, inverse, and powers.
Dense matrix and non-owning view.
Matrix< T > coxian_phase_subgen(const T &rate, const T &scv)
Sub-generator of the canonical Coxian form with the given RATE and SCV, entered at phase 1 (the coxia...
T qbd_setupdelayoff(const T &lambda, const T &mu, const T &alpharate, const T &alphascv, const T &betarate, const T &betascv)
Mean queue length of the M/M/1 queue with setup delay and delay-off (qbd_setupdelayoff....
QbdFundMat< T > qbd_fundmat(const Matrix< T > &B, const Matrix< T > &L, const Matrix< T > &F, unsigned iter_max, const T &tol)
G and R by cyclic reduction (qbd_fundmat.m, the Bini-Meini logarithmic reduction on the raw level blo...
SetupDelayoffClosed< T > qbd_setupdelayoff_closed(const T &N, const T &Z, const T &mu, const T &alpharate, const T &alphascv, const T &betarate, const T &betascv)
Mean queue length and throughput of a FINITE-POPULATION queue with setup delay and delay-off,...
Matrix< T > qbd_pi(const Matrix< T > &B, const Matrix< T > &Lbar, const Matrix< T > &R, std::size_t max_levels, const T &mass_tol)
Stationary distribution of a QBD given R (QBD_pi.m, continuous-time branch, default boundary).
std::vector< T > ctmc_solve(const Matrix< T > &Qin)
Steady-state distribution of a continuous-time Markov chain.
Number-type abstraction for the templated API port.
Quasi-birth-death processes: the rate matrix R, the fundamental matrix G, the caudal characteristic,...
static constexpr double FineTol
G and R together, as returned by qbd_fundmat.
Mean queue length and throughput of the CLOSED setup/delay-off queue.
T QN
mean number of jobs at the station
T XN
throughput of the station