62 const std::vector<std::size_t>& keep) {
63 const std::size_t n = Q.
rows();
64 if (Q.
cols() != n)
throw InputError(
"ctmc_pseudostochcomp: generator is not square");
67 std::vector<std::size_t> I = keep;
69 for (std::size_t i = 0; i < (n + 1) / 2; ++i) I.push_back(i);
71 std::vector<bool> kept(n,
false);
72 for (std::size_t i = 0; i < I.size(); ++i) {
73 if (I[i] >= n)
throw InputError(
"ctmc_pseudostochcomp: a retained index is out of range");
76 std::vector<std::size_t> Ic;
77 for (std::size_t i = 0; i < n; ++i)
78 if (!kept[i]) Ic.push_back(i);
79 if (Ic.empty())
throw InputError(
"ctmc_pseudostochcomp: the complement set is empty");
81 const std::size_t nk = I.size(), nd = Ic.size();
87 for (std::size_t a = 0; a < nk; ++a) {
88 for (std::size_t b = 0; b < nk; ++b) r.
Q11(a, b) = Q(I[a], I[b]);
89 for (std::size_t b = 0; b < nd; ++b) r.
Q12(a, b) = Q(I[a], Ic[b]);
91 for (std::size_t a = 0; a < nd; ++a) {
92 for (std::size_t b = 0; b < nk; ++b) r.
Q21(a, b) = Q(Ic[a], I[b]);
93 for (std::size_t b = 0; b < nd; ++b) r.
Q22(a, b) = Q(Ic[a], Ic[b]);
99 std::vector<T> y(nk, zero);
101 for (std::size_t b = 0; b < nk; ++b) {
103 for (std::size_t a = 0; a < nd; ++a) acc += pie[Ic[a]] * r.
Q21(a, b);
107 if (sy == zero)
throw NumericError(
"ctmc_pseudostochcomp: no flow returns to the retained set");
108 for (std::size_t b = 0; b < nk; ++b) y[b] = T(y[b] / sy);
112 for (std::size_t a = 0; a < nk; ++a) {
114 for (std::size_t b = 0; b < nd; ++b) out += r.
Q12(a, b);
115 for (std::size_t b = 0; b < nk; ++b) r.
Tm(a, b) = T(out * y[b]);
119 for (std::size_t a = 0; a < nk; ++a)
120 for (std::size_t b = 0; b < nk; ++b) r.
S(a, b) = T(r.
S(a, b) + r.
Tm(a, b));