66 std::size_t dist_size = 500, std::size_t num_w_moms = 3) {
68 "qsys_mapmapc requires transcendental arithmetic");
69 using mapphcdetail::madd2;
70 using mapphcdetail::mkron;
75 const std::size_t ma = D0.
rows();
76 const std::size_t p = service.
D0.rows();
77 if (D0.
cols() != ma || D1.
rows() != ma || D1.
cols() != ma)
78 throw InputError(
"qsys_mapmapc: D0 and D1 must be square and of equal order");
79 if (service.
D0.cols() != p || service.
D1.rows() != p || service.
D1.cols() != p)
80 throw InputError(
"qsys_mapmapc: S0 and S1 must be square and of equal order");
81 if (c < 1)
throw InputError(
"qsys_mapmapc: c must be a positive integer");
82 if (dist_size == 0)
throw InputError(
"qsys_mapmapc: dist_size must be positive");
85 if (lambda <= zero)
throw InputError(
"qsys_mapmapc: non-positive arrival rate");
88 const T rho = lambda * mean_service / ct;
89 if (rho >= one)
throw InputError(
"qsys_mapmapc: load rho must be strictly less than 1");
94 const std::vector<T> arr(c + 2, one);
97 std::vector<T>(),
true);
98 std::vector<Matrix<T> > LOC(c + 1);
99 for (
unsigned k = 0; k <= c; ++k) {
101 for (std::size_t i = 0; i < LOC[k].rows(); ++i) LOC[k](i, i) += one;
104 const std::size_t
nc = CDEP.
rows();
109 const Matrix<T> A_loc = madd2(mkron(D0, Inc), mkron(Ima, LOC[c]));
113 const std::size_t n_op =
nc * ma;
115 for (std::size_t i = 0; i < n_op; ++i)
116 for (std::size_t j = 0; j < n_op; ++j) ImR(i, j) = (i == j ? one : zero) - R(i, j);
118 const std::vector<T> sum_geom =
mulvec(ImRinv,
ones<T>(n_op));
120 std::vector<std::size_t> sz(c + 1), off(c + 2, 0);
121 for (
unsigned k = 0; k <= c; ++k) {
122 sz[k] = ma * LOC[k].rows();
123 off[k + 1] = off[k] + sz[k];
125 const std::size_t tot = off[c + 1];
128 for (
unsigned k = 0; k <= c; ++k) {
130 const Matrix<T> diag = (k < c) ? madd2(mkron(D0, Ick), mkron(Ima, LOC[k]))
131 : madd2(A_loc, RA_dn);
132 for (std::size_t i = 0; i < sz[k]; ++i)
133 for (std::size_t j = 0; j < sz[k]; ++j) Q(off[k] + i, off[k] + j) += diag(i, j);
136 for (std::size_t i = 0; i < up.
rows(); ++i)
137 for (std::size_t j = 0; j < up.
cols(); ++j) Q(off[k] + i, off[k + 1] + j) += up(i, j);
141 for (std::size_t i = 0; i < dn.
rows(); ++i)
142 for (std::size_t j = 0; j < dn.
cols(); ++j) Q(off[k] + i, off[k - 1] + j) += dn(i, j);
148 for (std::size_t i = 0; i < tot; ++i)
149 for (std::size_t j = 0; j < tot; ++j) M(j, i) = Q(i, j);
150 for (std::size_t col = 0; col < tot; ++col) M(tot - 1, col) = zero;
151 for (std::size_t i = 0; i < off[c]; ++i) M(tot - 1, i) = one;
152 for (std::size_t i = 0; i < sz[c]; ++i) M(tot - 1, off[c] + i) = sum_geom[i];
153 std::vector<T> b(tot, zero);
157 std::vector<T> pi_c(n_op);
158 for (std::size_t i = 0; i < n_op; ++i) pi_c[i] = pi_vec[off[c] + i];
162 for (
unsigned k = 0; k < c; ++k) {
164 for (std::size_t i = 0; i < sz[k]; ++i) s += pi_vec[off[k] + i];
168 std::vector<T> tail = pi_c;
171 for (std::size_t i = 0; i < n_op; ++i) s += tail[i];
176 std::vector<T> next(n_op, zero);
177 for (std::size_t j = 0; j < n_op; ++j)
178 for (std::size_t i = 0; i < n_op; ++i) next[j] += tail[i] * R(i, j);
181 for (std::size_t i = 0; i < n_op; ++i) s += tail[i];
187 for (
unsigned k = 0; k < c; ++k)
189 const std::vector<T> r_tail =
mulvec(R,
mulvec(ImRinv, sum_geom));
190 for (std::size_t i = 0; i < n_op; ++i) meanQL += pi_c[i] * (ct * sum_geom[i] + r_tail[i]);
197 for (std::size_t i = 0; i < n_op; ++i)
198 for (std::size_t j = 0; j < n_op; ++j) G0(i, j) = G0(i, j) / lambda;
202 for (std::size_t i = 0; i < n_op; ++i) probWait += pi_c[i] * v[i];
204 std::vector<T> wMoms;
205 if (num_w_moms > 0) {
207 const std::size_t n2 = n_op * n_op;
209 for (std::size_t a = 0; a < n_op; ++a) {
210 for (std::size_t bcol = 0; bcol < n_op; ++bcol) {
211 for (std::size_t i = 0; i < n_op; ++i)
212 Kop(a * n_op + i, bcol * n_op + i) += -Lj(bcol, a);
213 for (std::size_t i = 0; i < n_op; ++i)
214 for (std::size_t q = 0; q < n_op; ++q)
215 Kop(a * n_op + i, bcol * n_op + q) += -R(i, q) * Cj(bcol, a);
219 for (std::size_t k = 1; k <= num_w_moms; ++k) {
220 std::vector<T> rhs(n2, zero);
221 for (std::size_t j = 0; j < n_op; ++j)
222 for (std::size_t i = 0; i < n_op; ++i)
223 rhs[j * n_op + i] = (k == 1)
228 for (std::size_t j = 0; j < n_op; ++j)
229 for (std::size_t i = 0; i < n_op; ++i) g(i, j) = gv[j * n_op + i];
232 for (std::size_t i = 0; i < n_op; ++i) mk += pi_c[i] * v[i];
234 if (k % 2 == 0) mk = -mk;
242 r.
meanWaitingTime = wMoms.empty() ? meanQL / lambda - mean_service : wMoms[0];