233 using namespace etaqa_detail;
235 const std::size_t m = A.
rows();
236 const std::size_t dega = A.
cols() / m - 1;
240 std::size_t mb = 0, degb = 0;
248 if ((B.
cols() - mb) % m != 0)
249 throw InputError(
"MG1_pi_ETAQA: matrix B has an incorrect number of columns");
250 degb = (B.
cols() - mb) / m;
253 if (C0in.empty() && mb != m)
255 "MG1_pi_ETAQA: the Boundary option must be used since a dimension of B0 is not "
257 if (!C0in.empty() && (C0in.rows() != m || C0in.cols() != mb))
258 throw InputError(
"MG1_pi_ETAQA: the boundary parameter value has an incorrect dimension");
261 const std::vector<double> brs =
rowsums(B);
263 for (
double x : brs) tot += x;
264 if (tot > 1e-12 && (tot -
static_cast<double>(mb)) < 1e-12) {
265 for (std::size_t i = 0; i < mb; ++i) B(i, i) -= 1.0;
266 for (std::size_t i = 0; i < m; ++i) A(i, m + i) -= 1.0;
273 "MG1_pi_ETAQA: the Markov chain characterized by A is not positive recurrent (drift = " +
274 std::to_string(d.
value) +
")");
277 std::vector<Matrix<double>> Shat;
278 Shat.push_back(cols_of(B, mb + (degb - 1) * m, mb + degb * m));
279 for (std::size_t i = degb; i-- > 1;) {
281 madd(cols_of(B, mb + (i - 1) * m, mb + i * m),
matmul(Shat.front(), G));
282 Shat.insert(Shat.begin(), temp);
288 "MG1_pi_ETAQA: the number of repetitive state blocks is less than 2, this is not an "
289 "irreducible Markov chain");
290 std::vector<Matrix<double>> S;
291 S.push_back(Ab[dega]);
292 for (std::size_t i = dega; i-- > 1;) {
294 S.insert(S.begin(), temp);
299 std::vector<Matrix<double>> secondp;
300 secondp.push_back(cols_of(B, 0, mb));
301 secondp.push_back(C0);
302 secondp.push_back(zmb);
308 std::vector<Matrix<double>> thirdp;
309 thirdp.push_back(
madd(cols_of(B, mb, mb + m),
matmul(Shat[1], G)));
310 thirdp.push_back(
madd(Ab[1],
matmul(S[1], G)));
311 thirdp.push_back(zmm);
316 if (degb == 2) Bsum = cols_of(B, mb + m, mb + 2 * m);
318 for (std::size_t i = 2; i <= degb - 1; ++i) {
319 Bsum =
madd(Bsum, cols_of(B, mb + (i - 1) * m, mb + i * m));
320 Shat_sum =
madd(Shat_sum, Shat[i]);
322 Bsum =
madd(Bsum, cols_of(B, mb + (degb - 1) * m, B.
cols()));
327 for (std::size_t i = 2; i <= dega - 1; ++i) {
328 Ssum =
madd(Ssum, S[i]);
329 Asum =
madd(Asum, Ab[i]);
331 Asum =
madd(Asum, Ab[dega]);
332 }
else if (dega == 2) {
333 Asum =
madd(Asum, Ab[dega]);
336 "MG1_pi_ETAQA: the number of repetitive state blocks is less than 3, the Markov chain "
340 std::vector<Matrix<double>> fourthp;
341 fourthp.push_back(
madd(Bsum,
matmul(Shat_sum, G)));
342 fourthp.push_back(
madd(Asum,
matmul(Ssum, G)));
346 std::vector<Matrix<double>> xparts;
347 xparts.push_back(Secondc);
348 xparts.push_back(Thirdc);
349 xparts.push_back(Fourthc);
354 const std::size_t n = mb + 2 * m;
355 std::size_t drop = n - 1;
356 for (std::size_t i = 0; i < n; ++i) {
362 Xtemp = drop_col(Xtemp, drop);
364 std::vector<Matrix<double>> xnewp;
365 xnewp.push_back(Firstc);
366 xnewp.push_back(Xtemp);
369 std::vector<double> rside(n, 0.0);
371 return right_divide(rside, Xnew);
383 const std::vector<double>& pi, std::size_t n,
385 using namespace etaqa_detail;
387 const std::size_t m = A.
rows();
388 const std::size_t dega = A.
cols() / m - 1;
392 std::size_t mb = 0, degb = 0;
400 if ((B.
cols() - mb) % m != 0)
401 throw InputError(
"MG1_qlen_ETAQA: matrix B has an incorrect number of columns");
402 degb = (B.
cols() - mb) / m;
404 if (C0in.empty() && mb != m)
406 "MG1_qlen_ETAQA: the Boundary option must be used since the column size of B0 is not "
408 if (!C0in.empty() && (C0in.rows() != m || C0in.cols() != mb))
409 throw InputError(
"MG1_qlen_ETAQA: the boundary parameter value has an incorrect dimension");
412 for (
double x : pi) mass += x;
413 if (std::fabs(mass - 1.0) > 1e-10)
414 throw InputError(
"MG1_qlen_ETAQA: the input probability vector does not sum up to 1");
415 if ((pi.size() - mb) % m != 0)
417 "MG1_qlen_ETAQA: the probability vector has an incorrect number of columns");
419 const std::vector<double> pi0(pi.begin(), pi.begin() + mb);
420 const std::vector<double> pi1(pi.begin() + mb, pi.begin() + mb + m);
421 const std::vector<double> pistar(pi.begin() + mb + m, pi.begin() + mb + 2 * m);
425 for (std::size_t i = 1; i <= dega; ++i) Asum =
madd(Asum, Ab[i]);
427 for (std::size_t i = 3; i <= dega; ++i)
428 F11 =
madd(F11,
mscale(Ab[i],
static_cast<double>(i - 1)));
430 for (std::size_t i = 0; i < m; ++i) {
431 for (std::size_t j = 0; j + 1 < m; ++j) lsleft(i, j) = Asum(i, j);
433 for (std::size_t j = 0; j < m; ++j) s += F11(i, j) - Ab[0](i, j);
434 lsleft(i, m - 1) = s;
438 std::vector<Matrix<double>> Fhat0j;
439 Fhat0j.push_back(cols_of(B, mb + (degb - 1) * m, B.
cols()));
440 for (std::size_t j = degb; j-- > 1;)
441 Fhat0j.insert(Fhat0j.begin(),
442 madd(cols_of(B, mb + (j - 1) * m, mb + j * m), Fhat0j.front()));
446 std::vector<Matrix<double>> F0j;
447 F0j.push_back(Ab[dega]);
448 for (std::size_t j = dega; j-- > 2;) F0j.insert(F0j.begin(),
madd(Ab[j], F0j.front()));
450 std::vector<std::vector<double>> r;
454 std::vector<Matrix<double>> frestsaver, fcrestsaver;
455 for (std::size_t l = 1; l <= n; ++l) {
457 for (std::size_t j = 2; j <= dega; ++j)
458 t1 =
madd(t1,
mscale(Ab[j], std::pow(
static_cast<double>(j),
static_cast<double>(l))));
459 frestsaver.push_back(t1);
461 for (std::size_t j = 1; j <= dega; ++j)
464 std::pow(
static_cast<double>(j),
static_cast<double>(l))));
465 fcrestsaver.push_back(t2);
468 for (std::size_t k = 1; k <= n; ++k) {
469 const double dk =
static_cast<double>(k);
471 for (std::size_t j = 1; j <= degb; ++j)
472 fhatkM =
madd(fhatkM,
mscale(cols_of(B, mb + (j - 1) * m, mb + j * m),
473 std::pow(
static_cast<double>(j + 1), dk)));
474 const std::vector<double> fhatk = vmul(pi0, fhatkM);
477 for (std::size_t j = 2; j <= dega; ++j)
478 fkM =
madd(fkM,
mscale(Ab[j], std::pow(
static_cast<double>(j + 1), dk)));
479 fkM =
madd(
mscale(Ab[1], std::pow(2.0, dk)), fkM);
480 const std::vector<double> fk = vmul(pi1, fkM);
482 std::vector<double> frest(m, 0.0);
483 for (std::size_t l = 1; l <= k; ++l) {
485 const std::vector<double> t = vmul(r[k - l], M);
486 for (std::size_t j = 0; j < m; ++j) frest[j] += bino(k, l) * t[j];
489 std::vector<double> bk(m, 0.0);
490 for (std::size_t j = 0; j < m; ++j) bk[j] = -fhatk[j] - fk[j] - frest[j];
493 for (std::size_t j = 2; j <= degb; ++j)
494 fchatkM =
madd(fchatkM,
mscale(Fhat0j[j - 1], std::pow(
static_cast<double>(j), dk)));
495 const double fchatk = vmul_e(pi0, fchatkM);
498 for (std::size_t j = 1; j + 1 <= dega; ++j)
501 mscale(F0j[j - 1], std::pow(
static_cast<double>(j + 1), dk)));
502 const double fck = vmul_e(pi1, fckM);
505 for (std::size_t l = 1; l <= k; ++l)
506 fcrest += bino(k, l) * vmul_e(r[k - l], fcrestsaver[l - 1]);
508 const double ck = -fchatk - fck - fcrest;
510 std::vector<double> rside(m, 0.0);
511 for (std::size_t j = 0; j + 1 < m; ++j) rside[j] = bk[j];
513 r.push_back(right_divide(rside, lsleft));
516 return vsum(r.back()) + vsum(pi1);
562 using namespace etaqa_detail;
564 const std::size_t m = R.
rows();
565 const std::size_t mb = B.
cols();
566 if ((B.
rows() - mb) % m != 0)
567 throw InputError(
"GIM1_pi_ETAQA: input matrix B has an incorrect number of rows");
568 const std::size_t degb = (B.
rows() - mb) / m;
569 if (A.rows() % m != 0)
570 throw InputError(
"GIM1_pi_ETAQA: input matrix A has an incorrect number of rows");
571 const std::size_t dega = A.rows() / m - 1;
575 bool all_cols_negative =
true;
576 for (std::size_t j = 0; j < m && all_cols_negative; ++j) {
578 for (std::size_t i = 0; i < m; ++i)
579 if (temp0(i, j) < -100.0 * 2.220446049250313e-16) any =
true;
580 all_cols_negative = any;
582 if (all_cols_negative)
584 "GIM1_pi_ETAQA: the spectral radius of R is not below 1, GIM1 is not positive "
589 if (B0in.rows() != mb)
590 throw InputError(
"GIM1_pi_ETAQA: Boundary has an incorrect number of rows");
591 if (B0in.cols() != m)
592 throw InputError(
"GIM1_pi_ETAQA: Boundary has an incorrect number of columns");
596 for (std::size_t i = 0; i < m; ++i)
597 for (std::size_t j = 0; j < A.cols(); ++j) B0(i, j) = A(i, j);
602 for (std::size_t i = 0; i < mb; ++i)
603 for (std::size_t j = 0; j < B.
cols(); ++j) Btop(i, j) = B(i, j);
605 const std::vector<double> trs =
rowsums(test);
607 for (
double x : trs) tot += x - 1.0;
608 if (std::fabs(tot) < 1e-10) {
609 for (std::size_t i = 0; i < mb; ++i) B(i, i) -= 1.0;
610 for (std::size_t i = 0; i < m; ++i) A(m + i, i) -= 1.0;
620 for (std::size_t i = 2; i <= degb; ++i) {
621 tempsum =
madd(tempsum,
matmul(temp, vblock_after(B, mb, m, i)));
624 std::vector<Matrix<double>> secondp;
625 secondp.push_back(Btop);
626 secondp.push_back(vblock_after(B, mb, m, 1));
627 secondp.push_back(tempsum);
633 for (std::size_t i = 2; i <= dega; ++i) {
637 std::vector<Matrix<double>> thirdp;
638 thirdp.push_back(B0);
639 thirdp.push_back(Ab[1]);
640 thirdp.push_back(tempsum);
646 for (std::size_t i = 2; i <= dega; ++i) {
650 std::vector<Matrix<double>> fourthp;
652 fourthp.push_back(Ab[0]);
653 fourthp.push_back(
madd(
madd(Ab[0], Ab[1]), tempsum));
655 Fourthc = cols_of(Fourthc, 0, Fourthc.
cols() - 1);
657 std::vector<Matrix<double>> xparts;
658 xparts.push_back(Firstc);
659 xparts.push_back(Secondc);
660 xparts.push_back(Thirdc);
661 xparts.push_back(Fourthc);
664 std::vector<double> rside(mb + 2 * m, 0.0);
666 return right_divide(rside, X);
680 using namespace etaqa_detail;
682 const std::size_t m = R.
rows();
683 const std::size_t mb = B.
cols();
684 if ((B.
rows() - mb) % m != 0)
685 throw InputError(
"GIM1_qlen_ETAQA: input matrix B has an incorrect number of rows");
686 const std::size_t degb = (B.
rows() - mb) / m;
687 if (A.rows() % m != 0)
688 throw InputError(
"GIM1_qlen_ETAQA: input matrix A has an incorrect number of rows");
689 const std::size_t dega = A.rows() / m - 1;
692 bool all_cols_negative =
true;
693 for (std::size_t j = 0; j < m && all_cols_negative; ++j) {
695 for (std::size_t i = 0; i < m; ++i)
696 if (temp0(i, j) < -100.0 * 2.220446049250313e-16) any =
true;
697 all_cols_negative = any;
699 if (all_cols_negative)
701 "GIM1_qlen_ETAQA: the spectral radius of R is not below 1, GIM1 is not positive "
706 if (B0in.rows() != mb || B0in.cols() != m)
707 throw InputError(
"GIM1_qlen_ETAQA: Boundary has an incorrect dimension");
711 for (std::size_t i = 0; i < m; ++i)
712 for (std::size_t j = 0; j < A.cols(); ++j) B0(i, j) = A(i, j);
715 const std::vector<double> pi0(pi.begin(), pi.begin() + mb);
716 const std::vector<double> pi1(pi.begin() + mb, pi.begin() + mb + m);
717 const std::vector<double> pistar(pi.begin() + mb + m, pi.begin() + mb + 2 * m);
719 if (n == 0)
return 1.0;
722 const double a3 = A(2 % A.rows(), 2 / A.rows());
725 for (std::size_t i = 0; i < mb; ++i)
726 for (std::size_t j = 0; j < B.
cols(); ++j) Btop(i, j) = B(i, j);
728 const std::vector<double> trs =
rowsums(test);
730 for (
double x : trs) tot += x - 1.0;
731 if (std::fabs(tot) < 1e-10) {
732 for (std::size_t i = 0; i < mb; ++i) B(i, i) -= 1.0;
733 for (std::size_t i = 0; i < m; ++i) A(m + i, i) -= 1.0;
740 for (std::size_t i = 2; i <= dega; ++i) {
742 Rpower =
matmul(R, Rpower);
745 std::vector<double> leftr(m, 0.0);
746 if (degb >= 2 && dega >= 2) {
749 const bool loop_runs = dega >= 3;
752 for (std::size_t i = 1; i + 2 <= dega; ++i) {
753 part1 =
madd(part1,
matmul(Rpower, Ab[i + 2]));
754 part2 =
madd(part2,
mscale(
matmul(Rpower, Ab[i + 2]),
static_cast<double>(i)));
755 Rpower =
matmul(R, Rpower);
757 for (std::size_t i = 0; i < m; ++i) {
760 for (std::size_t j = 0; j < m; ++j) s += part1(i, j) + part2(i, j);
764 for (std::size_t j = 0; j < m; ++j) s -= Ab[0](i, j);
767 }
else if (degb == 1 && dega != 1) {
770 for (std::size_t i = 2; i <= dega; ++i) {
772 Rpower =
matmul(R, Rpower);
774 for (std::size_t i = 0; i < m; ++i) {
776 for (std::size_t j = 0; j < m; ++j) s += acc(i, j) - Ab[0](i, j);
781 "GIM1_qlen_ETAQA: the number of A blocks is not enough, this is a reducible Markov "
786 for (std::size_t i = 0; i < m; ++i) {
787 for (std::size_t j = 0; j + 1 < m; ++j) lsleft(i, j) = lsum(i, j);
788 lsleft(i, m - 1) = leftr[i];
791 std::vector<std::vector<double>> r;
794 std::vector<std::vector<double>> reuse;
796 for (std::size_t k = 1; k <= n; ++k) {
797 const double dk =
static_cast<double>(k);
798 std::vector<double> bk(m, 0.0);
800 const std::vector<double> t0 = vmul(pi0, B0);
803 const std::vector<double> t1 = vmul(pi1, M);
804 for (std::size_t j = 0; j < m; ++j) bk[j] = -(std::pow(2.0, dk) * t0[j] + t1[j]);
805 for (std::size_t l = 1; l <= k; ++l) {
807 madd(Ab[1],
mscale(Ab[0], std::pow(2.0,
static_cast<double>(l))));
808 const std::vector<double> t = vmul(r[k - l], Ml);
809 for (std::size_t j = 0; j < m; ++j) bk[j] -= bino(k, l) * t[j];
815 for (std::size_t i = 1; i + 2 <= dega; ++i) {
817 for (std::size_t z = 1; z <= i; ++z) t += std::pow(static_cast<double>(z), dk);
819 Rpower =
matmul(Rpower, R);
821 std::vector<double> col(m, 0.0);
822 for (std::size_t i = 0; i < m; ++i) {
824 for (std::size_t j = 0; j < m; ++j) s += Ab[0](i, j) - tempsum(i, j);
827 reuse.push_back(col);
829 double ck = std::pow(2.0, dk) * vmul_e(pi1, Ab[0]);
832 for (std::size_t i = 2; i <= degb; ++i) {
834 for (std::size_t z = 2; z <= i; ++z) t += std::pow(static_cast<double>(z), dk);
835 tempsum2 =
madd(tempsum2,
mscale(
matmul(Rpower, vblock_after(B, mb, m, i)), t));
836 Rpower =
matmul(R, Rpower);
838 ck -= vmul_e(pi1, tempsum2);
839 for (std::size_t l = 1; l <= k; ++l) {
841 for (std::size_t j = 0; j < m; ++j) s += r[k - l][j] * reuse[l - 1][j];
842 ck += bino(k, l) * s;
845 std::vector<double> rside(m, 0.0);
846 for (std::size_t j = 0; j + 1 < m; ++j) rside[j] = bk[j];
848 r.push_back(right_divide(rside, lsleft));
851 return vsum(r.back()) + vsum(pi1);