LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
snc_env_map.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_SNC_ENV_MAP_H
6
#define LINE_API_SNC_ENV_MAP_H
7
8
/**
9
* @file
10
* @ingroup api_snc
11
* MGF arrival envelope of a MAP/MMPP flow with unit-size jobs.
12
*
13
* For a Markovian arrival process (D0,D1) counting N(0,t) unit-work jobs,
14
* `E[exp(theta*N(0,t))] = pi*expm((D0+D1*exp(theta))*t)*1`. With lstar the
15
* eigenvalue of maximal real part of `A(theta)=D0+D1*e^theta` and v > 0 its
16
* right Perron eigenvector, bounding `1 <= v/min(v)` entrywise gives
17
*
18
* rho(theta) = lstar/theta,
19
* sigma(theta) = log(max(v)/min(v))/theta,
20
*
21
* the standard exponential-form envelope of a Markov-modulated source. The burst
22
* term is what the modulating chain contributes: 0 for a one-phase MAP, where
23
* this reproduces `snc_env_poisson` exactly, and positive for an MMPP.
24
*
25
* THE PERRON PAIR IS COMPUTED BY POWER ITERATION ON THE SHIFTED MATRIX `A+cI`,
26
* not by a general eigensolver. A(theta) is essentially nonnegative, so the
27
* shift makes it nonnegative with a positive diagonal, hence primitive whenever
28
* the MAP is irreducible, and the iteration converges to the pair the bound
29
* needs without asking a general solver which of its eigenvectors is the
30
* positive one. The MATLAB reference uses `eig` and agrees to machine
31
* precision; the JAR port iterates the same way.
32
*
33
* Port of matlab/src/api/snc/snc_env_map.m. Reference: C.-S. Chang, Performance
34
* Guarantees in Communication Networks, Springer 2000, Ch. 7.
35
*/
36
37
#include <algorithm>
38
#include <cmath>
39
#include <cstddef>
40
#include <limits>
41
#include <vector>
42
#include "
line/api/snc/snc_types.h
"
43
#include "
line/util/error.h
"
44
#include "
line/util/matrix.h
"
45
46
namespace
line
{
47
namespace
snc
{
48
49
/**
50
* @brief MGF arrival envelope of a MAP/MMPP flow with unit-size jobs.
51
*
52
* @param D0 hidden-transition generator block of the MAP
53
* @param D1 arrival-transition block of the MAP
54
* @param theta Chernoff parameter, theta > 0
55
*/
56
inline
Env
snc_env_map
(
const
Matrix<double>
& D0,
const
Matrix<double>
& D1,
double
theta) {
57
if
(theta <= 0)
throw
UnsupportedError
(
"snc_env_map: theta must be positive"
);
58
const
std::size_t n = D0.
rows
();
59
if
(D0.
cols
() != n || D1.
rows
() != n || D1.
cols
() != n)
60
throw
UnsupportedError
(
"snc_env_map: D0 and D1 must be square and of equal size"
);
61
62
std::vector<std::vector<double>> A(n, std::vector<double>(n, 0.0));
63
const
double
etheta = std::exp(theta);
64
double
shift = 0.0;
65
for
(std::size_t i = 0; i < n; ++i) {
66
for
(std::size_t j = 0; j < n; ++j) A[i][j] = D0(i, j) + D1(i, j) * etheta;
67
shift = std::max(shift, -A[i][i]);
68
}
69
shift += 1.0;
70
for
(std::size_t i = 0; i < n; ++i) A[i][i] += shift;
71
72
std::vector<double> v(n, 1.0), w(n, 0.0);
73
double
lambdaShift = 0.0;
74
for
(
int
it = 0; it < 100000; ++it) {
75
for
(std::size_t i = 0; i < n; ++i) {
76
double
acc = 0.0;
77
for
(std::size_t j = 0; j < n; ++j) acc += A[i][j] * v[j];
78
w[i] = acc;
79
}
80
double
norm = 0.0;
81
for
(std::size_t i = 0; i < n; ++i) norm = std::max(norm, std::fabs(w[i]));
82
if
(!(norm > 0))
83
throw
UnsupportedError
(
84
"snc_env_map: MAP is not irreducible: the Perron eigenvector is not positive"
);
85
double
delta = 0.0;
86
for
(std::size_t i = 0; i < n; ++i) {
87
w[i] /= norm;
88
delta = std::max(delta, std::fabs(w[i] - v[i]));
89
}
90
v = w;
91
lambdaShift = norm;
92
if
(delta < 1e-14)
break
;
93
}
94
double
vmin = std::numeric_limits<double>::infinity(), vmax = 0.0;
95
for
(std::size_t i = 0; i < n; ++i) {
96
vmin = std::min(vmin, v[i]);
97
vmax = std::max(vmax, v[i]);
98
}
99
if
(!(vmin > 0))
100
throw
UnsupportedError
(
101
"snc_env_map: MAP is not irreducible: the Perron eigenvector is not positive"
);
102
return
Env
{std::log(vmax / vmin) / theta, (lambdaShift - shift) / theta};
103
}
104
105
/** The same envelope as a function of theta. */
106
inline
Envelope
snc_env_map_fn
(
const
Matrix<double>
& D0,
const
Matrix<double>
& D1) {
107
return
[D0, D1](
double
theta) {
return
snc_env_map
(D0, D1, theta); };
108
}
109
110
}
// namespace snc
111
}
// namespace line
112
113
#endif
// LINE_API_SNC_ENV_MAP_H
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::UnsupportedError::UnsupportedError
UnsupportedError(const std::string &what)
Definition
error.h:51
error.h
The exception types the port throws.
matrix.h
Dense matrix and non-owning view.
line::snc
Definition
snc_bound_backlog.h:34
line::snc::snc_env_map_fn
Envelope snc_env_map_fn(const Matrix< double > &D0, const Matrix< double > &D1)
The same envelope as a function of theta.
Definition
snc_env_map.h:106
line::snc::snc_env_map
Env snc_env_map(const Matrix< double > &D0, const Matrix< double > &D1, double theta)
MGF arrival envelope of a MAP/MMPP flow with unit-size jobs.
Definition
snc_env_map.h:56
line::snc::Envelope
std::function< Env(double)> Envelope
An envelope as a function of the Chernoff parameter.
Definition
snc_types.h:48
line
Definition
aoi_dist2ph.h:52
snc_types.h
Shared types of the stochastic network calculus domain.
line::snc::Env
The pair (sigma, rho) of an envelope evaluated at one theta.
Definition
snc_types.h:42
include
line
api
snc
snc_env_map.h
Generated by
1.18.0