143 const Matrix<T>& S,
unsigned c, std::size_t dist_size,
144 std::size_t num_w_moms,
const std::vector<T>& w_points) {
146 "qsys_mapphc requires transcendental arithmetic");
147 using mapphcdetail::find_cfg;
148 using mapphcdetail::madd2;
149 using mapphcdetail::mkron;
150 using mapphcdetail::multisets;
155 const std::size_t ma = D0.
rows();
156 const std::size_t ms = S.
rows();
157 if (D0.
cols() != ma || D1.
rows() != ma || D1.
cols() != ma)
158 throw InputError(
"qsys_mapphc: D0 and D1 must be square and of equal order");
159 if (S.
cols() != ms || alpha.size() != ms)
160 throw InputError(
"qsys_mapphc: alpha and S must have matching order");
161 if (c < 1)
throw InputError(
"qsys_mapphc: c must be a positive integer");
162 if (dist_size == 0)
throw InputError(
"qsys_mapphc: dist_size must be positive");
164 std::vector<T> s0(ms, zero);
165 for (std::size_t i = 0; i < ms; ++i) {
167 for (std::size_t j = 0; j < ms; ++j) r += S(i, j);
172 if (lambda <= zero)
throw InputError(
"qsys_mapphc: non-positive arrival rate");
175 T mean_service = zero;
176 for (std::size_t i = 0; i < ms; ++i) mean_service -= alpha[i] * negSinv_e[i];
178 const T rho = lambda * mean_service / ct;
179 if (rho >= one)
throw InputError(
"qsys_mapphc: load rho must be strictly less than 1");
181 std::vector<std::vector<std::vector<int> > > cfg(c + 1);
182 for (
unsigned k = 0; k <= c; ++k) cfg[k] = multisets(ms, k);
184 std::vector<Matrix<T> > Lcfg, Up, Dn;
185 for (
unsigned k = 0; k <= c; ++k) {
186 const std::vector<std::vector<int> >& Ck = cfg[k];
187 const std::size_t nk = Ck.size();
189 for (std::size_t row = 0; row < nk; ++row) {
190 const std::vector<int>& n = Ck[row];
191 for (std::size_t i = 0; i < ms; ++i) {
192 if (n[i] == 0)
continue;
194 for (std::size_t j = 0; j < ms; ++j) {
195 if (j == i)
continue;
196 std::vector<int> m = n;
199 Lk(row, find_cfg(Ck, m)) += ni * S(i, j);
201 Lk(row, row) += ni * S(i, i);
207 const std::vector<std::vector<int> >& Ck1 = cfg[k + 1];
209 for (std::size_t row = 0; row < nk; ++row) {
210 for (std::size_t j = 0; j < ms; ++j) {
211 std::vector<int> m = Ck[row];
213 Uk(row, find_cfg(Ck1, m)) += alpha[j];
222 const std::vector<std::vector<int> >& Ckm = cfg[k - 1];
224 for (std::size_t row = 0; row < nk; ++row) {
225 const std::vector<int>& n = Ck[row];
226 for (std::size_t i = 0; i < ms; ++i) {
227 if (n[i] == 0)
continue;
228 std::vector<int> m = n;
240 const std::vector<std::vector<int> >& Cc = cfg[c];
241 const std::size_t
nc = Cc.size();
243 for (std::size_t row = 0; row <
nc; ++row) {
244 const std::vector<int>& n = Cc[row];
245 for (std::size_t i = 0; i < ms; ++i) {
246 if (n[i] == 0)
continue;
248 for (std::size_t j = 0; j < ms; ++j) {
249 std::vector<int> m = n;
252 Cdep(row, find_cfg(Cc, m)) += ni * s0[i] * alpha[j];
260 const Matrix<T> A_loc = madd2(mkron(D0, Inc), mkron(Ima, Lcfg[c]));
264 const std::size_t n_op =
nc * ma;
266 for (std::size_t i = 0; i < n_op; ++i)
267 for (std::size_t j = 0; j < n_op; ++j) ImR(i, j) = (i == j ? one : zero) - R(i, j);
269 const std::vector<T> sum_geom =
mulvec(ImRinv,
ones<T>(n_op));
272 std::vector<std::size_t> sz(c + 1), off(c + 2, 0);
273 for (
unsigned k = 0; k <= c; ++k) {
274 sz[k] = ma * cfg[k].size();
275 off[k + 1] = off[k] + sz[k];
277 const std::size_t tot = off[c + 1];
280 for (
unsigned k = 0; k <= c; ++k) {
282 const Matrix<T> diag = (k < c) ? madd2(mkron(D0, Ick), mkron(Ima, Lcfg[k]))
283 : madd2(A_loc, RA_dn);
284 for (std::size_t i = 0; i < sz[k]; ++i)
285 for (std::size_t j = 0; j < sz[k]; ++j) Q(off[k] + i, off[k] + j) += diag(i, j);
288 for (std::size_t i = 0; i < up.
rows(); ++i)
289 for (std::size_t j = 0; j < up.
cols(); ++j) Q(off[k] + i, off[k + 1] + j) += up(i, j);
293 for (std::size_t i = 0; i < dn.
rows(); ++i)
294 for (std::size_t j = 0; j < dn.
cols(); ++j) Q(off[k] + i, off[k - 1] + j) += dn(i, j);
301 for (std::size_t i = 0; i < tot; ++i)
302 for (std::size_t j = 0; j < tot; ++j) M(j, i) = Q(i, j);
303 for (std::size_t col = 0; col < tot; ++col) M(tot - 1, col) = zero;
304 for (std::size_t i = 0; i < off[c]; ++i) M(tot - 1, i) = one;
305 for (std::size_t i = 0; i < sz[c]; ++i) M(tot - 1, off[c] + i) = sum_geom[i];
306 std::vector<T> b(tot, zero);
310 std::vector<T> pi_c(n_op);
311 for (std::size_t i = 0; i < n_op; ++i) pi_c[i] = pi_vec[off[c] + i];
315 for (
unsigned k = 0; k < c; ++k) {
317 for (std::size_t i = 0; i < sz[k]; ++i) s += pi_vec[off[k] + i];
320 std::vector<T> tail = pi_c;
322 for (std::size_t i = 0; i < ql.size(); ++i) acc += ql[i];
325 for (std::size_t i = 0; i < n_op; ++i) s += tail[i];
330 std::vector<T> next(n_op, zero);
331 for (std::size_t j = 0; j < n_op; ++j)
332 for (std::size_t i = 0; i < n_op; ++i) next[j] += tail[i] * R(i, j);
335 for (std::size_t i = 0; i < n_op; ++i) s += tail[i];
344 for (
unsigned k = 0; k < c; ++k)
347 const std::vector<T> r_tail =
mulvec(R,
mulvec(ImRinv, u_tail));
349 for (std::size_t i = 0; i < n_op; ++i)
350 meanQL += pi_c[i] * (c_scal * u_tail[i] + r_tail[i]);
353 const Matrix<T> Lj = mkron(Ima, Lcfg[c]);
356 for (std::size_t i = 0; i < n_op; ++i)
357 for (std::size_t j = 0; j < n_op; ++j) G0(i, j) = G0(i, j) / lambda;
361 for (std::size_t i = 0; i < n_op; ++i) probWait += pi_c[i] * v[i];
365 const std::size_t n2 = n_op * n_op;
367 for (std::size_t a = 0; a < n_op; ++a) {
368 for (std::size_t bcol = 0; bcol < n_op; ++bcol) {
370 for (std::size_t i = 0; i < n_op; ++i)
371 Kop(a * n_op + i, bcol * n_op + i) += -Lj(bcol, a);
373 for (std::size_t i = 0; i < n_op; ++i)
374 for (std::size_t p = 0; p < n_op; ++p)
375 Kop(a * n_op + i, bcol * n_op + p) += -R(i, p) * Cj(bcol, a);
378 std::vector<T> wMoms;
380 for (std::size_t k = 1; k <= num_w_moms; ++k) {
381 std::vector<T> rhs(n2, zero);
382 for (std::size_t j = 0; j < n_op; ++j)
383 for (std::size_t i = 0; i < n_op; ++i)
384 rhs[j * n_op + i] = (k == 1)
389 for (std::size_t j = 0; j < n_op; ++j)
390 for (std::size_t i = 0; i < n_op; ++i) g(i, j) = gv[j * n_op + i];
393 for (std::size_t i = 0; i < n_op; ++i) mk += pi_c[i] * v[i];
395 if (k % 2 == 0) mk = -mk;
400 std::vector<T> wCCDF;
401 if (!w_points.empty()) {
403 for (std::size_t a = 0; a < n_op; ++a) {
404 for (std::size_t bcol = 0; bcol < n_op; ++bcol) {
405 for (std::size_t i = 0; i < n_op; ++i)
406 Kt(a * n_op + i, bcol * n_op + i) += Lj(bcol, a);
407 for (std::size_t i = 0; i < n_op; ++i)
408 for (std::size_t p = 0; p < n_op; ++p)
409 Kt(a * n_op + i, bcol * n_op + p) += R(i, p) * Cj(bcol, a);
412 std::vector<T> v0(n2, zero);
413 for (std::size_t j = 0; j < n_op; ++j)
414 for (std::size_t i = 0; i < n_op; ++i) v0[j * n_op + i] = G0(i, j);
415 for (std::size_t it = 0; it < w_points.size(); ++it) {
417 for (std::size_t i = 0; i < n2; ++i)
418 for (std::size_t j = 0; j < n2; ++j) Kts(i, j) = Kt(i, j) * w_points[it];
421 for (std::size_t j = 0; j < n_op; ++j)
422 for (std::size_t i = 0; i < n_op; ++i) Gt(i, j) = vt[j * n_op + i];
425 for (std::size_t i = 0; i < n_op; ++i) s += pi_c[i] * v[i];