LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
ctmc_randomization.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_RANDOMIZATION_H
6#define LINE_API_MC_CTMC_RANDOMIZATION_H
7
8/**
9 * @file
10 * @ingroup api_mc
11 * Uniformization (randomization) of a CTMC: the embedded DTMC P = I + Q/q.
12 *
13 * Templated port of matlab/lib/kpctoolbox/mc/ctmc_randomization.m and
14 * jar/src/main/java/jline/api/mc/Ctmc_randomization.java. The rate q must
15 * dominate max_i |q_ii| or P is not stochastic; the result is then passed
16 * through dtmc_makestochastic, which repairs the rounding of the division.
17 *
18 * REFERENCE DEFECT. The MATLAB default rate is max|Q| + rand, drawn from the
19 * global unseeded stream, so two calls on the same generator return different
20 * matrices and nothing downstream of it is reproducible. The default here is
21 * the deterministic q = (21/20) max|Q|, which is the same rate ctmc_courtois
22 * derives explicitly and which strictly exceeds max_i |q_ii| (so P stays
23 * stochastic and aperiodic). Every quantity the callers in this port take from
24 * P -- stationary vectors, SCC structure, aggregation matrices -- is invariant
25 * to q, so the substitution changes no result, only its reproducibility.
26 *
27 * Every operation is a field operation, so this is exact at Rational.
28 */
29
30#include <cstddef>
31
33#include "line/num/number.h"
34#include "line/util/error.h"
35#include "line/util/matrix.h"
36
37namespace line {
38namespace mc {
39
40template <class T>
42 Matrix<T> P; ///< uniformized stochastic matrix
43 T q; ///< rate actually used
44};
45
46/** Largest magnitude of any entry of Q; equals max_i |q_ii| for a generator. */
47template <class T>
50 for (std::size_t i = 0; i < Q.rows(); ++i)
51 for (std::size_t j = 0; j < Q.cols(); ++j) {
52 const T a = num_abs(T(Q(i, j)));
53 if (a > m) m = a;
54 }
55 return m;
56}
57
58/**
59 * @brief Uniformization (randomization) of a CTMC: the embedded DTMC P = I +
60 * Q/q.
61 *
62 * @param Q generator
63 * @param q uniformization rate, which must satisfy q >= max_i |q_ii|
64 */
65template <class T>
67 const std::size_t n = Q.rows();
68 if (Q.cols() != n) throw InputError("ctmc_randomization: generator is not square");
69 if (!(q > num_traits<T>::from_int(0)))
70 throw InputError("ctmc_randomization: the uniformization rate must be positive");
71 Matrix<T> P(n, n);
72 const T one = num_traits<T>::from_int(1);
73 for (std::size_t i = 0; i < n; ++i)
74 for (std::size_t j = 0; j < n; ++j)
75 P(i, j) = Q(i, j) / q + (i == j ? one : num_traits<T>::from_int(0));
78 r.q = q;
79 return r;
80}
81
82/** Deterministic default rate (21/20) max|Q|; see the defect note above. */
83template <class T>
85 const T m = ctmc_maxabs(Q);
86 // zero-transition uniformization rationale: see _kb/03-api-layer.md (cpp port notes: mc)
87 const T q = (m == num_traits<T>::from_int(0)) ? num_traits<T>::from_int(1)
88 : T(m * num_traits<T>::from_rational(21, 20));
89 return ctmc_randomization(Q, q);
90}
91
92} // namespace mc
93} // namespace line
94
95#endif // LINE_API_MC_CTMC_RANDOMIZATION_H
InputError(const std::string &what)
Definition error.h:39
std::size_t cols() const
Definition matrix.h:90
std::size_t rows() const
Definition matrix.h:89
Normalize a non-negative matrix into a stochastic transition matrix.
The exception types the port throws.
Dense matrix and non-owning view.
Matrix< T > dtmc_makestochastic(const Matrix< T > &Pin)
Normalize a non-negative matrix into a stochastic transition matrix.
T ctmc_maxabs(const Matrix< T > &Q)
Largest magnitude of any entry of Q; equals max_i |q_ii| for a generator.
RandomizationResult< T > ctmc_randomization(const Matrix< T > &Q, const T &q)
Uniformization (randomization) of a CTMC: the embedded DTMC P = I + Q/q.
T num_abs(const T &v)
Definition number.h:172
Number-type abstraction for the templated API port.
Matrix< T > P
uniformized stochastic matrix