LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
lossn_erlangfp.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_LOSSN_LOSSN_ERLANGFP_H
6
#define LINE_API_LOSSN_LOSSN_ERLANGFP_H
7
8
/**
9
* @file
10
* @ingroup api_lossn
11
* Erlang fixed-point (reduced-load) approximation for a loss network.
12
*
13
* Templated port of matlab/src/api/lossn/lossn_erlangfp.m. Each link j carries
14
* an offered load
15
* rho_j = (1/(1-E_j)) sum_r nu_r A(j,r) prod_i (1-E_i)^A(i,r)
16
* and blocks it with Erlang's loss formula B(rho_j, C_j); the vector E is the
17
* fixed point of that map, reached by the shared damped iteration in
18
* line::da::da_fpi. Carried traffic and per-class loss follow from E.
19
*
20
* MATLAB evaluates Erlang B through logs and exponentials to keep the
21
* factorials in range. The port keeps that form, and consequently the whole
22
* function is transcendental-gated: the fixed point is only defined to within
23
* the iteration tolerance anyway, so an exact instantiation would promise more
24
* than the algorithm delivers.
25
*
26
* The recursive form B_k = rho B_{k-1} / (k + rho B_{k-1}) IS rational, and a
27
* future exact variant of the blocking formula alone could use it; the fixed
28
* point around it would still be inexact.
29
*/
30
31
#include <cmath>
32
#include <cstddef>
33
#include <functional>
34
#include <vector>
35
36
#include "
line/api/da/da_fpi.h
"
37
#include "
line/num/number.h
"
38
#include "
line/util/error.h
"
39
#include "
line/util/matrix.h
"
40
41
namespace
line
{
42
namespace
lossn
{
43
44
template
<
class
T>
45
struct
ErlangFpResult
{
46
std::vector<T>
QLen
;
///< carried traffic per class
47
std::vector<T>
Loss
;
///< blocking probability per class
48
std::vector<T>
E
;
///< per-link blocking probabilities (the fixed point)
49
std::size_t
iterations
= 0;
50
bool
converged
=
false
;
51
};
52
53
/**
54
* Erlang's loss formula B(nu, C), evaluated through logs as MATLAB does so the
55
* factorials stay in range for large C.
56
*/
57
template
<
class
T>
58
T
erlang_b
(
const
T& nu,
int
C) {
59
static_assert
(
num_traits<T>::has_transcendental
,
60
"erlang_b as ported evaluates through log/exp; use the rational recursion "
61
"B_k = nu B_{k-1} / (k + nu B_{k-1}) for an exact variant"
);
62
if
(C < 0)
throw
InputError
(
"erlang_b: negative capacity"
);
63
using
std::exp;
64
using
std::log;
65
const
T lnu = log(nu);
66
T den =
num_traits<T>::from_int
(0);
67
for
(
int
i = 0; i <= C; ++i)
68
den += exp(
num_traits<T>::from_int
(i) * lnu - log(
num_factorial<T>
(
static_cast<
unsigned
>
(i))));
69
const
T lb =
num_traits<T>::from_int
(C) * lnu -
70
log(
num_factorial<T>
(
static_cast<
unsigned
>
(C))) - log(den);
71
return
exp(lb);
72
}
73
74
/**
75
* @brief Erlang fixed-point (reduced-load) approximation for a loss network.
76
*
77
* @param nu offered load per class (R)
78
* @param A (J x R) route matrix: A(j,r) is the number of circuits class r
79
* takes on link j
80
* @param C (J) link capacities
81
* @param options fixed-point options (tolerance, iteration cap, damping)
82
*/
83
template
<
class
T>
84
ErlangFpResult<T>
lossn_erlangfp
(
const
std::vector<T>& nu,
const
Matrix<T>
& A,
85
const
std::vector<int>& C,
86
const
da::FpiOptions
& options =
da::FpiOptions
()) {
87
static_assert
(
num_traits<T>::has_transcendental
,
88
"lossn_erlangfp requires transcendental arithmetic (Erlang B through logs, and "
89
"a tolerance-driven fixed point)"
);
90
const
std::size_t R = nu.size();
91
const
std::size_t J = C.size();
92
if
(A.
rows
() != J || A.
cols
() != R)
93
throw
InputError
(
"lossn_erlangfp: the route matrix does not match nu and C"
);
94
95
const
T zero =
num_traits<T>::from_int
(0), one =
num_traits<T>::from_int
(1);
96
97
// One sweep of the reduced-load map, in the (xnew, xref) form da_fpi wants.
98
const
std::function<std::pair<std::vector<T>, std::vector<T>>(
const
std::vector<T>&, std::size_t)>
99
sweep = [&](
const
std::vector<T>& Eprev, std::size_t) {
100
std::vector<T> Enew = Eprev;
101
for
(std::size_t j = 0; j < J; ++j) {
102
T rhoj = zero;
103
for
(std::size_t r = 0; r < R; ++r) {
104
if
(A(j, r) <= zero)
continue
;
105
T term = nu[r] * A(j, r);
106
for
(std::size_t i = 0; i < J; ++i) {
107
if
(A(i, r) <= zero)
continue
;
108
const
long
e =
static_cast<
long
>
(
num_traits<T>::to_double
(A(i, r)));
109
term *=
num_pow_int
(T(one - Eprev[i]),
static_cast<
unsigned
>
(e));
110
}
111
rhoj += term;
112
}
113
const
T avail = one - Eprev[j];
114
if
(avail == zero)
throw
NumericError
(
"lossn_erlangfp: link blocked with probability 1"
);
115
rhoj /= avail;
116
Enew[j] =
erlang_b
(rhoj, C[j]);
117
}
118
return
std::make_pair(Enew, Eprev);
119
};
120
121
std::vector<T> E0(J,
num_traits<T>::from_rational
(1, 2));
122
da::FpiResult<T>
fp =
da::da_fpi<T>
(sweep, E0, options);
123
124
ErlangFpResult<T>
r;
125
r.
E
= fp.
x
;
126
r.
iterations
= fp.
iterations
;
127
r.
converged
= fp.
converged
;
128
r.
QLen
.assign(R, zero);
129
r.
Loss
.assign(R, zero);
130
for
(std::size_t cls = 0; cls < R; ++cls) {
131
T q = nu[cls];
132
for
(std::size_t j = 0; j < J; ++j) {
133
if
(A(j, cls) <= zero)
continue
;
134
const
long
e =
static_cast<
long
>
(
num_traits<T>::to_double
(A(j, cls)));
135
q *=
num_pow_int
(T(one - r.
E
[j]),
static_cast<
unsigned
>
(e));
136
}
137
r.
QLen
[cls] = q;
138
r.
Loss
[cls] = (nu[cls] == zero) ? zero : one - q / nu[cls];
139
}
140
return
r;
141
}
142
143
}
// namespace lossn
144
}
// namespace line
145
146
#endif
// LINE_API_LOSSN_LOSSN_ERLANGFP_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::NumericError::NumericError
NumericError(const std::string &what)
Definition
error.h:45
da_fpi.h
Damped fixed-point iteration, the shared driver of the decomposition algorithms.
error.h
The exception types the port throws.
matrix.h
Dense matrix and non-owning view.
line::da::da_fpi
FpiResult< T > da_fpi(const std::function< std::pair< std::vector< T >, std::vector< T > >(const std::vector< T > &, std::size_t)> &iterfun, const std::vector< T > &x0, const FpiOptions &options=FpiOptions())
Damped fixed-point iteration, the shared driver of the decomposition algorithms.
Definition
da_fpi.h:92
line::lossn
Definition
lossn_erlangfp.h:42
line::lossn::lossn_erlangfp
ErlangFpResult< T > lossn_erlangfp(const std::vector< T > &nu, const Matrix< T > &A, const std::vector< int > &C, const da::FpiOptions &options=da::FpiOptions())
Erlang fixed-point (reduced-load) approximation for a loss network.
Definition
lossn_erlangfp.h:84
line::lossn::erlang_b
T erlang_b(const T &nu, int C)
Erlang's loss formula B(nu, C), evaluated through logs as MATLAB does so the factorials stay in range...
Definition
lossn_erlangfp.h:58
line
Definition
aoi_dist2ph.h:52
line::num_factorial
T num_factorial(unsigned n)
Factorial as a value of T.
Definition
number.h:184
line::num_pow_int
T num_pow_int(const T &base, unsigned e)
Integer power, valid in any field (no transcendental requirement).
Definition
number.h:192
number.h
Number-type abstraction for the templated API port.
line::da::FpiOptions
Options mirroring the fields MATLAB reads off the options struct.
Definition
da_fpi.h:50
line::da::FpiResult
Definition
da_fpi.h:76
line::da::FpiResult::iterations
std::size_t iterations
Definition
da_fpi.h:78
line::da::FpiResult::x
std::vector< T > x
Definition
da_fpi.h:77
line::da::FpiResult::converged
bool converged
Definition
da_fpi.h:79
line::lossn::ErlangFpResult
Definition
lossn_erlangfp.h:45
line::lossn::ErlangFpResult::iterations
std::size_t iterations
Definition
lossn_erlangfp.h:49
line::lossn::ErlangFpResult::E
std::vector< T > E
per-link blocking probabilities (the fixed point)
Definition
lossn_erlangfp.h:48
line::lossn::ErlangFpResult::QLen
std::vector< T > QLen
carried traffic per class
Definition
lossn_erlangfp.h:46
line::lossn::ErlangFpResult::Loss
std::vector< T > Loss
blocking probability per class
Definition
lossn_erlangfp.h:47
line::lossn::ErlangFpResult::converged
bool converged
Definition
lossn_erlangfp.h:50
line::num_traits
Definition
number.h:111
include
line
api
lossn
lossn_erlangfp.h
Generated by
1.18.0