62 const std::vector<AmvaSched>& type,
double tol = 1e-6,
65 const std::size_t M = L.
rows(), R = L.
cols();
66 if (N.size() != R)
throw InputError(
"pfqn_chow: L and N disagree on the class count");
67 if (!Z.empty() && Z.size() != R)
throw InputError(
"pfqn_chow: Z has the wrong length");
68 if (!type.empty() && type.size() != M)
throw InputError(
"pfqn_chow: type has the wrong length");
74 std::vector<T> Qtot(M, zero);
75 for (std::size_t i = 0; i < M; ++i)
76 for (std::size_t s = 0; s < R; ++s) Qtot[i] += base.
QN(i, s);
79 for (std::size_t cls = 0; cls < R; ++cls) {
80 if (N[cls] == zero)
continue;
81 std::vector<T> Nalt(N);
84 for (std::size_t i = 0; i < M; ++i) {
86 for (std::size_t s = 0; s < R; ++s) qalt += alt.
QN(i, s);
90 if (ref > zero) theta(i, cls) = delta / ref;
101 if (M == 0)
return r;
103 if (QN0.rows() != M || QN0.cols() != R)
104 throw InputError(
"pfqn_chow: QN0 has the wrong shape");
107 for (std::size_t i = 0; i < M; ++i)
108 for (std::size_t s = 0; s < R; ++s)
112 for (std::size_t it = 1; it <= maxiter; ++it) {
115 for (std::size_t cls = 0; cls < R; ++cls) {
116 if (N[cls] == zero) {
118 for (std::size_t i = 0; i < M; ++i) {
125 T ctot = Z.empty() ? zero : Z[cls];
126 for (std::size_t i = 0; i < M; ++i) {
127 CN(i, cls) = L(i, cls);
128 if (L(i, cls) == zero)
continue;
130 const T infl = T(one + theta(i, cls));
131 for (std::size_t s = 0; s < R; ++s) {
132 if (fcfs && s != cls)
133 CN(i, cls) += L(i, s) * r.
QN(i, s) * infl;
135 CN(i, cls) += L(i, cls) * r.
QN(i, s) * infl;
138 if (CN(i, cls) < L(i, cls)) CN(i, cls) = L(i, cls);
141 if (ctot == zero)
throw NumericError(
"pfqn_chow: zero total residence time");
142 r.
XN[cls] = N[cls] / ctot;
144 for (std::size_t cls = 0; cls < R; ++cls)
145 for (std::size_t i = 0; i < M; ++i) {
146 r.
QN(i, cls) = r.
XN[cls] * CN(i, cls);
147 r.
UN(i, cls) = r.
XN[cls] * L(i, cls);
151 for (std::size_t cls = 0; cls < R; ++cls) {
152 if (N[cls] == zero)
continue;
153 for (std::size_t i = 0; i < M; ++i) {
154 if (Qprev(i, cls) == zero) {
155 if (r.
QN(i, cls) == zero)
continue;
156 delta = std::numeric_limits<double>::infinity();
161 if (d > delta) delta = d;
170 for (std::size_t cls = 0; cls < R; ++cls)
171 for (std::size_t i = 0; i < M; ++i)
172 r.
RN(i, cls) = (N[cls] == zero) ? zero : r.
QN(i, cls) / r.
XN[cls];
AmvaResult< T > pfqn_chow(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z, const std::vector< AmvaSched > &type, double tol=1e-6, std::size_t maxiter=1000, const Matrix< T > &QN0=Matrix< T >(), ChowVariant variant=ChowVariant::Forward)
Chow Second Approximation (SA) approximate MVA.
AmvaResult< T > pfqn_lcp(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z, const std::vector< AmvaSched > &type, double tol=1e-6, std::size_t maxiter=1000, const Matrix< T > &QN0=Matrix< T >())
Bard Large Customer Population (LCP) approximate MVA.