LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
qsys_mxm1.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_MXM1_H
6#define LINE_API_QSYS_QSYS_MXM1_H
7
8/**
9 * @file
10 * @ingroup api_qsys
11 * M^X/M/1: the batch-arrival queue with exponential service.
12 *
13 * Templated port of matlab/src/api/qsys/qsys_mxm1.m, cross-checked against
14 * jar/src/main/java/jline/api/qsys/Qsys_mxm1.java.
15 *
16 * lambda = lambda_batch E[X], rho = lambda/mu
17 * Wq = rho/(mu(1-rho)) + (E[X^2]-E[X]) / (2 mu E[X] (1-rho))
18 * W = Wq + 1/mu, Q = lambda W
19 *
20 * The first term is the M/M/1 delay of the batch stream and the second is the
21 * delay a job suffers behind its own batch mates. Only the first two moments
22 * of the batch size enter, and only rationally, so this is exact for
23 * T = Rational.
24 *
25 * MATLAB dispatches on the argument shapes to accept the batch law as
26 * (E[X], E[X^2]), as (E[X], Var[X]) with a 'variance' flag, or as a support
27 * with a pmf. C++ overloading cannot see MATLAB's shape test, so the three
28 * forms are separate named entry points: qsys_mxm1, qsys_mxm1_variance and
29 * qsys_mxm1_pmf. All three funnel into the same closed form.
30 */
31
32#include <cstddef>
33#include <vector>
34
36#include "line/num/number.h"
37#include "line/util/error.h"
38
39namespace line {
40namespace qsys {
41
42template <class T>
43struct MxM1Result {
44 T W; ///< mean time in system
45 T Wq; ///< mean waiting time in queue
46 T U; ///< server utilization rho
47 T Q; ///< mean number in system, lambda W
48};
49
50/**
51 * @brief M^X/M/1: the batch-arrival queue with exponential service.
52 *
53 * @param lambda_batch batch arrival rate
54 * @param mu service rate
55 * @param E_X mean batch size
56 * @param E_X2 second raw moment of the batch size
57 */
58template <class T>
59MxM1Result<T> qsys_mxm1(const T& lambda_batch, const T& mu, const T& E_X, const T& E_X2) {
60 const T one = num_traits<T>::from_int(1);
61 const T two = num_traits<T>::from_int(2);
62 const T lambda = lambda_batch * E_X;
63 const T rho = lambda / mu;
64 if (rho >= one) throw InputError("qsys_mxm1: system is unstable, rho >= 1");
66 r.Wq = rho / (mu * (one - rho)) + (E_X2 - E_X) / (two * mu * E_X * (one - rho));
67 r.W = r.Wq + one / mu;
68 r.U = rho;
69 r.Q = lambda * r.W;
70 return r;
71}
72
73/** Variance form: MATLAB's qsys_mxm1(..., Var_X, 'variance'). */
74template <class T>
75MxM1Result<T> qsys_mxm1_variance(const T& lambda_batch, const T& mu, const T& E_X,
76 const T& Var_X) {
77 return qsys_mxm1(lambda_batch, mu, E_X, T(Var_X + E_X * E_X));
78}
79
80/**
81 * Support-and-pmf form: MATLAB's qsys_mxm1(..., batch_sizes, pmf). The pmf is
82 * renormalized, as in MATLAB, so an unnormalized weight vector is accepted.
83 */
84template <class T>
85MxM1Result<T> qsys_mxm1_pmf(const T& lambda_batch, const T& mu,
86 const std::vector<T>& batch_sizes, const std::vector<T>& pmf) {
87 if (batch_sizes.size() != pmf.size())
88 throw InputError("qsys_mxm1: batch sizes and pmf must have the same length");
89 if (batch_sizes.empty()) throw InputError("qsys_mxm1: empty batch-size support");
90 const T zero = num_traits<T>::from_int(0);
91 T tot = zero;
92 for (const T& v : pmf) tot += v;
93 if (tot == zero) throw InputError("qsys_mxm1: pmf sums to zero");
94 T E_X = zero, E_X2 = zero;
95 for (std::size_t i = 0; i < pmf.size(); ++i) {
96 const T w = pmf[i] / tot;
97 E_X += batch_sizes[i] * w;
98 E_X2 += batch_sizes[i] * batch_sizes[i] * w;
99 }
100 return qsys_mxm1(lambda_batch, mu, E_X, E_X2);
101}
102
103} // namespace qsys
104} // namespace line
105
106#endif // LINE_API_QSYS_QSYS_MXM1_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
MxM1Result< T > qsys_mxm1_variance(const T &lambda_batch, const T &mu, const T &E_X, const T &Var_X)
Variance form: MATLAB's qsys_mxm1(..., Var_X, 'variance').
Definition qsys_mxm1.h:75
MxM1Result< T > qsys_mxm1(const T &lambda_batch, const T &mu, const T &E_X, const T &E_X2)
M^X/M/1: the batch-arrival queue with exponential service.
Definition qsys_mxm1.h:59
MxM1Result< T > qsys_mxm1_pmf(const T &lambda_batch, const T &mu, const std::vector< T > &batch_sizes, const std::vector< T > &pmf)
Support-and-pmf form: MATLAB's qsys_mxm1(..., batch_sizes, pmf).
Definition qsys_mxm1.h:85
Number-type abstraction for the templated API port.
Shared return type and arithmetic helpers for the templated qsys port.
T W
mean time in system
Definition qsys_mxm1.h:44
T Wq
mean waiting time in queue
Definition qsys_mxm1.h:45
T U
server utilization rho
Definition qsys_mxm1.h:46
T Q
mean number in system, lambda W
Definition qsys_mxm1.h:47