206 const Matrix<T>& mu,
const std::vector<double>& nservers,
207 double tol = 1e-6, std::size_t maxiter = 1000,
double wtol = 1e-4) {
209 "pfqn_qdlin requires transcendental arithmetic");
210 const std::size_t M =
static_cast<std::size_t
>(L.
rows());
211 const std::size_t K =
static_cast<std::size_t
>(L.
cols());
213 throw InputError(
"pfqn_qdlin: the population vector must have one entry per class");
214 if (!Z.empty() && Z.size() != K)
215 throw InputError(
"pfqn_qdlin: the think-time vector must have one entry per class");
216 if (!nservers.empty() && nservers.size() != M)
217 throw InputError(
"pfqn_qdlin: the server-count vector must have one entry per station");
218 for (std::size_t r = 0; r < K; ++r)
221 "pfqn_qdlin: an infinite population is not supported, closed classes only");
234 for (std::size_t r = 0; r < K; ++r) Ntot += N[r];
238 bool hasDelay =
false;
239 for (std::size_t r = 0; r < K && !Z.empty(); ++r)
241 const std::size_t off = hasDelay ? 1 : 0;
242 const std::size_t Ms = M + off;
245 std::vector<double> srv(Ms, 1.0);
246 std::vector<char> isdelay(Ms, 0);
248 for (std::size_t r = 0; r < K; ++r) ST(0, r) = Z[r];
249 srv[0] = std::numeric_limits<double>::infinity();
252 for (std::size_t k = 0; k < M; ++k) {
253 for (std::size_t r = 0; r < K; ++r) ST(k + off, r) = L(k, r);
254 srv[k + off] = nservers.empty() ? 1.0 : nservers[k];
258 const std::size_t smax =
static_cast<std::size_t
>(mu.
cols());
260 for (std::size_t k = 0; k < M; ++k)
261 for (std::size_t j = 0; j < smax; ++j) muFull(k + off, j) = mu(k, j);
264 std::vector<std::size_t> nnz;
265 for (std::size_t r = 0; r < K; ++r)
271 const T share = T(one / Msf);
272 for (std::size_t r : nnz)
273 for (std::size_t k = 0; k < Ms; ++k) Q(k, r) = T(share * N[r]);
274 std::vector<T> X(K, zero);
275 for (std::size_t r = 0; r < K; ++r) {
277 for (std::size_t k = 0; k < Ms; ++k) col += ST(k, r);
282 for (std::size_t r : nnz)
283 for (std::size_t k = 0; k < Ms; ++k)
284 Umat(k, r) = std::isfinite(srv[k])
286 : T(ST(k, r) * X[r]);
288 std::vector<Matrix<T>> gamma(K,
Matrix<T>(Ms, K, zero));
291 const double omicron = 0.5;
294 const double maxSweep = std::sqrt(
static_cast<double>(maxiter));
295 const std::size_t maxTotiter = std::min<std::size_t>(maxiter, 10000);
299 std::size_t outerIter = 0;
300 while (
static_cast<double>(outerIter) < maxSweep && out.
iter <= maxTotiter) {
301 if (outerIter >= 2) {
303 for (std::size_t k = 0; k < Ms; ++k)
304 for (std::size_t r = 0; r < K; ++r)
307 if (gap <= tol)
break;
313 bool exhausted =
false;
314 for (std::size_t s = 0; s < K && !exhausted; ++s) {
316 std::vector<T> Ns = N;
317 Ns[s] = T(Ns[s] - one);
318 const T shrink = T((Ntot - one) / Ntot);
320 for (std::size_t k = 0; k < Ms; ++k)
321 for (std::size_t r = 0; r < K; ++r) Qs(k, r) = T(Qs(k, r) * shrink);
322 std::vector<T> Xs = X;
323 for (std::size_t r = 0; r < K; ++r) Xs[r] = T(Xs[r] * shrink);
325 std::size_t iterS = 0;
327 while (
static_cast<double>(iterS) <= maxSweep) {
330 for (std::size_t k = 0; k < Ms; ++k)
331 for (std::size_t r = 0; r < K; ++r)
334 if (gap <= tol)
break;
338 const std::vector<T> XsPrev = Xs;
340 detail::qdlin_forward(ST, srv, isdelay, muFull, gamma, QsPrev, Ns, nnz, wtol, W,
343 if (out.
iter >= maxTotiter) {
348 for (std::size_t r : nnz) {
350 for (std::size_t k = 0; k < Ms; ++k) wsum += W(k, r);
355 Xs[r] = T(om * Ns[r] / wsum + omc * XsPrev[r]);
359 for (std::size_t k = 0; k < Ms; ++k)
360 Qs(k, r) = T(om * Xs[r] * W(k, r) + omc * QsPrev(k, r));
366 for (std::size_t k = 0; k < Ms; ++k) {
367 T a = zero, b = zero;
368 for (std::size_t r = 0; r < K; ++r) {
372 gamma[s](k, 0) = T(a / (Ntot - one) - b / Ntot);
375 for (std::size_t k = 0; k < Ms; ++k) gamma[s](k, 0) = zero;
378 if (exhausted)
break;
381 std::size_t innerIter = 0;
383 while (
static_cast<double>(innerIter) <= maxSweep) {
384 if (innerIter >= 2) {
386 for (std::size_t k = 0; k < Ms; ++k)
387 for (std::size_t r = 0; r < K; ++r)
390 if (gap <= tol)
break;
394 const std::vector<T> Xprev = X;
397 detail::qdlin_forward(ST, srv, isdelay, muFull, gamma, Qprev, N, nnz, wtol, W, STeff);
399 if (out.
iter >= maxTotiter) {
404 for (std::size_t r : nnz) {
406 for (std::size_t k = 0; k < Ms; ++k) wsum += W(k, r);
412 X[r] = T(om * N[r] / wsum + omc * Xprev[r]);
416 for (std::size_t k = 0; k < Ms; ++k) {
417 Q(k, r) = T(om * X[r] * W(k, r) + omc * Qprev(k, r));
419 Umat(k, r) = T(om * STeff(k, r) * X[r] + omc * Uprev(k, r));
423 if (exhausted)
break;
428 for (std::size_t k = 0; k < Ms; ++k) {
429 if (isdelay[k])
continue;
431 for (std::size_t r = 0; r < K; ++r) usum += Umat(k, r);
434 for (std::size_t r = 0; r < K; ++r) denom += T(STeff(k, r) * X[r]);
436 for (std::size_t r = 0; r < K; ++r)
438 Umat(k, r) = T(STeff(k, r) * X[r] / denom);
447 const bool iteratedU = !mu.
empty();
448 for (std::size_t r : nnz) {
450 for (std::size_t k = 0; k < M; ++k) {
451 const std::size_t ks = k + off;
452 out.
Q(k, r) = Q(ks, r);
453 out.
U(k, r) = iteratedU ? Umat(ks, r)
454 : (std::isfinite(srv[ks])
455 ? T(ST(ks, r) * X[r] /
457 : T(ST(ks, r) * X[r]));
459 ? T(Q(ks, r) / Tput(ks, r))