5#ifndef LINE_API_FES_MAP_MOMENTS_H
6#define LINE_API_FES_MAP_MOMENTS_H
61std::vector<T> solve_row(
const Matrix<T>& A,
const std::vector<T>& b) {
63 for (std::size_t i = 0; i < A.
rows(); ++i)
64 for (std::size_t j = 0; j < A.
cols(); ++j) At(j, i) = A(i, j);
81 std::size_t iter_max) {
84 std::vector<T> y(v.size(), zero);
89 for (std::size_t it = 0; it < iter_max; ++it) {
90 const std::vector<T> zT0 =
vecmul(z, T0);
91 std::vector<T> znext(z.size());
92 for (std::size_t i = 0; i < z.size(); ++i) znext[i] = z[i] + dt * zT0[i];
93 for (std::size_t i = 0; i < y.size(); ++i) y[i] += dt * half * (z[i] + znext[i]);
97 if (nrm <= tol * nrm0)
break;
113 double step_safety = 0.1,
double tol = 1e-12,
114 std::size_t iter_max = 1000000) {
117 const std::size_t dim = T0.
rows();
123 std::vector<T> pie =
vecmul(phi, T1);
125 for (
const T& x : pie) lambda += x;
126 for (std::size_t i = 0; i < pie.size(); ++i) pie[i] = pie[i] / lambda;
129 for (std::size_t i = 0; i < dim; ++i)
130 for (std::size_t j = 0; j < dim; ++j) negT0(i, j) = -T0(i, j);
132 const bool euler = (method ==
"euler");
133 if (!euler && method !=
"ssolve")
134 throw InputError(
"fes_map_moments: unknown method, use ssolve or euler");
139 for (std::size_t i = 0; i < dim; ++i) {
141 if (d > dmax) dmax = d;
146 const std::vector<T> v1 = euler ?
fes_map_euler(pie, T0, dt, tol, iter_max)
147 : detail::solve_row(negT0, pie);
148 const std::vector<T> v2 = euler ?
fes_map_euler(v1, T0, dt, tol, iter_max)
149 : detail::solve_row(negT0, v1);
150 const std::vector<T> v3 = euler ?
fes_map_euler(v2, T0, dt, tol, iter_max)
151 : detail::solve_row(negT0, v2);
152 const std::vector<T> v2T1 =
vecmul(v2, T1);
153 const std::vector<T> v4 = euler ?
fes_map_euler(v2T1, T0, dt, tol, iter_max)
154 : detail::solve_row(negT0, v2T1);
161 for (std::size_t i = 0; i < dim; ++i) {
173 for (std::size_t i = 0; i < dim; ++i) A(i, dim - 1) = one;
174 std::vector<T> rhs(dim);
175 for (std::size_t i = 0; i < dim; ++i) rhs[i] = pie[i] - phi[i];
177 const std::vector<T> y = detail::solve_row(A, rhs);
178 const std::vector<T> yT1 =
vecmul(y, T1);
180 for (
const T& x : yT1) s += x;
Steady-state distribution of a continuous-time Markov chain.
The exception types the port throws.
Dense linear algebra over the templated number type: products, identity, inverse, and powers.
LU factorization with partial pivoting, templated on the number type.
Markovian arrival process descriptors: stationary vectors, rate, moments, autocorrelation and the ind...
Dense matrix and non-owning view.
FesMapMoments< T > fes_map_moments(const mam::Map< T > &map, const std::string &method="ssolve", double step_safety=0.1, double tol=1e-12, std::size_t iter_max=1000000)
Moments and index of dispersion of an inter-departure MAP.
std::vector< T > fes_map_euler(const std::vector< T > &v, const Matrix< T > &T0, const T &dt, double tol, std::size_t iter_max)
Approximate v (-T0)^-1 by the trapezoid rule with the Euler propagator.
Matrix< T > map_infgen(const Map< T > &m)
Generator of the underlying phase process, D0 + D1.
std::vector< T > ctmc_solve(const Matrix< T > &Qin)
Steady-state distribution of a continuous-time Markov chain.
std::vector< T > vecmul(const std::vector< T > &v, const Matrix< T > &A)
Row vector times matrix, v A.
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.
Descriptors a MAP(2) is fitted against.
A MAP as the pair of matrices (D0, D1).