LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
ctmc_relsolve.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_MC_CTMC_RELSOLVE_H
6
#define LINE_API_MC_CTMC_RELSOLVE_H
7
8
/**
9
* @file
10
* @ingroup api_mc
11
* Equilibrium distribution relative to a reference state.
12
*
13
* Templated port of matlab/lib/kpctoolbox/mc/ctmc_relsolve.m. The balance
14
* equations are closed with p(refstate) = 1 instead of sum(p) = 1, so the
15
* result is NOT a probability vector: it is the stationary measure scaled so
16
* that the reference state carries weight one. Dividing by its sum recovers
17
* ctmc_solve. Keeping the unnormalized form is what makes the ratios usable
18
* when the normalizing constant itself overflows.
19
*
20
* On a reducible generator the reference-state closure is meaningless across
21
* components, so the reducible case falls back to solving each weakly connected
22
* component and renormalizing globally, exactly as MATLAB does.
23
*/
24
25
#include <cstddef>
26
#include <vector>
27
28
#include "
line/api/mc/ctmc_solve.h
"
29
#include "
line/num/number.h
"
30
#include "
line/util/error.h
"
31
#include "
line/util/lu.h
"
32
#include "
line/util/matrix.h
"
33
34
namespace
line
{
35
namespace
mc
{
36
37
/** Stationary measure scaled so that entry refstate equals one. */
38
template
<
class
T>
39
std::vector<T>
ctmc_relsolve
(
const
Matrix<T>
& Qin, std::size_t refstate) {
40
const
std::size_t n = Qin.
rows
();
41
if
(Qin.
cols
() != n)
throw
InputError
(
"ctmc_relsolve: Q is not square"
);
42
if
(n == 0)
throw
InputError
(
"ctmc_relsolve: Q is empty"
);
43
if
(refstate >= n)
throw
InputError
(
"ctmc_relsolve: refstate out of range"
);
44
const
T zero =
num_traits<T>::from_int
(0);
45
if
(n == 1)
return
std::vector<T>(1,
num_traits<T>::from_int
(1));
46
const
Matrix<T>
Q =
ctmc_makeinfgen
(Qin);
47
const
std::vector<std::vector<std::size_t>> comps = detail::weak_components(Q);
48
if
(comps.size() > 1) {
49
std::vector<T> p(n, zero);
50
for
(std::size_t c = 0; c < comps.size(); ++c) {
51
const
Matrix<T>
Qc =
ctmc_makeinfgen
(detail::submatrix(Q, comps[c]));
52
const
std::vector<T> pc =
ctmc_solve
(Qc);
53
for
(std::size_t k = 0; k < comps[c].size(); ++k) p[comps[c][k]] = pc[k];
54
}
55
T s = zero;
56
for
(std::size_t i = 0; i < n; ++i) s += p[i];
57
for
(std::size_t i = 0; i < n; ++i) p[i] = p[i] / s;
58
return
p;
59
}
60
bool
allzero =
true
;
61
for
(std::size_t i = 0; i < n && allzero; ++i)
62
for
(std::size_t j = 0; j < n; ++j)
63
if
(Q(i, j) != zero) {
64
allzero =
false
;
65
break
;
66
}
67
if
(allzero)
68
return
std::vector<T>(n,
num_traits<T>::from_int
(1) /
69
num_traits<T>::from_int
(
static_cast<
int
>
(n)));
70
// The last balance equation is redundant, so it is replaced by p(refstate) = 1.
71
Matrix<T>
A(n, n, zero);
72
for
(std::size_t i = 0; i < n; ++i)
73
for
(std::size_t j = 0; j + 1 < n; ++j) A(j, i) = Q(i, j);
74
A(n - 1, refstate) =
num_traits<T>::from_int
(1);
75
std::vector<T> b(n, zero);
76
b[n - 1] =
num_traits<T>::from_int
(1);
77
return
solve
(A, b);
78
}
79
80
/** Reference state 1 in the MATLAB numbering, i.e. index 0 here. */
81
template
<
class
T>
82
std::vector<T>
ctmc_relsolve
(
const
Matrix<T>
& Q) {
83
return
ctmc_relsolve
(Q,
static_cast<
std::size_t
>
(0));
84
}
85
86
}
// namespace mc
87
}
// namespace line
88
89
#endif
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
ctmc_solve.h
Steady-state distribution of a continuous-time Markov chain.
error.h
The exception types the port throws.
lu.h
LU factorization with partial pivoting, templated on the number type.
matrix.h
Dense matrix and non-owning view.
line::mc
Definition
ctmc_bicgstab.h:59
line::mc::ctmc_makeinfgen
Matrix< T > ctmc_makeinfgen(const Matrix< T > &Q)
Set the diagonal so that every row sums to zero (ctmc_makeinfgen).
Definition
ctmc_solve.h:58
line::mc::ctmc_solve
std::vector< T > ctmc_solve(const Matrix< T > &Qin)
Steady-state distribution of a continuous-time Markov chain.
Definition
ctmc_solve.h:122
line::mc::ctmc_relsolve
std::vector< T > ctmc_relsolve(const Matrix< T > &Qin, std::size_t refstate)
Stationary measure scaled so that entry refstate equals one.
Definition
ctmc_relsolve.h:39
line
Definition
aoi_dist2ph.h:52
line::solve
std::vector< T > solve(const Matrix< T > &A, const std::vector< T > &b)
Convenience: solve Ax = b, leaving A and b untouched.
Definition
lu.h:158
number.h
Number-type abstraction for the templated API port.
line::num_traits
Definition
number.h:111
include
line
api
mc
ctmc_relsolve.h
Generated by
1.18.0