LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
qsys_mmc_prio.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_API_QSYS_QSYS_MMC_PRIO_H
6#define LINE_API_QSYS_QSYS_MMC_PRIO_H
7
8/**
9 * @file
10 * @ingroup api_qsys
11 * M/M/c with non-preemptive (head-of-line) priorities and a common exponential
12 * service rate (Cobham, 1954).
13 *
14 * Port of matlab/src/api/qsys/qsys_mmc_prio.m. With A = sum(lambda)/mu, the
15 * Erlang C probability of waiting C(c, A) and sigma_i = sum_{j<=i} lambda_j/(c mu),
16 *
17 * Wq_i = (C / (c mu)) / ((1 - sigma_{i-1})(1 - sigma_i)), W_i = Wq_i + 1/mu.
18 *
19 * ARITHMETIC: field. Erlang B is a rational recursion, so the computation is
20 * exact for T = Rational.
21 */
22
23#include <cstddef>
24#include <string>
25#include <vector>
26
28#include "line/num/number.h"
29#include "line/util/error.h"
30
31namespace line {
32namespace qsys {
33
34/** MATLAB's [W, rho, res] outputs. */
35template <class T>
37 std::vector<T> W; ///< per-class mean response time, class 1 first
38 T rho; ///< Q/(1+Q)
39 QsysResT<T> res; ///< meanSojournTime, meanWaitingTime, meanQueueLength, probWait, utilization, analyzer
40};
41
42/**
43 * @brief M/M/c with head-of-line priorities.
44 *
45 * @param lambda per-class arrival rates, highest priority first
46 * @param mu common service rate
47 * @param c number of servers
48 */
49template <class T>
50MmcPrioResult<T> qsys_mmc_prio(const std::vector<T>& lambda, const T& mu, unsigned c) {
51 const T zero = num_traits<T>::from_int(0), one = num_traits<T>::from_int(1);
52 for (const T& l : lambda)
53 if (l <= zero)
54 throw InputError(ErrorKind("Argument"), "qsys_mmc_prio: lambda must be positive and mu a positive scalar");
55 if (mu <= zero)
56 throw InputError(ErrorKind("Argument"), "qsys_mmc_prio: lambda must be positive and mu a positive scalar");
57 if (c < 1) throw InputError(ErrorKind("Argument"), "qsys_mmc_prio: c must be a positive integer");
58 const std::size_t R = lambda.size();
59 const T cT = num_traits<T>::from_int(static_cast<long>(c));
60 T lsum = zero;
61 for (const T& l : lambda) lsum += l;
62 const T A = T(lsum / mu);
63 if (A >= cT) resdetail::throw_unstable("qsys_mmc_prio", "lambda/(c mu)", num_traits<T>::to_double(T(A / cT)));
64 T B = one;
65 for (unsigned k = 1; k <= c; ++k) B = T(A * B / (num_traits<T>::from_int(static_cast<long>(k)) + A * B));
66 const T C = T(cT * B / (cT - A * (one - B)));
67 std::vector<T> sig(R + 1, zero);
68 for (std::size_t i = 0; i < R; ++i) sig[i + 1] = T(sig[i] + lambda[i]);
69 for (T& s : sig) s = T(s / (cT * mu));
71 std::vector<T> Wq(R), Qi(R);
72 r.W.assign(R, zero);
73 T Q = zero;
74 for (std::size_t i = 0; i < R; ++i) {
75 Wq[i] = T((C / (cT * mu)) / ((one - sig[i]) * (one - sig[i + 1])));
76 r.W[i] = T(Wq[i] + one / mu);
77 Qi[i] = T(lambda[i] * r.W[i]);
78 Q += Qi[i];
79 }
80 r.rho = T(Q / (one + Q));
81 r.res.set("meanSojournTime", r.W);
82 r.res.set("meanWaitingTime", Wq);
83 r.res.set("meanQueueLength", Qi);
84 r.res.set("probWait", C);
85 r.res.set("utilization", T(A / cT));
86 r.res.analyzer = "exact:M/M/" + std::to_string(c) + "-prio";
87 return r;
88}
89
90} // namespace qsys
91} // namespace line
92
93#endif // LINE_API_QSYS_QSYS_MMC_PRIO_H
InputError(const std::string &what)
Definition error.h:105
The exception types the port throws.
void throw_unstable(const char *fn, const char *what, double v)
A LINE:input:Unstable refusal "fn: unstable system: <what> = %g >= 1".
Definition qsys_res.h:213
MmcPrioResult< T > qsys_mmc_prio(const std::vector< T > &lambda, const T &mu, unsigned c)
M/M/c with head-of-line priorities.
Conservation laws of a layered queueing network, enumerated from its structure.
Definition aoi_dist2ph.h:52
Number-type abstraction for the templated API port.
The res struct the exact queueing-system functions return, and the numeric helpers those functions sh...
ErrorKind(std::string n)
Definition error.h:39
MATLAB's [W, rho, res] outputs.
QsysResT< T > res
meanSojournTime, meanWaitingTime, meanQueueLength, probWait, utilization, analyzer
std::vector< T > W
per-class mean response time, class 1 first
MATLAB's res struct: named measures in insertion order, plus res.analyzer.
Definition qsys_res.h:57
std::string analyzer
Definition qsys_res.h:59
void set(const std::string &name, const T &v)
Sets (or overwrites) a scalar field.
Definition qsys_res.h:62