58 const std::vector<AmvaSched>& type,
double tol = 1e-6,
60 const std::size_t M = L.
rows(), R = L.
cols();
61 if (N.size() != R)
throw InputError(
"pfqn_lcp: L and N disagree on the class count");
62 if (!Z.empty() && Z.size() != R)
throw InputError(
"pfqn_lcp: Z has the wrong length");
63 if (!type.empty() && type.size() != M)
throw InputError(
"pfqn_lcp: type has the wrong length");
75 if (QN0.rows() != M || QN0.cols() != R)
76 throw InputError(
"pfqn_lcp: QN0 has the wrong shape");
79 for (std::size_t i = 0; i < M; ++i)
80 for (std::size_t s = 0; s < R; ++s)
84 for (std::size_t it = 1; it <= maxiter; ++it) {
88 for (std::size_t cls = 0; cls < R; ++cls) {
91 for (std::size_t i = 0; i < M; ++i) {
98 T ctot = Z.empty() ? zero : Z[cls];
99 for (std::size_t i = 0; i < M; ++i) {
100 CN(i, cls) = L(i, cls);
101 if (L(i, cls) == zero)
continue;
103 for (std::size_t s = 0; s < R; ++s) {
105 if (fcfs && s != cls)
106 CN(i, cls) += L(i, s) * r.
QN(i, s);
108 CN(i, cls) += L(i, cls) * r.
QN(i, s);
112 if (ctot == zero)
throw NumericError(
"pfqn_lcp: zero total residence time");
113 r.
XN[cls] = N[cls] / ctot;
115 for (std::size_t cls = 0; cls < R; ++cls)
116 for (std::size_t i = 0; i < M; ++i) {
117 r.
QN(i, cls) = r.
XN[cls] * CN(i, cls);
118 r.
UN(i, cls) = r.
XN[cls] * L(i, cls);
122 for (std::size_t cls = 0; cls < R; ++cls) {
123 if (N[cls] == zero)
continue;
124 for (std::size_t i = 0; i < M; ++i) {
125 if (Qprev(i, cls) == zero) {
126 if (r.
QN(i, cls) == zero)
continue;
127 delta = std::numeric_limits<double>::infinity();
133 if (d > delta) delta = d;
142 for (std::size_t cls = 0; cls < R; ++cls)
143 for (std::size_t i = 0; i < M; ++i)
144 r.
RN(i, cls) = (N[cls] == zero) ? zero : r.
QN(i, cls) / r.
XN[cls];
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.