LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
me_gegec_mql.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_ME_ME_GEGEC_MQL_H
6#define LINE_API_ME_ME_GEGEC_MQL_H
7
8/**
9 * @file
10 * @ingroup api_me
11 * Mean queue length of a stable infinite-capacity GE/GE/c/FCFS queue.
12 *
13 * Templated port of `matlab/src/api/me/me_gegec_mql.m`, the exact Maximum
14 * Entropy solution of Kouvatsos (1994), equation (3.9).
15 *
16 * WHY IT EXISTS SEPARATELY FROM `me_oqn`. `me_oqn.h` carries a numerically
17 * identical local copy of this formula; the reference does the same and says
18 * why -- `me_oqn.m` is compiled to a MEX file by MEXIFY, which cannot call out.
19 * This file is the one `me_oqn_blk` uses for the stations whose buffer is
20 * INFINITE, so a blocking network with a mix of finite and unbounded queues
21 * solves both kinds with the same coefficients.
22 *
23 * THE GEOMETRIC TAIL IS WHY `x` MATTERS. The state probabilities are a product
24 * of `g(1..c)` up to the server count and then a geometric ratio `x`
25 * thereafter, so `Z` and the two partial sums below are the closed forms of
26 * that split: `S1` covers the states with an idle server, `S2` the saturated
27 * tail, whose mean needs both `1/(1-x)` and `x/(1-x)^2`.
28 *
29 * ARITHMETIC. The tail sums assume `|x| < 1`, i.e. a STABLE queue; the caller
30 * is responsible for that, exactly as in the reference. Transcendental only.
31 */
32
33#include <cstddef>
34#include <vector>
35
36#include "line/num/number.h"
37#include "line/util/error.h"
38
39namespace line {
40namespace me {
41
42/**
43 * Port of `me_gegec_mql`.
44 *
45 * @param lambda arrival rate
46 * @param Ca squared coefficient of variation of the interarrival times
47 * @param mu service rate of ONE server
48 * @param Cs squared coefficient of variation of the service times
49 * @param c number of servers, finite and at least 1
50 * @return the mean number of jobs in the queue
51 */
52template <class T>
53T me_gegec_mql(const T& lambda, const T& Ca, const T& mu, const T& Cs, long c) {
55 "me_gegec_mql requires transcendental arithmetic");
56 if (c < 1) throw InputError("me_gegec_mql: the server count must be at least 1");
57 const T one = num_traits<T>::from_int(1);
58 const T two = num_traits<T>::from_int(2);
59
60 const T alpha2 = T(two / (Cs + one));
61 const T alpha1 = T(one - alpha2);
62 const T beta2 = T(two / (Ca + one));
63 const T beta1 = T(one - beta2);
64 const T lambda2 = T(beta2 * lambda);
65 const T mu2 = T(alpha2 * mu);
66
67 const std::size_t C = static_cast<std::size_t>(c);
68 std::vector<T> g(C, one);
69 for (std::size_t j = 1; j + 1 <= C - 1 + 1 && j <= C - 1; ++j) {
70 const T jj = num_traits<T>::from_int(static_cast<long>(j));
71 const T jm1 = num_traits<T>::from_int(static_cast<long>(j) - 1);
72 g[j - 1] = T((lambda2 + jm1 * mu2 * beta1) * alpha2 /
73 (jj * mu2 * (one - alpha1 * beta1)));
74 }
75 const T cc = num_traits<T>::from_int(c);
76 const T cm1 = num_traits<T>::from_int(c - 1);
77 g[C - 1] = T((lambda2 + cm1 * mu2 * beta1) * alpha2 / (lambda2 * alpha1 + cc * mu2));
78 const T x = T((lambda2 + cc * mu2 * beta1) / (lambda2 * alpha1 + cc * mu2));
79
80 // Gn = cumprod(g)
81 std::vector<T> Gn(C, one);
82 T acc = one;
83 for (std::size_t i = 0; i < C; ++i) {
84 acc = T(acc * g[i]);
85 Gn[i] = acc;
86 }
87
88 const T omx = T(one - x);
89 T Z = one;
90 for (std::size_t i = 0; i + 1 < C; ++i) Z += Gn[i];
91 Z += T(Gn[C - 1] / omx);
92
94 for (std::size_t n = 1; n + 1 <= C; ++n)
95 S1 += num_traits<T>::from_int(static_cast<long>(n)) * Gn[n - 1];
96 const T S2 = T(Gn[C - 1] * (cc / omx + x / (omx * omx)));
97 return T((S1 + S2) / Z);
98}
99
100} // namespace me
101} // namespace line
102
103#endif // LINE_API_ME_ME_GEGEC_MQL_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
T me_gegec_mql(const T &lambda, const T &Ca, const T &mu, const T &Cs, long c)
Port of me_gegec_mql.
Number-type abstraction for the templated API port.