96 std::size_t lcfsStat, std::size_t lcfsprStat) {
104 "solver_nc_lcfsqn: the LCFS closed form reports lG = log(G); this backend has no "
105 "transcendental arithmetic");
108 const std::size_t M =
sn.nstations, R =
sn.nclasses;
110 std::vector<T> alpha(R, zero), beta(R, zero);
111 std::vector<int> N(R, 0);
112 for (std::size_t r = 0; r < R; ++r) {
113 if (std::isinf(
sn.classes[r].population))
114 throw UnsupportedError(
"solver_nc_lcfsqn: requires a closed queueing network");
115 N[r] =
static_cast<int>(std::llround(
sn.classes[r].population));
116 if (N[r] <= 0)
continue;
119 if (!(mu_l > 0.0) || !std::isfinite(mu_l))
121 "solver_nc_lcfsqn: invalid service rate at the LCFS station");
122 if (!(mu_p > 0.0) || !std::isfinite(mu_p))
124 "solver_nc_lcfsqn: invalid service rate at the LCFS-PR station");
131 : -std::numeric_limits<double>::infinity();
134 for (
int v : N) K +=
static_cast<std::size_t
>(v);
137 std::vector<T> alphaE, betaE;
138 std::vector<std::size_t> ecls(R, 0);
139 for (std::size_t r = 0; r < R; ++r) {
140 ecls[r] = alphaE.size() + 1;
141 for (
int a = 0; a < N[r]; ++a) {
142 alphaE.push_back(alpha[r]);
143 betaE.push_back(beta[r]);
147 for (std::size_t r = 0; r < R; ++r)
150 const std::vector<int>
ones(K, 1);
151 Matrix<T> Q_l(2, R, zero), U_l(2, R, zero), T_l(2, R, zero);
152 for (std::size_t r = 0; r < R; ++r) {
153 if (N[r] <= 0)
continue;
154 const std::size_t e = ecls[r];
155 T Tcopy = zero, Qcopy = zero;
156 for (std::size_t xt = 1; xt <= K; ++xt) {
157 const Matrix<T> Tx = detail::lcfs_make_Tx(alphaE, betaE, xt, K, e);
158 const std::vector<int> onesTx(K - 1, 1);
159 Tcopy = T(Tcopy +
num_pow_int(alphaE[e - 1], xt - 1) *
161 const Matrix<T> Yx = detail::lcfs_make_Yx(alphaE, betaE, xt, K, e);
165 T_l(0, r) = T(nr * Tcopy);
166 T_l(1, r) = T(nr * Tcopy);
167 Q_l(0, r) = T(nr * Qcopy);
168 Q_l(1, r) = T(nr - Q_l(0, r));
170 for (std::size_t r = 0; r < R; ++r) {
171 U_l(0, r) = T(T_l(0, r) * alpha[r]);
172 U_l(1, r) = T(T_l(1, r) * beta[r]);
175 Matrix<T> Q(M, R, zero), U(M, R, zero), Tp(M, R, zero), Rt(M, R, zero);
176 std::vector<T> X(R, zero), C(R, zero);
177 for (std::size_t r = 0; r < R; ++r) {
178 Q(lcfsStat - 1, r) = Q_l(0, r);
179 Q(lcfsprStat - 1, r) = Q_l(1, r);
180 U(lcfsStat - 1, r) = U_l(0, r);
181 U(lcfsprStat - 1, r) = U_l(1, r);
182 if (N[r] <= 0)
continue;
184 Tp(lcfsStat - 1, r) = T_l(0, r);
185 Tp(lcfsprStat - 1, r) = T_l(1, r);
187 for (std::size_t i : {lcfsStat, lcfsprStat})
188 for (std::size_t r = 0; r < R; ++r)
189 if (Tp(i - 1, r) > zero) Rt(i - 1, r) = T(Q(i - 1, r) / Tp(i - 1, r));
190 for (std::size_t r = 0; r < R; ++r)
191 if (N[r] > 0) C[r] = T(Rt(lcfsStat - 1, r) + Rt(lcfsprStat - 1, r));
200 out.
sol.method =
"lcfsqn.ca";