LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
dtmc_rand.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_DTMC_RAND_H
6
#define LINE_API_MC_DTMC_RAND_H
7
8
/**
9
* @file
10
* @ingroup api_mc
11
* Random DTMC kernels, trajectory simulation and the weak-component split.
12
*
13
* Templated port of matlab/lib/kpctoolbox/mc: dtmc_rand.m, dtmc_simulate.m and
14
* weaklyconncomp.m.
15
*
16
* dtmc_rand is defined as the uniformization of a random generator, so its
17
* kernel always has a nonzero diagonal and never mixes at rate one. Building
18
* the rows directly from normalised uniforms would look equivalent and is not:
19
* the self-loop probability of the uniformized chain is 1 + q_ii/q, which
20
* concentrates near one on the fast states.
21
*
22
* weaklyconncomp goes through dmperm in MATLAB and through a graph traversal
23
* here. Component LABELS are therefore not comparable across the two, only the
24
* partition is; the labels here are assigned in order of the smallest member,
25
* which is the one canonical choice that is stable under recompilation.
26
*/
27
28
#include <algorithm>
29
#include <cstddef>
30
#include <random>
31
#include <vector>
32
33
#include "
line/api/mc/ctmc_rand.h
"
34
#include "
line/api/mc/ctmc_randomization.h
"
35
#include "
line/api/mc/ctmc_solve.h
"
36
#include "
line/num/number.h
"
37
#include "
line/util/error.h
"
38
#include "
line/util/matrix.h
"
39
40
namespace
line
{
41
namespace
mc
{
42
43
/** Random stochastic matrix, the uniformization of a random generator. */
44
template
<
class
T,
class
Gen>
45
Matrix<T>
dtmc_rand
(std::size_t n, Gen& gen) {
46
return
ctmc_randomization
(
ctmc_rand<T>
(n, gen)).P;
47
}
48
49
/**
50
* Sample path of a DTMC, n states starting from pi0.
51
*
52
* An absorbing state ends the path early, exactly as the reference does: it
53
* returns the prefix rather than padding, so the returned length is at most n.
54
*/
55
template
<
class
T,
class
Gen>
56
std::vector<std::size_t>
dtmc_simulate
(
const
Matrix<T>
& P,
const
std::vector<T>& pi0,
57
std::size_t n, Gen& gen) {
58
const
std::size_t m = P.
rows
();
59
if
(P.
cols
() != m)
throw
InputError
(
"dtmc_simulate: P is not square"
);
60
if
(pi0.size() != m)
throw
InputError
(
"dtmc_simulate: pi0 does not match the state space"
);
61
const
T zero =
num_traits<T>::from_int
(0);
62
std::uniform_real_distribution<double> unif(0.0, 1.0);
63
64
std::size_t st = m;
65
{
66
const
T r =
num_traits<T>::from_double
(unif(gen));
67
T acc = zero;
68
for
(std::size_t i = 0; i < m; ++i) {
69
acc += pi0[i];
70
if
(pi0[i] > zero && r < acc) {
71
st = i;
72
break
;
73
}
74
}
75
if
(st == m)
76
for
(std::size_t i = 0; i < m; ++i)
77
if
(pi0[i] > zero) {
78
st = i;
79
break
;
80
}
81
if
(st == m)
throw
InputError
(
"dtmc_simulate: pi0 puts no mass on any state"
);
82
}
83
84
std::vector<std::size_t> sts;
85
sts.reserve(n);
86
for
(std::size_t k = 0; k < n; ++k) {
87
sts.push_back(st);
88
T rowsum = zero;
89
for
(std::size_t j = 0; j < m; ++j) rowsum += P(st, j);
90
if
(rowsum == zero || P(st, st) ==
num_traits<T>::from_int
(1))
return
sts;
91
const
T r =
num_traits<T>::from_double
(unif(gen));
92
T acc = zero;
93
std::size_t nxt = m;
94
for
(std::size_t j = 0; j < m; ++j) {
95
acc += P(st, j);
96
if
(P(st, j) > zero && r < acc) {
97
nxt = j;
98
break
;
99
}
100
}
101
if
(nxt == m)
102
for
(std::size_t j = 0; j < m; ++j)
103
if
(P(st, j) > zero) {
104
nxt = j;
105
break
;
106
}
107
st = nxt;
108
}
109
return
sts;
110
}
111
112
/** Number of weakly connected components and the per-node label (weaklyconncomp.m). */
113
template
<
class
T>
114
struct
WeakCompResult
{
115
std::size_t
count
;
///< S, the number of components
116
std::vector<std::size_t>
comp
;
///< C, zero-based component label per node
117
};
118
119
/** Weakly connected components of the graph whose adjacency is the support of G. */
120
template
<
class
T>
121
WeakCompResult<T>
weaklyconncomp
(
const
Matrix<T>
& G) {
122
const
std::vector<std::vector<std::size_t>> parts = detail::weak_components(G);
123
WeakCompResult<T>
out;
124
out.
count
= parts.size();
125
out.
comp
.assign(G.
rows
(), 0);
126
for
(std::size_t c = 0; c < parts.size(); ++c)
127
for
(std::size_t k = 0; k < parts[c].size(); ++k) out.
comp
[parts[c][k]] = c;
128
return
out;
129
}
130
131
}
// namespace mc
132
}
// namespace line
133
134
#endif
// LINE_API_MC_DTMC_RAND_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
ctmc_rand.h
Random infinitesimal generator of a CTMC.
ctmc_randomization.h
Uniformization (randomization) of a CTMC: the embedded DTMC P = I + Q/q.
ctmc_solve.h
Steady-state distribution of a continuous-time Markov chain.
error.h
The exception types the port throws.
matrix.h
Dense matrix and non-owning view.
line::mc
Definition
ctmc_bicgstab.h:59
line::mc::weaklyconncomp
WeakCompResult< T > weaklyconncomp(const Matrix< T > &G)
Weakly connected components of the graph whose adjacency is the support of G.
Definition
dtmc_rand.h:121
line::mc::ctmc_rand
Matrix< T > ctmc_rand(std::size_t n, Gen &gen)
Random infinitesimal generator of a CTMC.
Definition
ctmc_rand.h:71
line::mc::dtmc_rand
Matrix< T > dtmc_rand(std::size_t n, Gen &gen)
Random stochastic matrix, the uniformization of a random generator.
Definition
dtmc_rand.h:45
line::mc::ctmc_randomization
RandomizationResult< T > ctmc_randomization(const Matrix< T > &Q, const T &q)
Uniformization (randomization) of a CTMC: the embedded DTMC P = I + Q/q.
Definition
ctmc_randomization.h:66
line::mc::dtmc_simulate
std::vector< std::size_t > dtmc_simulate(const Matrix< T > &P, const std::vector< T > &pi0, std::size_t n, Gen &gen)
Sample path of a DTMC, n states starting from pi0.
Definition
dtmc_rand.h:56
line
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
line::mc::WeakCompResult
Number of weakly connected components and the per-node label (weaklyconncomp.m).
Definition
dtmc_rand.h:114
line::mc::WeakCompResult::count
std::size_t count
S, the number of components.
Definition
dtmc_rand.h:115
line::mc::WeakCompResult::comp
std::vector< std::size_t > comp
C, zero-based component label per node.
Definition
dtmc_rand.h:116
line::num_traits
Definition
number.h:111
include
line
api
mc
dtmc_rand.h
Generated by
1.18.0