LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
qsys_mg1k_loss_mgs.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_MG1K_LOSS_MGS_H
6#define LINE_API_QSYS_QSYS_MG1K_LOSS_MGS_H
7
8/**
9 * @file
10 * @ingroup api_qsys
11 * MacGregor Smith's closed-form approximation of the M/G/1/K loss probability.
12 *
13 * Templated port of matlab/src/api/qsys/qsys_mg1k_loss_mgs.m, cross-checked
14 * against jar/src/main/java/jline/api/qsys/Qsys_mg1k_loss_mgs.java
15 * (identical).
16 *
17 * rho = lambda/mu, s = sqrt(scv), r = sqrt(rho), b = 2 + r s^2 - r
18 * Ploss = rho^((r s^2 - r + 2K)/b) (rho - 1) / ( rho^(2(1 + r s^2 - r + K)/b) - 1 )
19 *
20 * The exponents interpolate the exact M/M/1/K expression in the service
21 * variability: at scv = 1 they are K and K+1 and the formula reduces to
22 * qsys_mm1k_loss.
23 *
24 * ARITHMETIC. Both the square root of rho and the real-valued exponents are
25 * transcendental, so the function is gated. There is no exact instantiation
26 * even in principle: for scv != 1 the exponents are irrational.
27 *
28 * Reference: J. MacGregor Smith, Optimal design and performance modelling of
29 * M/G/1/K queueing systems.
30 */
31
33#include "line/num/number.h"
34#include "line/util/error.h"
35
36namespace line {
37namespace qsys {
38
39template <class T>
42 T utilization; ///< rho = lambda/mu
43};
44
45/**
46 * @brief MacGregor Smith's closed-form approximation of the M/G/1/K loss
47 * probability.
48 *
49 * @param lambda arrival rate
50 * @param mu service rate
51 * @param mu_scv squared coefficient of variation of the service time
52 * @param K system capacity, jobs in service included
53 */
54template <class T>
55Mg1kLossMgsResult<T> qsys_mg1k_loss_mgs(const T& lambda, const T& mu, const T& mu_scv,
56 unsigned K) {
58 "qsys_mg1k_loss_mgs requires transcendental arithmetic");
59 const T one = num_traits<T>::from_int(1);
60 const T two = num_traits<T>::from_int(2);
61 const T rho = lambda / mu;
62 const T s = detail::num_sqrt(mu_scv);
63 const T sqrt_rho = detail::num_sqrt(rho);
64 const T Kt = num_traits<T>::from_int(static_cast<long>(K));
65 const T b = two + sqrt_rho * s * s - sqrt_rho;
66 if (b == num_traits<T>::from_int(0))
67 throw NumericError("qsys_mg1k_loss_mgs: degenerate exponent denominator");
68 const T num = detail::num_pow(rho, T((sqrt_rho * s * s - sqrt_rho + two * Kt) / b)) * (rho - one);
69 const T den = detail::num_pow(rho, T(two * (one + sqrt_rho * s * s - sqrt_rho + Kt) / b)) - one;
70 if (den == num_traits<T>::from_int(0))
71 throw NumericError("qsys_mg1k_loss_mgs: rho == 1, the closed form is singular");
73 r.utilization = rho;
74 r.lossProbability = num / den;
75 return r;
76}
77
78} // namespace qsys
79} // namespace line
80
81#endif // LINE_API_QSYS_QSYS_MG1K_LOSS_MGS_H
NumericError(const std::string &what)
Definition error.h:45
The exception types the port throws.
Mg1kLossMgsResult< T > qsys_mg1k_loss_mgs(const T &lambda, const T &mu, const T &mu_scv, unsigned K)
MacGregor Smith's closed-form approximation of the M/G/1/K loss probability.
Number-type abstraction for the templated API port.
Shared return type and arithmetic helpers for the templated qsys port.