84 double tol = 1e-6, std::size_t maxiter = 1000,
87 "pfqn_tay requires transcendental arithmetic: it iterates to a tolerance, so "
88 "its answer is a fixed point only to within tol");
89 const std::size_t M = L.
rows(), R = L.
cols();
90 if (N.size() != R)
throw InputError(
"pfqn_tay: L and N disagree on the class count");
91 if (!Z.empty() && Z.size() != R)
throw InputError(
"pfqn_tay: Z has the wrong length");
95 out.
XN.assign(R, zero);
99 if (M == 0)
return out;
103 std::vector<std::size_t> act;
104 for (std::size_t r = 0; r < R; ++r)
105 if (N[r] > zero) act.push_back(r);
106 if (act.empty())
return out;
107 if (act.size() < R) {
109 std::vector<T> Na(act.size(), zero), Za(act.size(), zero);
110 for (std::size_t a = 0; a < act.size(); ++a) {
111 for (std::size_t m = 0; m < M; ++m) La(m, a) = L(m, act[a]);
113 Za[a] = Z.empty() ? zero : Z[act[a]];
116 for (std::size_t a = 0; a < act.size(); ++a) {
117 out.
XN[act[a]] = sub.XN[a];
118 for (std::size_t m = 0; m < M; ++m) {
119 out.
QN(m, act[a]) = sub.QN(m, a);
120 out.
UN(m, act[a]) = sub.UN(m, a);
121 out.
RN(m, act[a]) = sub.RN(m, a);
132 for (std::size_t m = 0; m < M; ++m)
133 for (std::size_t r = 0; r < R; ++r) QN(m, r) = N[r] / Md;
135 if (QN0.rows() != M || QN0.cols() != R)
136 throw InputError(
"pfqn_tay: QN0 has the wrong shape");
140 for (std::size_t r = 0; r < R; ++r) {
141 T Lsum = zero, Qsum = zero;
142 for (std::size_t m = 0; m < M; ++m) {
146 const T den = (Z.empty() ? zero : Z[r]) + Lsum * (one + Qsum);
147 out.
XN[r] = (den == zero) ? zero : N[r] / den;
151 for (std::size_t it = 1; it <= maxiter; ++it) {
157 for (std::size_t m = 0; m < M; ++m)
158 for (std::size_t r = 0; r < R; ++r)
159 B(m, r) = one / (one + L(m, r) * out.
XN[r] / N[r]);
163 std::vector<T> den(R, zero);
164 for (std::size_t j = 0; j < R; ++j) {
166 for (std::size_t m = 0; m < M; ++m) s += B(m, j) * QN(m, j) * (one + QN(m, j));
167 den[j] = s + (Z.empty() ? zero : Z[j]) * out.
XN[j];
172 for (std::size_t j = 0; j < R; ++j)
173 for (std::size_t c = 0; c < R; ++c) {
175 for (std::size_t m = 0; m < M; ++m) s += B(m, c) * QN(m, j) * QN(m, c);
179 for (std::size_t m = 0; m < M; ++m)
180 for (std::size_t k = 0; k < R; ++k) {
182 std::vector<T> b(R, zero);
183 for (std::size_t j = 0; j < R; ++j) {
187 "pfqn_tay: the elasticity system is singular at station " +
188 std::to_string(m + 1) +
", class " + std::to_string(j + 1) +
189 ": the class carries no queue anywhere and no think time");
190 for (std::size_t c = 0; c < R; ++c)
191 if (c != j) A(j, c) = C(j, c) / den[j];
192 const T delta = (j == k) ? one : zero;
193 b[j] = -((delta + QN(m, j)) * B(m, k) * QN(m, k) / den[j]);
196 for (std::size_t r = 0; r < R; ++r) Qarr(m, k * R + r) = QN(m, k) + E[r];
199 for (std::size_t r = 0; r < R; ++r)
200 for (std::size_t m = 0; m < M; ++m) {
202 for (std::size_t k = 0; k < R; ++k) s += Qarr(m, k * R + r);
203 out.
RN(m, r) = L(m, r) * (one + s);
205 for (std::size_t r = 0; r < R; ++r) {
206 T s = (Z.empty() ? zero : Z[r]);
207 for (std::size_t m = 0; m < M; ++m) s += out.
RN(m, r);
208 out.
XN[r] = (s == zero) ? zero : N[r] / s;
210 for (std::size_t m = 0; m < M; ++m)
211 for (std::size_t r = 0; r < R; ++r) QN(m, r) = out.
RN(m, r) * out.
XN[r];
214 for (std::size_t m = 0; m < M; ++m)
215 for (std::size_t r = 0; r < R; ++r) {
218 if (d > delta) delta = d;
227 for (std::size_t m = 0; m < M; ++m)
228 for (std::size_t r = 0; r < R; ++r) out.
UN(m, r) = L(m, r) * out.
XN[r];