LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
qsys_gig1_rq.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_GIG1_RQ_H
6
#define LINE_API_QSYS_QSYS_GIG1_RQ_H
7
8
/**
9
* @file
10
* @ingroup api_qsys
11
* Robust Queueing (RQ) approximation of a G/GI/1 queue characterized by its
12
* arrival index of dispersion and the first two service moments.
13
*
14
* Templated port of matlab/src/api/qsys/qsys_gig1_rq.m, cross-checked against
15
* jar/src/main/java/jline/api/qsys/Qsys_gig1_rq.java.
16
*
17
* The mean steady-state workload is the value of a one-dimensional variational
18
* problem (Whitt and You 2018, eqs. (13), (16)-(18)):
19
*
20
* Zstar = sup_{x>=0} [ -(1-rho) x + sqrt( 2 rho x (I_a(x) + c_s^2)/mu ) ]
21
* W = max(0, Zstar/rho - (c_s^2+1)/(2 mu))
22
* Q = lambda W the mean number waiting
23
* X = Q + rho the mean number in system
24
*
25
* The objective is unimodal in practice but not guaranteed to be, so MATLAB
26
* brackets it with a 200-point log-spaced scan over [1e-6, 1e8] and refines
27
* the best bracket with fminbnd at TolX 1e-10, keeping the better of the scan
28
* value and the refined value. The port keeps the same scan and refines with
29
* golden-section search on the same bracket at the same TolX. fminbnd is
30
* golden section with parabolic acceleration, so on a bracket containing a
31
* single interior maximum the two locate the same point to within TolX; and
32
* because MATLAB and the port both return max(scan, refined), a refinement
33
* that lands short can never fall below the scan value. Where the objective
34
* really is multimodal both are equally at the mercy of the scan, and neither
35
* claims a global optimum.
36
*
37
* ARITHMETIC. The square root and the tolerance-driven search make this
38
* transcendental.
39
*
40
* The arrival process enters only through the callable I_a(x), so the caller
41
* supplies whatever index-of-dispersion model applies; for a renewal arrival
42
* stream I_a is the constant c_a^2.
43
*
44
* At rho <= 0 all four measures are zero, as in MATLAB. At rho >= 1 MATLAB
45
* returns Inf; the port raises instead, since the exact instantiations have no
46
* infinity and a silent Inf propagates into whatever consumes the result.
47
*/
48
49
#include <cstddef>
50
#include <vector>
51
52
#include "
line/api/qsys/qsys_types.h
"
53
#include "
line/num/number.h
"
54
#include "
line/util/error.h
"
55
56
namespace
line
{
57
namespace
qsys
{
58
59
template
<
class
T>
60
struct
Gig1RqResult
{
61
T
Z
;
///< mean steady-state workload E[Z]
62
T
W
;
///< mean steady-state waiting time E[W]
63
T
Q
;
///< mean number waiting, lambda W
64
T
X
;
///< mean number in system, Q + rho
65
};
66
67
/**
68
* @brief Robust Queueing (RQ) approximation of a G/GI/1 queue characterized
69
* by its arrival index of dispersion and the first two service moments.
70
*
71
* @param rho traffic intensity lambda/mu
72
* @param mu service rate
73
* @param cs2 squared coefficient of variation of the service time
74
* @param IaFun_ callable, IaFun_(x) -> the arrival IDC I_a(x) at x > 0
75
*/
76
template
<
class
T,
class
IaFun>
77
Gig1RqResult<T>
qsys_gig1_rq
(
const
T& rho,
const
T& mu,
const
T& cs2, IaFun&& IaFun_) {
78
static_assert
(
num_traits<T>::has_transcendental
,
79
"qsys_gig1_rq requires transcendental arithmetic"
);
80
const
T zero =
num_traits<T>::from_int
(0), one =
num_traits<T>::from_int
(1);
81
const
T two =
num_traits<T>::from_int
(2);
82
Gig1RqResult<T>
r;
83
if
(rho <= zero) {
84
r.
Z
= r.
W
= r.
Q
= r.
X
= zero;
85
return
r;
86
}
87
if
(rho >= one)
88
throw
InputError
(
"qsys_gig1_rq: rho must be strictly less than 1 for a finite workload"
);
89
const
T lambda = rho * mu;
90
91
// f(x) = -(1-rho) x + sqrt(2 rho x (I_a(x) + c_s^2)/mu), and f(x<=0) = 0.
92
auto
f = [&](
const
T& x) -> T {
93
if
(x <= zero)
return
zero;
94
const
T ia = IaFun_(x);
95
T inner = two * rho * x * (ia + cs2) / mu;
96
if
(inner < zero) inner = zero;
97
return
-(one - rho) * x + detail::num_sqrt(inner);
98
};
99
100
// Coarse log-spaced scan over [1e-6, 1e8], 200 points, as in MATLAB.
101
const
std::size_t NS = 200;
102
std::vector<T> xs(NS);
103
for
(std::size_t i = 0; i < NS; ++i) {
104
const
double
e = -6.0 + 14.0 *
static_cast<
double
>
(i) /
static_cast<
double
>
(NS - 1);
105
xs[i] = T(
num_traits<T>::from_double
(std::pow(10.0, e)));
106
}
107
std::size_t imax = 0;
108
T best = f(xs[0]);
109
for
(std::size_t i = 1; i < NS; ++i) {
110
const
T v = f(xs[i]);
111
if
(v > best) {
112
best = v;
113
imax = i;
114
}
115
}
116
T lo = xs[imax > 0 ? imax - 1 : 0];
117
T hi = xs[imax + 1 < NS ? imax + 1 : NS - 1];
118
119
// Golden-section refinement on the bracket at TolX 1e-10.
120
const
T tolx = T(
num_traits<T>::from_double
(1e-10));
121
const
T invphi = T(
num_traits<T>::from_double
(0.6180339887498949));
122
T c = hi - (hi - lo) * invphi;
123
T d = lo + (hi - lo) * invphi;
124
T fc = f(c), fd = f(d);
125
for
(
unsigned
it = 0; it < 500u && hi - lo > tolx; ++it) {
126
if
(fc > fd) {
127
hi = d;
128
d = c;
129
fd = fc;
130
c = hi - (hi - lo) * invphi;
131
fc = f(c);
132
}
else
{
133
lo = c;
134
c = d;
135
fc = fd;
136
d = lo + (hi - lo) * invphi;
137
fd = f(d);
138
}
139
}
140
const
T refined = fc > fd ? fc : fd;
141
T Z = best > refined ? best : refined;
142
if
(Z < zero) Z = zero;
143
144
r.
Z
= Z;
145
T W = Z / rho - (cs2 + one) / (two * mu);
146
if
(W < zero) W = zero;
147
r.
W
= W;
148
r.
Q
= lambda * W;
149
r.
X
= r.
Q
+ rho;
150
return
r;
151
}
152
153
}
// namespace qsys
154
}
// namespace line
155
156
#endif
// LINE_API_QSYS_QSYS_GIG1_RQ_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
error.h
The exception types the port throws.
line::qsys
Definition
qsys_bmapm1.h:58
line::qsys::qsys_gig1_rq
Gig1RqResult< T > qsys_gig1_rq(const T &rho, const T &mu, const T &cs2, IaFun &&IaFun_)
Robust Queueing (RQ) approximation of a G/GI/1 queue characterized by its arrival index of dispersion...
Definition
qsys_gig1_rq.h:77
line
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
qsys_types.h
Shared return type and arithmetic helpers for the templated qsys port.
line::num_traits
Definition
number.h:111
line::qsys::Gig1RqResult
Definition
qsys_gig1_rq.h:60
line::qsys::Gig1RqResult::Q
T Q
mean number waiting, lambda W
Definition
qsys_gig1_rq.h:63
line::qsys::Gig1RqResult::Z
T Z
mean steady-state workload E[Z]
Definition
qsys_gig1_rq.h:61
line::qsys::Gig1RqResult::X
T X
mean number in system, Q + rho
Definition
qsys_gig1_rq.h:64
line::qsys::Gig1RqResult::W
T W
mean steady-state waiting time E[W]
Definition
qsys_gig1_rq.h:62
include
line
api
qsys
qsys_gig1_rq.h
Generated by
1.18.0