117 "solver_rqna: the robust queueing-network analyzer needs transcendental arithmetic "
118 "(counting-process indices of dispersion); rerun with --arith double or --arith real");
120 using rqna_detail::rqna_phat;
121 using rqna_detail::rqna_geom_map;
122 using rqna_detail::submat;
133 for (std::size_t r = 0; r < L.
nclasses; ++r)
134 if (std::isfinite(L.
classes[r].population))
135 throw UnsupportedError(
"solver_rqna: RQNA supports open networks only (no closed classes)");
138 "solver_rqna: the reference indexes the stateful-indexed sn.rt with station indices, "
139 "which is only correct when every stateful node is a station");
153 std::vector<bool> isSource(M,
false), schedInf(M,
false);
154 for (std::size_t i = 0; i < M; ++i) {
155 isSource[i] = (L.
stations[i].nodetype == qn::NodeType::Source);
156 schedInf[i] = (L.
stations[i].sched == qn::SchedStrategy::INF);
157 if (isSource[i] && src == M) src = i;
160 throw UnsupportedError(
"solver_rqna: RQNA requires an open network with a Source station");
161 std::vector<std::size_t> qstat;
162 for (std::size_t i = 0; i < M; ++i)
163 if (!isSource[i]) qstat.push_back(i);
164 const std::size_t nq = qstat.size();
167 auto rtS = [&](std::size_t i, std::size_t j) -> T {
return L.
rt(i, j); };
175 std::vector<T> mu(nq, zero), cs2(nq, zero), lambda0(nq, zero), qsplit(nq, zero);
176 std::vector<mam::Map<T> > svcMAP;
179 for (std::size_t a = 0; a < nq; ++a) {
180 const std::size_t ia = qstat[a];
181 mu[a] = L.
rates(ia, 0);
182 cs2[a] = L.
scv(ia, 0);
184 qsplit[a] = rtS(src, ia);
185 lambda0[a] = T(lambda_src * qsplit[a]);
186 for (std::size_t b = 0; b < nq; ++b) P(a, b) = rtS(ia, qstat[b]);
190 std::vector<T> c2a0(nq, zero);
191 for (std::size_t a = 0; a < nq; ++a) c2a0[a] = T(qsplit[a] * c2_src + (one - qsplit[a]));
194 std::function<std::vector<T>(
const T&)> a0IdcFun = [&](
const T& t) {
195 std::vector<T> out(nq, zero);
197 for (std::size_t a = 0; a < nq; ++a) out[a] = T(qsplit[a] * Iarv + (one - qsplit[a]));
200 std::function<std::vector<T>(
const std::vector<T>&)> sIdcFun =
201 [&](
const std::vector<T>& tt) {
202 std::vector<T> out(nq, zero);
214 const std::vector<T>& lambda = ctx.
lambda;
215 const std::vector<T>& rho = ctx.
rho;
218 auto component = [&](
const T& x, std::size_t a) -> T {
222 for (std::size_t a = 0; a < nq; ++a) {
223 const std::size_t ia = qstat[a];
224 s.
Tp(ia, 0) = lambda[a];
225 if (!(lambda[a] > zero))
continue;
227 s.
U(ia, 0) = T(lambda[a] / mu[a]);
228 s.
Q(ia, 0) = T(lambda[a] / mu[a]);
229 s.
R(ia, 0) = T(one / mu[a]);
233 phat = rqna_phat(P, rho, a);
237 std::vector<std::size_t> Hc, Hi;
238 for (std::size_t i = 0; i < nq; ++i) {
239 if (i == a)
continue;
240 if (rho[i] <= T(rho[a] + tol)) Hc.push_back(i);
241 else Hi.push_back(i);
243 std::vector<std::size_t> R;
245 for (std::size_t i : Hi) R.push_back(i);
246 const std::size_t m = R.size();
251 Pred = submat(P, R, R);
253 const std::size_t
nc = Hc.size();
255 for (std::size_t i = 0; i <
nc; ++i) {
257 for (std::size_t j = 0; j <
nc; ++j) ImP(i, j) = T(ImP(i, j) - P(Hc[i], Hc[j]));
260 G =
matmul(Fhc, submat(P, Hc, R));
261 Pred = submat(P, R, R);
263 for (std::size_t i = 0; i < m; ++i)
264 for (std::size_t j = 0; j < m; ++j) Pred(i, j) = T(Pred(i, j) + corr2(i, j));
267 if (ph < zero) ph = zero;
270 for (std::size_t j = 0; j < m; ++j) Pred(0, j) = T(Pred(0, j) / (one - ph));
275 std::vector<T> lam0R(m, zero);
276 for (std::size_t rr = 0; rr < m; ++rr) {
277 lam0R[rr] = lambda0[R[rr]];
278 for (std::size_t ii = 0; ii < Hc.size(); ++ii)
279 lam0R[rr] = T(lam0R[rr] + lambda0[Hc[ii]] * G(ii, rr));
281 std::vector<T> c2a0R(m, zero);
282 for (std::size_t rr = 0; rr < m; ++rr) {
283 if (!(lam0R[rr] > zero))
continue;
284 T acc = T(lambda0[R[rr]] * (qsplit[R[rr]] * idc_arv_inf + (one - qsplit[R[rr]])));
285 for (std::size_t ii = 0; ii < Hc.size(); ++ii) {
286 const T g = G(ii, rr);
287 const T ci = T(qsplit[Hc[ii]] * idc_arv_inf + (one - qsplit[Hc[ii]]));
288 acc = T(acc + lambda0[Hc[ii]] * g * (g * ci + (one - g)));
290 c2a0R[rr] = T(acc / lam0R[rr]);
292 std::function<std::vector<T>(
const T&)> a0IdcR = [&, R, Hc, G, lam0R, m](
const T& t) {
293 std::vector<T> Ir(m, one);
295 auto c2fun_i = [&](std::size_t i) -> T {
296 return T(qsplit[i] * Iarv + (one - qsplit[i]));
298 for (std::size_t rr = 0; rr < m; ++rr) {
299 if (!(lam0R[rr] > zero))
continue;
300 T num = T(lambda0[R[rr]] * c2fun_i(R[rr]));
301 for (std::size_t ii = 0; ii < Hc.size(); ++ii) {
302 const T g = G(ii, rr);
303 num = T(num + lambda0[Hc[ii]] * g * (g * c2fun_i(Hc[ii]) + (one - g)));
305 Ir[rr] = T(num / lam0R[rr]);
311 std::vector<T> muR(m, zero), cs2R(m, zero);
312 std::vector<mam::Map<T> > svcR;
314 for (std::size_t rr = 0; rr < m; ++rr) {
316 cs2R[rr] = cs2[R[rr]];
317 svcR.push_back(svcMAP[R[rr]]);
319 svcR[0] = rqna_geom_map(svcMAP[a], ph);
320 muR[0] = T((one - ph) * mu[a]);
321 cs2R[0] = T(ph + (one - ph) * cs2[a]);
322 std::function<std::vector<T>(
const std::vector<T>&)> sIdcR =
323 [&, m](
const std::vector<T>& tt) {
324 std::vector<T> out(m, zero);
325 for (std::size_t rr = 0; rr < m; ++rr)
332 auto IaFunA = [&](
const T& x) -> T {
336 s.
R(ia, 0) = T((one - ph) * Wt + one / mu[a]);
338 auto IaFun_a = [&](
const T& x) -> T {
return component(x, a); };
340 s.
R(ia, 0) = T(Wa + one / mu[a]);
343 s.
Q(ia, 0) = T(lambda[a] * s.
R(ia, 0));
346 s.
Tp(src, 0) = lambda_src;
348 for (std::size_t i = 0; i < M; ++i) Csum = T(Csum + s.
R(i, 0));