109 const std::vector<
Matrix<T>>& D1s,
const std::vector<int>& N) {
110 using amva_detail::inverse;
111 using amva_detail::solve_linear;
112 using amva_detail::stationary;
113 using Mat = std::vector<std::vector<double>>;
114 const std::size_t R = N.size();
115 if (mu_in.size() != R || D0s.size() != R || D1s.size() != R)
116 throw InputError(
"mapqn_amva: mu, D0s, D1s and N must all have one entry per class");
117 std::vector<double> mu(R);
118 std::vector<std::size_t> Ks(R);
119 std::vector<Mat> D0(R), D1(R);
120 for (std::size_t r = 0; r < R; ++r) {
122 Ks[r] = D0s[r].rows();
123 D0[r].assign(Ks[r], std::vector<double>(Ks[r], 0.0));
124 D1[r].assign(Ks[r], std::vector<double>(Ks[r], 0.0));
125 for (std::size_t i = 0; i < Ks[r]; ++i)
126 for (std::size_t j = 0; j < Ks[r]; ++j) {
132 for (std::size_t r = 0; r < R; ++r) K *= Ks[r];
133 std::vector<std::size_t> stride(R, 1);
134 for (std::size_t r = 0; r < R; ++r)
135 for (std::size_t t = r + 1; t < R; ++t) stride[r] *= Ks[t];
136 std::vector<std::vector<std::size_t>> krOf(K, std::vector<std::size_t>(R, 0));
137 for (std::size_t k = 0; k < K; ++k)
138 for (std::size_t r = 0; r < R; ++r) krOf[k][r] = (k / stride[r]) % Ks[r];
140 for (std::size_t r = 0; r < R; ++r) Ntot += N[r];
142 std::vector<Mat> G(R), Ainv(R), Tt(R);
143 std::vector<std::vector<double>> th(R), phi(R), age(R);
144 std::vector<double> ES(R, 0.0), abar(R, 0.0);
145 for (std::size_t r = 0; r < R; ++r) {
146 const std::size_t Kr = Ks[r];
147 G[r].assign(Kr, std::vector<double>(Kr, 0.0));
148 for (std::size_t i = 0; i < Kr; ++i)
149 for (std::size_t j = 0; j < Kr; ++j) G[r][i][j] = D0[r][i][j] + D1[r][i][j];
150 th[r] = stationary(G[r]);
152 for (std::size_t i = 0; i < Kr; ++i)
153 for (std::size_t j = 0; j < Kr; ++j) rate += th[r][i] * D1[r][i][j];
155 phi[r].assign(Kr, 0.0);
156 for (std::size_t j = 0; j < Kr; ++j) {
158 for (std::size_t i = 0; i < Kr; ++i) a += th[r][i] * D1[r][i][j];
159 phi[r][j] = a * ES[r];
161 Mat negD0(Kr, std::vector<double>(Kr, 0.0));
162 for (std::size_t i = 0; i < Kr; ++i)
163 for (std::size_t j = 0; j < Kr; ++j) negD0[i][j] = -D0[r][i][j];
164 const Mat negD0inv =
inverse(negD0);
165 std::vector<double> s(Kr, 0.0);
166 for (std::size_t i = 0; i < Kr; ++i)
167 for (std::size_t j = 0; j < Kr; ++j) s[i] += negD0inv[i][j];
168 Mat P(Kr, std::vector<double>(Kr, 0.0));
169 for (std::size_t i = 0; i < Kr; ++i)
170 for (std::size_t j = 0; j < Kr; ++j) {
172 for (std::size_t m = 0; m < Kr; ++m) a += negD0inv[i][m] * D1[r][m][j];
175 Tt[r].assign(Ntot + 2, std::vector<double>(Kr, 0.0));
176 std::vector<double> acc(Kr, 0.0), v = s;
177 for (
int j = 1; j <= Ntot + 1; ++j) {
178 for (std::size_t i = 0; i < Kr; ++i) acc[i] += v[i];
180 std::vector<double> nv(Kr, 0.0);
181 for (std::size_t i = 0; i < Kr; ++i)
182 for (std::size_t m = 0; m < Kr; ++m) nv[i] += P[i][m] * v[m];
185 std::vector<double> w(Kr, 0.0);
186 for (std::size_t j = 0; j < Kr; ++j)
187 for (std::size_t i = 0; i < Kr; ++i) w[j] += th[r][i] * negD0inv[i][j];
188 age[r].assign(Kr, 0.0);
189 for (std::size_t j = 0; j < Kr; ++j) { age[r][j] = w[j] / th[r][j]; abar[r] += w[j]; }
190 Mat A(Kr, std::vector<double>(Kr, 0.0));
191 for (std::size_t i = 0; i < Kr; ++i)
192 for (std::size_t j = 0; j < Kr; ++j) A[i][j] = G[r][i][j] - (i == j ? mu[r] : 0.0);
196 std::vector<double> F(K, 1.0);
197 std::vector<std::vector<double>> u(R, std::vector<double>(K, 1.0));
198 for (std::size_t k = 0; k < K; ++k) {
199 for (std::size_t r = 0; r < R; ++r) F[k] *= phi[r][krOf[k][r]];
200 for (std::size_t r = 0; r < R; ++r)
201 for (std::size_t s = 0; s < R; ++s) u[r][k] *= (s == r) ? th[s][krOf[k][s]] : phi[s][krOf[k][s]];
203 auto apply_axis = [&](
const std::vector<double>& V,
const Mat& M, std::size_t r) {
204 std::vector<double> out(K, 0.0);
205 for (std::size_t k = 0; k < K; ++k) {
206 const std::size_t kr = krOf[k][r];
207 const std::size_t base = k - kr * stride[r];
209 for (std::size_t h = 0; h < Ks[r]; ++h) a += V[base + h * stride[r]] * M[h][kr];
214 auto t_at = [&](std::size_t r,
double b, std::size_t kr) {
215 const Mat& Tr = Tt[r];
216 long j0 =
static_cast<long>(std::floor(b));
217 j0 = std::max<long>(0, std::min<long>(j0,
static_cast<long>(Tr.size()) - 2));
218 const double f = std::min(std::max(b -
static_cast<double>(j0), 0.0), 1.0);
219 return (1.0 - f) * Tr[
static_cast<std::size_t
>(j0)][kr] + f * Tr[
static_cast<std::size_t
>(j0) + 1][kr];
222 std::vector<std::size_t> lstride(R, 1);
224 for (std::size_t rr = R; rr-- > 0;) { lstride[rr] = L; L *=
static_cast<std::size_t
>(N[rr] + 1); }
225 std::vector<std::vector<std::vector<double>>> Qs(L, std::vector<std::vector<double>>(R, std::vector<double>(K, 0.0)));
226 std::vector<std::vector<double>> pis(L, std::vector<double>(K, 0.0)), Xs(L, std::vector<double>(R, 0.0));
228 for (std::size_t l = 1; l < L; ++l) {
229 std::vector<int> n(R, 0);
230 for (std::size_t r = 0; r < R; ++r) n[r] = static_cast<int>((l / lstride[r]) %
static_cast<std::size_t
>(N[r] + 1));
231 std::vector<std::vector<std::vector<double>>> b(R), bN(R);
232 std::vector<std::vector<double>> Rk(R, std::vector<double>(K, 0.0));
233 for (std::size_t r = 0; r < R; ++r) {
234 if (n[r] < 1)
continue;
235 const std::size_t
lp = l - lstride[r];
236 b[r].assign(R, std::vector<double>(K, 0.0));
237 for (std::size_t t = 0; t < R; ++t)
238 for (std::size_t k = 0; k < K; ++k) b[r][t][k] = pis[lp][k] > 0 ? Qs[
lp][t][k] / pis[
lp][k] : 0.0;
239 for (std::size_t k = 0; k < K; ++k) {
241 for (std::size_t t = 0; t < R; ++t) a += t_at(t, b[r][t][k] + (t == r ? 1.0 : 0.0), krOf[k][t]);
244 bN[r].assign(R, std::vector<double>(K, 0.0));
245 for (std::size_t t = 0; t < R; ++t) {
246 if (t == r || n[t] == 0)
continue;
247 const double Xt = Xs[
lp][t];
249 for (std::size_t k = 0; k < K; ++k) Qt += Qs[
lp][t][k];
251 const double W = std::max(Qt / Xt - abar[r], 0.0);
252 for (std::size_t k = 0; k < K; ++k)
253 bN[r][t][k] = Xt * std::min(W + age[r][krOf[k][r]],
static_cast<double>(n[t]) / Xt);
258 std::vector<std::vector<double>> c0(R);
259 std::vector<std::vector<std::vector<double>>> c1(R, std::vector<std::vector<double>>(R));
260 for (std::size_t r = 0; r < R; ++r) {
261 if (n[r] < 1)
continue;
262 std::vector<double> v0(K, 0.0);
263 for (std::size_t k = 0; k < K; ++k) v0[k] = -mu[r] * n[r] * F[k];
264 c0[r] = apply_axis(v0, Ainv[r], r);
265 for (std::size_t s = 0; s < R; ++s) {
266 std::vector<double> term(K, 0.0);
267 for (std::size_t k = 0; k < K; ++k) term[k] = -mu[r] * n[r] * ES[s] * (u[s][k] - F[k]);
269 const std::vector<double> ud = apply_axis(u[r], D1[r], r);
270 for (std::size_t k = 0; k < K; ++k) term[k] += ES[r] * ud[k];
271 }
else if (n[s] >= 1) {
272 std::vector<double> W(K, 0.0);
273 for (std::size_t k = 0; k < K; ++k) W[k] = ES[s] * u[s][k] * bN[s][r][k];
274 const std::vector<double> a1 = apply_axis(W, G[r], r), a2 = apply_axis(W, G[s], s);
275 for (std::size_t k = 0; k < K; ++k) term[k] += a1[k] - a2[k];
277 c1[r][s] = apply_axis(term, Ainv[r], r);
281 Mat M(R, std::vector<double>(R, 0.0));
282 std::vector<double> v(R, 0.0);
283 for (std::size_t r = 0; r < R; ++r) M[r][r] = 1.0;
284 for (std::size_t r = 0; r < R; ++r) {
285 if (n[r] < 1)
continue;
287 for (std::size_t k = 0; k < K; ++k) a += (n[r] * F[k] - c0[r][k]) * Rk[r][k];
288 v[r] = n[r] - mu[r] * a;
289 M[r][r] = 1.0 / mu[r];
290 for (std::size_t s = 0; s < R; ++s) {
291 if (n[s] < 1)
continue;
293 for (std::size_t k = 0; k < K; ++k) e += (n[r] * ES[s] * (u[s][k] - F[k]) - c1[r][s][k]) * Rk[r][k];
294 M[r][s] += mu[r] * e;
297 const std::vector<double> X = solve_linear(M, v);
298 std::vector<double> pi(K, 0.0);
300 for (std::size_t k = 0; k < K; ++k) {
302 for (std::size_t s = 0; s < R; ++s) p += X[s] * ES[s] * (u[s][k] - F[k]);
303 pi[k] = std::max(p, 0.0);
306 for (
double& p : pi) p /= psum;
307 for (std::size_t r = 0; r < R; ++r) {
308 if (n[r] < 1)
continue;
309 std::vector<double> Ur(K, 0.0), Qr(K, 0.0), Wr(K, 0.0);
310 double usum = 0.0, wsum = 0.0;
311 for (std::size_t k = 0; k < K; ++k) {
312 Ur[k] = X[r] * ES[r] * u[r][k];
314 for (std::size_t s = 0; s < R; ++s) Qr[k] += X[s] * c1[r][s][k];
315 Wr[k] = std::max(Qr[k] - Ur[k], 0.0);
320 const double tot = std::max(n[r] - X[r] / mu[r] - usum, 0.0);
321 for (std::size_t k = 0; k < K; ++k) Qs[l][r][k] = Ur[k] + (wsum > 0 ? Wr[k] * tot / wsum : 0.0);
327 out.
X.resize(R); out.
Qq.resize(R); out.
U.resize(R); out.
ES.resize(R); out.
pi.resize(K);
328 for (std::size_t r = 0; r < R; ++r) {
330 for (std::size_t k = 0; k < K; ++k) q += Qs[L - 1][r][k];