219 double tol = 1e-10) {
221 if (phases.empty())
throw InputError(
ErrorKind{
"Argument"},
"ldqbd_censor: phases must give one vector of phase counts per set.");
222 const std::size_t S = phases.size();
223 std::vector<std::size_t> nset(S, 0), setOff(S + 1, 0);
224 for (std::size_t s = 0; s < S; ++s) {
225 if (phases[s].empty())
227 "} must be a non-empty vector of positive integers.");
228 for (std::size_t p : phases[s]) {
231 "} must be a non-empty vector of positive integers.");
234 setOff[s + 1] = setOff[s] + nset[s];
236 const std::size_t n = setOff[S];
240 " but the phase counts add up to " + std::to_string(n) +
".");
243 std::vector<std::map<std::size_t, T>> rows(n);
245 for (std::size_t i = 0; i < n; ++i) {
247 if (d > scale) scale = d;
249 for (std::size_t i = 0; i < n; ++i) {
251 for (std::size_t j = 0; j < n; ++j) {
253 if (v == zero<T>())
continue;
254 if (i != j && v < zero<T>())
255 throw InputError(
ErrorKind{
"Argument"},
"ldqbd_censor: the off-diagonal entries of Q must be nonnegative.");
261 if (bad)
throw InputError(
ErrorKind{
"Argument"},
"ldqbd_censor: the rows of Q must sum to zero.");
265 std::vector<Factor<T>> fac;
266 std::vector<std::vector<std::size_t>> bRows(S);
267 std::vector<std::vector<std::vector<T>>> bVals(S);
268 for (std::size_t k = 0; k + 1 < S; ++k) {
269 const std::size_t o0 = setOff[k], o1 = setOff[k + 1], nk = nset[k];
271 std::map<std::size_t, std::size_t> colPos;
272 for (std::size_t i = 0; i < nk; ++i)
273 for (
const auto& e : rows[o0 + i]) {
274 if (e.first >= o0 && e.first < o1) M(i, e.first - o0) = -e.second;
275 else if (e.first >= o1) colPos[e.first] = 0;
277 check(M, phases[k], k);
278 fac.emplace_back(M, phases[k], k,
false);
279 std::vector<std::size_t> cols;
280 for (
auto& c : colPos) {
281 c.second = cols.size();
282 cols.push_back(c.first);
284 Matrix<T> QkB(nk, cols.size(), zero<T>());
285 for (std::size_t i = 0; i < nk; ++i)
286 for (
const auto& e : rows[o0 + i])
287 if (e.first >= o1) QkB(i, colPos[e.first]) = e.second;
288 for (std::size_t r = o1; r < n; ++r) {
290 for (
const auto& e : rows[r]) {
291 if (e.first >= o0 && e.first < o1 && !(e.second == zero<T>())) {
292 if (v.empty()) v.assign(nk, zero<T>());
293 v[e.first - o0] = e.second;
297 bRows[k].push_back(r);
298 bVals[k].push_back(v);
301 if (!cols.empty() && !bRows[k].empty()) {
302 const Matrix<T> X = fac.back().colsolve(QkB);
303 for (std::size_t i = 0; i < bRows[k].size(); ++i) {
304 const std::vector<T> u =
vecmul(bVals[k][i], X);
305 auto& row = rows[bRows[k][i]];
306 for (std::size_t j = 0; j < cols.size(); ++j) {
307 if (u[j] == zero<T>())
continue;
308 auto it = row.find(cols[j]);
309 if (it == row.end()) row[cols[j]] = u[j];
310 else it->second += u[j];
317 const std::size_t oS = setOff[S - 1], nS = nset[S - 1];
319 for (std::size_t i = 0; i < nS; ++i)
320 for (
const auto& e : rows[oS + i])
321 if (e.first >= oS) MS(i, e.first - oS) = -e.second;
322 check(MS, phases[S - 1], S - 1);
323 const Factor<T> f(MS, phases[S - 1], S - 1,
true);
324 const std::size_t L = f.levels();
329 for (std::size_t i = 0; i < A.
rows(); ++i)
330 for (std::size_t j = 0; j < A.
cols(); ++j) At(j, i) = A(i, j);
331 std::vector<T> e1(A.
rows(), zero<T>());
337 throw NumericError(
ErrorKind{
"Singular"},
"ldqbd_censor: the last level of set " + std::to_string(S) +
338 " has no unique stationary vector; the chain may be reducible.");
340 std::vector<T> pB(n, zero<T>());
341 for (std::size_t i = 0; i < xL.size(); ++i) pB[oS + f.off[L - 1] + i] = xL[i];
342 for (std::size_t l = L - 1; l-- > 0;) {
343 const std::vector<T> xn(pB.begin() + oS + f.off[l + 1], pB.begin() + oS + f.off[l + 2]);
344 const std::vector<T> xg =
vecmul(xn, f.G[l + 1]);
345 for (std::size_t i = 0; i < f.P[l]; ++i) pB[oS + f.off[l] + i] = -xg[i];
349 for (std::size_t k = S - 1; k-- > 0;) {
350 std::vector<T> y(nset[k], zero<T>());
351 for (std::size_t i = 0; i < bRows[k].size(); ++i) {
352 const T p = pB[bRows[k][i]];
353 if (p == zero<T>())
continue;
354 for (std::size_t t = 0; t < nset[k]; ++t) y[t] += p * bVals[k][i][t];
356 const std::vector<T> x = fac[k].rowsolve(y);
357 for (std::size_t t = 0; t < nset[k]; ++t) pB[setOff[k] + t] = x[t];
360 for (
const T& v : pB) tot += v;
363 for (std::size_t i = 0; i < n; ++i) res.
pi[i] = pB[i] / tot;
366 for (std::size_t s = 0; s < S; ++s)
367 for (std::size_t p : phases[s]) {
368 res.
pi_cells[s].emplace_back(res.
pi.begin() + pos, res.
pi.begin() + pos + p);