5#ifndef LINE_API_MC_DTMC_TRANSIENT_H
6#define LINE_API_MC_DTMC_TRANSIENT_H
46 const std::size_t n = P.
rows();
47 if (P.
cols() != n)
throw InputError(
"dtmc_transient: P is not square");
48 std::vector<T> pik = pi0;
51 if (pik.size() != n)
throw InputError(
"dtmc_transient: pi0 has the wrong length");
53 for (std::size_t j = 0; j < n; ++j) out(0, j) = pik[j];
54 for (std::size_t k = 1; k <= steps; ++k) {
56 for (std::size_t i = 0; i < n; ++i)
57 for (std::size_t j = 0; j < n; ++j) next[j] += pik[i] * P(i, j);
59 for (std::size_t j = 0; j < n; ++j) out(k, j) = pik[j];
74 "dtmc_hitting_time requires a backend with an infinity, since a state that "
75 "cannot reach the target set has an infinite hitting time");
76 const std::size_t n = P.
rows();
77 if (P.
cols() != n)
throw InputError(
"dtmc_hitting_time: P is not square");
78 std::vector<bool> is_target(n,
false);
79 for (std::size_t k = 0; k < target.size(); ++k) {
80 if (target[k] >= n)
throw InputError(
"dtmc_hitting_time: target index out of range");
81 is_target[target[k]] =
true;
83 std::vector<std::size_t> nt;
84 for (std::size_t i = 0; i < n; ++i)
85 if (!is_target[i]) nt.push_back(i);
87 if (nt.empty())
return h;
88 const std::size_t m = nt.size();
90 for (std::size_t a = 0; a < m; ++a)
91 for (std::size_t b = 0; b < m; ++b)
97 std::vector<bool> reaches(m,
false);
101 for (std::size_t a = 0; a < m; ++a) {
102 if (reaches[a])
continue;
103 for (std::size_t j = 0; j < n; ++j) {
105 bool ok = is_target[j];
107 for (std::size_t c = 0; c < m; ++c)
108 if (nt[c] == j && reaches[c]) ok =
true;
117 std::vector<std::size_t> keep;
118 for (std::size_t a = 0; a < m; ++a) {
124 if (keep.empty())
return h;
127 for (std::size_t a = 0; a < keep.size(); ++a)
128 for (std::size_t c = 0; c < keep.size(); ++c) Ak(a, c) = A(keep[a], keep[c]);
129 const std::vector<T> hk =
solve(Ak, bk);
130 for (std::size_t a = 0; a < keep.size(); ++a) h[nt[keep[a]]] = hk[a];
137 const T& t,
double tol = 1e-12,
long maxiter = -1) {
Steady-state distribution of a continuous-time Markov chain.
The exception types the port throws.
LU factorization with partial pivoting, templated on the number type.
Dense matrix and non-owning view.
Matrix< T > ctmc_makeinfgen(const Matrix< T > &Q)
Set the diagonal so that every row sums to zero (ctmc_makeinfgen).
UniformizationResult< T > ctmc_uniformization(const std::vector< T > &pi0, const Matrix< T > &Q, const T &t, double tol=1e-12, long maxiter=-1)
Transient distribution of a CTMC by uniformization (Jensen's method), and the time-averaged distribut...
std::vector< T > dtmc_hitting_time(const Matrix< T > &P, const std::vector< std::size_t > &target)
Expected number of steps to reach the target set, zero on the target set itself.
UniformizationResult< T > dtmc_uniformization(const std::vector< T > &pi0, const Matrix< T > &P, const T &t, double tol=1e-12, long maxiter=-1)
Transient law of a DTMC through the uniformized generator of P.
Matrix< T > dtmc_transient(const Matrix< T > &P, const std::vector< T > &pi0, std::size_t steps)
Trajectory of the law over steps transitions, row k holding pi0 P^k.
Conservation laws of a layered queueing network, enumerated from its structure.
std::vector< T > solve(const Matrix< T > &A, const std::vector< T > &b)
Convenience: solve Ax = b, leaving A and b untouched.
Number-type abstraction for the templated API port.