5#ifndef LINE_API_MAM_MFQ_SOJOURN_H
6#define LINE_API_MAM_MFQ_SOJOURN_H
87 const Matrix<T>& Q0,
bool transToPH,
const T& prec) {
89 "mfq_sojourn requires transcendental arithmetic");
90 using namespace mfq_detail;
92 const std::size_t N = Q.
rows();
93 if (Q.
cols() != N || Rin.
rows() != N || Rin.
cols() != N || Rout.
rows() != N ||
95 throw InputError(
"mfq_sojourn: Q, Rin and Rout must be square and of equal order");
99 const std::size_t Np = s.
ini.size();
100 if (Np == 0)
throw NumericError(
"mfq_sojourn: the fluid model has no up-drift states");
103 const std::vector<T> iniKi =
vecmul(s.
ini, negKinv);
110 for (std::size_t j = 0; j < N; ++j) lambda += a[j] + b[j];
112 if (lambda <= zero)
throw NumericError(
"mfq_sojourn: non-positive fluid arrival rate");
115 const std::size_t n = N * Np;
117 std::vector<T> delta(Np);
118 for (std::size_t i = 0; i < Np; ++i) {
119 delta[i] = iniKi[i] / lambda;
120 if (delta[i] == zero)
122 "mfq_sojourn: the PH similarity is singular on this model; ask for the ME "
123 "representation instead");
128 out.
alpha.assign(n, zero);
129 for (std::size_t j = 0; j < N; ++j)
130 for (std::size_t i = 0; i < Np; ++i) out.
alpha[j * Np + i] = cloRin(i, j) * delta[i];
133 for (std::size_t i = 0; i < Np; ++i)
134 for (std::size_t k = 0; k < Np; ++k) Mi(i, k) = s.
K(k, i) * delta[k] / delta[i];
136 for (std::size_t j1 = 0; j1 < N; ++j1)
137 for (std::size_t j2 = 0; j2 < N; ++j2)
138 for (std::size_t i1 = 0; i1 < Np; ++i1)
139 for (std::size_t i2 = 0; i2 < Np; ++i2) {
140 T v = Rout(j1, j2) * Mi(i1, i2);
141 if (i1 == i2) v += Q(j1, j2);
142 out.
A(j1 * Np + i1, j2 * Np + i2) = v;
147 std::vector<T> clovec(n, zero);
148 for (std::size_t j = 0; j < N; ++j)
149 for (std::size_t i = 0; i < Np; ++i) clovec[j * Np + i] = W(i, j);
153 std::vector<T> rep(n, zero);
154 for (std::size_t j = 0; j < N; ++j)
155 for (std::size_t i = 0; i < Np; ++i) rep[j * Np + i] = s.
ini[i] / lambda;
159 for (std::size_t j1 = 0; j1 < N; ++j1)
160 for (std::size_t j2 = 0; j2 < N; ++j2)
161 for (std::size_t i1 = 0; i1 < Np; ++i1)
162 for (std::size_t i2 = 0; i2 < Np; ++i2) {
163 T v = Rout(j1, j2) * s.
K(i1, i2);
164 if (i1 == i2) v += Q(j2, j1);
165 Mid(j1 * Np + i1, j2 * Np + i2) = v;
NumericError(const std::string &what)
The exception types the port throws.
Dense linear algebra over the templated number type: products, identity, inverse, and powers.
Dense matrix and non-owning view.
Core of the Markovian fluid queue: the fundamental matrices Psi, K, U and the matrix-exponential stat...
Marked MAP (MMAP) algebra: per-class rates, class probabilities, superposition, normalization and sca...
MeRepresentation< T > mfq_sojourn(const Matrix< T > &Q, const Matrix< T > &Rin, const Matrix< T > &Rout, const Matrix< T > &Q0, bool transToPH, const T &prec)
Sojourn time of a drop in a Markov-modulated fluid queue.
GeneralFluidSolution< T > mfq_general_solve(const Matrix< T > &Q, const Matrix< T > &R, const Matrix< T > &Q0, const T &prec)
Stationary law of a general Markovian fluid model, pi(x) = ini exp(K x) clo above level zero plus the...
Matrix< T > mfq_transform_to_ones(const std::vector< T > &v)
The similarity transformation B with B v = e, for a non-negative column vector v.
std::vector< T > vecmul(const std::vector< T > &v, const Matrix< T > &A)
Row vector times matrix, v A.
Matrix< T > inverse(const Matrix< T > &A)
Inverse by LU with one factorization and n back substitutions.
Matrix< T > matmul(const Matrix< T > &A, const Matrix< T > &B)
Matrix product A B.
Number-type abstraction for the templated API port.
Stationary matrix-exponential solution of a general Markovian fluid model.
Matrix< T > K
matrix exponent of the density, Np x Np
std::vector< T > mass0
P(level 0, state j), length N.
std::vector< T > ini
initial vector of the density, length Np
Matrix< T > clo
closing matrix of the density, Np x N
A matrix-exponential or phase-type representation (alpha, A).
Matrix< T > A
generator-like matrix exponent
std::vector< T > alpha
initial row vector