LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
pfqn_gldsingle.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_PFQN_GLDSINGLE_H
6
#define LINE_API_PFQN_GLDSINGLE_H
7
8
/**
9
* @file
10
* @ingroup api_pfqn
11
* Exact normalizing constant of a SINGLE-CLASS closed network whose stations
12
* are load dependent.
13
*
14
* Templated port of matlab/src/api/pfqn/pfqn_gldsingle.m.
15
*
16
* The recursion carries a rate offset t alongside the station index m and the
17
* population n, so that the jobs already placed at station m shift its rate
18
* lattice without materializing a separate shifted matrix:
19
*
20
* g(0, n, t) = 0 for n >= 1
21
* g(m, 0, t) = 1
22
* g(m, n, t) = g(m-1, n, 1) + L(m) g(m, n-1, t+1) / mu(m, t)
23
* G = g(M, N, 1)
24
*
25
* This is the single-class specialization of pfqn_gld; the two agree to the
26
* last bit on every model both accept, and the specialization is kept because
27
* pfqn_ncld dispatches to it directly for R = 1 and because it costs O(M N^2)
28
* rather than going through the general convolution.
29
*
30
* Arithmetic: EXACT-CAPABLE. MATLAB carries TWO implementations of the same
31
* recursion, a linear one and a log-space one selected by
32
*
33
* useLog = isreal(L) && isreal(mu) && all(L>=0) && all(mu>0)
34
*
35
* with a pairwise log-sum-exp replacing the addition. That branch is purely a
36
* range-management device for IEEE double -- the comment in the reference says
37
* so explicitly, citing underflow of the delay term to realmin at N >= 190 --
38
* and the two branches compute the same mathematical quantity. This port keeps
39
* only the linear recursion, which is exact in any field: at T = Rational
40
* there is no underflow to manage, and at T = Real<D> the exponent range is
41
* wide enough that the models which drove the reference into log space stay in
42
* range. Callers that genuinely need the double path on such a model should
43
* raise the arithmetic rather than reintroduce the logs, since the log-sum-exp
44
* form cannot represent the negative intermediate rates that the reference's
45
* own `useLog` guard exists to fall back from.
46
*
47
* An infinite rate is accepted the same way the reference accepts it: the term
48
* L/mu vanishes. In an exact field there is no infinity, so a caller expressing
49
* "this station cannot hold this many jobs" must pass a zero DEMAND instead.
50
*/
51
52
#include <cstddef>
53
#include <vector>
54
55
#include "
line/api/pfqn/pfqn_ca.h
"
56
#include "
line/num/number.h
"
57
#include "
line/util/error.h
"
58
#include "
line/util/matrix.h
"
59
60
namespace
line
{
61
namespace
pfqn
{
62
63
/**
64
* @brief Exact normalizing constant of a SINGLE-CLASS closed network whose
65
* stations are load dependent.
66
*
67
* @param L (M x 1) service demands, one class
68
* @param N population
69
* @param mu (M x >=N) load-dependent rates, mu(i,k) with k jobs at station i
70
*/
71
template
<
class
T>
72
NcResult<T>
pfqn_gldsingle
(
const
Matrix<T>
& L,
int
N,
const
Matrix<T>
& mu) {
73
if
(!L.
empty
() && L.
cols
() != 1)
74
throw
InputError
(
"pfqn_gldsingle: multiclass model detected, this routine is single class"
);
75
if
(N < 0)
throw
InputError
(
"pfqn_gldsingle: negative population"
);
76
77
const
std::size_t M = L.
empty
() ? 0 : L.
rows
();
78
const
T zero =
num_traits<T>::from_int
(0);
79
const
T one =
num_traits<T>::from_int
(1);
80
81
if
(N == 0)
return
{one, 0.0};
82
if
(M == 0)
return
{zero,
num_traits<T>::log_as_double
(zero)};
83
if
(mu.
rows
() != M)
throw
InputError
(
"pfqn_gldsingle: mu has the wrong station count"
);
84
if
(
static_cast<
int
>
(mu.
cols
()) < N)
85
throw
InputError
(
"pfqn_gldsingle: mu has fewer rate columns than the population"
);
86
87
const
std::size_t Nu =
static_cast<
std::size_t
>
(N);
88
// g[m][n][t], t = 1 .. N+2 stored at index t; index 0 unused. The station
89
// index m runs 0 .. M with m = 0 the empty network.
90
const
std::size_t Tdim = Nu + 3;
91
std::vector<T> g(
static_cast<
std::size_t
>
(M + 1) * (Nu + 1) * Tdim, zero);
92
const
auto
at = [&](std::size_t m, std::size_t n, std::size_t t) -> T& {
93
return
g[(m * (Nu + 1) + n) * Tdim + t];
94
};
95
96
// g(0, n, t) = 0 for n >= 1 (already zero); g(0, 0, t) is never read.
97
for
(std::size_t m = 1; m <= M; ++m) {
98
for
(std::size_t t = 1; t <= Nu + 1; ++t) at(m, 0, t) = one;
99
for
(std::size_t n = 1; n <= Nu; ++n) {
100
for
(std::size_t t = 1; t + n <= Nu + 1; ++t) {
101
const
T& rate = mu(m - 1, t - 1);
102
if
(rate == zero)
103
throw
NumericError
(
104
"pfqn_gldsingle: a load-dependent rate is zero, the station cannot serve "
105
"and the normalizing constant diverges"
);
106
at(m, n, t) = at(m - 1, n, 1) + L(m - 1, 0) * at(m, n - 1, t + 1) / rate;
107
}
108
}
109
}
110
111
const
T G = at(M, Nu, 1);
112
return
{G,
num_traits<T>::log_as_double
(G)};
113
}
114
115
}
// namespace pfqn
116
}
// namespace line
117
118
#endif
// LINE_API_PFQN_GLDSINGLE_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
line::Matrix
Definition
matrix.h:56
line::Matrix::cols
std::size_t cols() const
Definition
matrix.h:90
line::Matrix::rows
std::size_t rows() const
Definition
matrix.h:89
line::Matrix::empty
bool empty() const
Definition
matrix.h:92
line::NumericError::NumericError
NumericError(const std::string &what)
Definition
error.h:45
error.h
The exception types the port throws.
matrix.h
Dense matrix and non-owning view.
line::pfqn
Definition
cd_peak_scaling.h:43
line::pfqn::pfqn_gldsingle
NcResult< T > pfqn_gldsingle(const Matrix< T > &L, int N, const Matrix< T > &mu)
Exact normalizing constant of a SINGLE-CLASS closed network whose stations are load dependent.
Definition
pfqn_gldsingle.h:72
line
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
pfqn_ca.h
Convolution algorithm for the exact normalizing constant of a closed product-form network (Buzen 1973...
line::num_traits
Definition
number.h:111
line::pfqn::NcResult
Return value of the normalizing-constant family, mirroring Ret.pfqnNc.
Definition
pfqn_ca.h:44
include
line
api
pfqn
pfqn_gldsingle.h
Generated by
1.18.0