5#ifndef LINE_API_MMDP_MMDP_H
6#define LINE_API_MMDP_MMDP_H
59 const std::size_t n = Q.
rows();
60 if (n == 0 || Q.
cols() != n)
return false;
61 if (R.
rows() != n || R.
cols() != n)
return false;
62 for (std::size_t i = 0; i < n; ++i) {
65 for (std::size_t j = 0; j < n; ++j) {
67 if (i != j && q < -tol)
return false;
70 if (std::fabs(rowsum) > tol)
return false;
72 for (std::size_t j = 0; j < n; ++j)
82 for (std::size_t i = 0; i < R.
rows(); ++i) r[i] = R(i, i);
89 const std::size_t n = Q.
rows();
90 if (n == 0)
throw InputError(
"mmdp_mean_rate: empty generator");
92 throw InputError(
"mmdp_mean_rate: R must be the same size as Q");
94 if (n == 1)
return R(0, 0);
97 for (std::size_t i = 0; i < n; ++i) m += pi[i] * R(i, i);
110 const std::size_t n = Q.
rows();
111 if (n == 0)
throw InputError(
"mmdp_scv: empty generator");
113 throw InputError(
"mmdp_scv: R must be the same size as Q");
115 if (n == 1)
return zero;
118 T m = zero, m2 = zero;
119 for (std::size_t i = 0; i < n; ++i) {
120 m += pi[i] * R(i, i);
121 m2 += pi[i] * R(i, i) * R(i, i);
125 return T((m2 - m * m) / (m * m));
144 const std::size_t n = D0.
rows();
145 if (n == 0 || D0.
cols() != n || D1.
rows() != n || D1.
cols() != n)
146 throw InputError(
"mmdp_from_map: D0 and D1 must be square and the same size");
150 for (std::size_t i = 0; i < n; ++i) {
152 for (std::size_t j = 0; j < n; ++j) {
153 out.
Q(i, j) = D0(i, j) + D1(i, j);
173 throw InputError(
"mmdp2: both switching rates must be positive");
177 out.
Q(0, 0) = -sigma0;
178 out.
Q(0, 1) = sigma0;
179 out.
Q(1, 0) = sigma1;
180 out.
Q(1, 1) = -sigma1;
189 return T((r0 * sigma1 + r1 * sigma0) / (sigma0 + sigma1));
194T
mmdp2_scv(
const T& r0,
const T& r1,
const T& sigma0,
const T& sigma1) {
195 const T tot = T(sigma0 + sigma1);
196 const T p0 = T(sigma1 / tot), p1 = T(sigma0 / tot);
197 const T m = T(p0 * r0 + p1 * r1);
200 const T v = T(p0 * r0 * r0 + p1 * r1 * r1 - m * m);
201 return T(v / (m * m));
Steady-state distribution of a continuous-time Markov chain.
The exception types the port throws.
Dense matrix and non-owning view.
std::vector< T > ctmc_solve(const Matrix< T > &Qin)
Steady-state distribution of a continuous-time Markov chain.
T mmdp_mean_rate(const Matrix< T > &Q, const Matrix< T > &R)
Stationary mean flow rate, pi diag(R).
bool mmdp_isfeasible(const Matrix< T > &Q, const Matrix< T > &R, double tol=1e-10)
True when (Q, R) is a valid MMDP.
T mmdp2_mean_rate(const T &r0, const T &r1, const T &sigma0, const T &sigma1)
The closed-form mean rate of a two-state MMDP.
std::vector< T > mmdp_rates(const Matrix< T > &R)
The per-state rates, i.e.
MmdpPair< T > mmdp2(const T &r0, const T &r1, const T &sigma0, const T &sigma1)
The two-state MMDP, in the reference's own parameterization.
MmdpPair< T > mmdp_from_map(const Matrix< T > &D0, const Matrix< T > &D1)
The MMDP of a MAP: Q = D0 + D1, R = diag(row sums of D1).
T mmdp2_scv(const T &r0, const T &r1, const T &sigma0, const T &sigma1)
The closed-form SCV of a two-state MMDP.
T mmdp_scv(const Matrix< T > &Q, const Matrix< T > &R)
SCV of the RATE under the stationary law: Var[r] / E[r]^2.
Number-type abstraction for the templated API port.
The (Q, R) pair of an MMDP.