82 const std::vector<int>& N) {
83 const std::size_t R = alpha.size();
84 if (beta.size() != R)
throw InputError(
"pfqn_lcfsqn_mva: alpha and beta have different lengths");
85 if (N.size() != R)
throw InputError(
"pfqn_lcfsqn_mva: alpha and N have different lengths");
91 res.
T_.assign(R, zero);
98 if (v < 0)
throw InputError(
"pfqn_lcfsqn_mva: negative population");
101 if (K == 0)
return res;
102 for (std::size_t r = 0; r < R; ++r)
103 if (!(alpha[r] > zero))
throw InputError(
"pfqn_lcfsqn_mva: a service time at the LCFS "
104 "station is not positive");
106 const std::vector<std::size_t> prods =
plane_sizes(N);
109 std::vector<T> Q(total * 2 * R, zero), B(total * 2 * R, zero), Tp(total * R, zero);
110 const auto QB = [&](std::vector<T>& v, std::size_t idx, std::size_t s, std::size_t r) -> T& {
111 return v[idx * 2 * R + s * R + r];
114 std::vector<int> n(R, 0);
117 const std::size_t idx =
pop_index(n, prods);
119 for (
int v : n) tot += v;
123 for (std::size_t r = 0; r < R; ++r)
124 A *=
num_pow_int(alpha[r],
static_cast<unsigned>(n[r]));
127 for (std::size_t k = 0; k < R; ++k) {
128 if (n[k] == 0)
continue;
129 const std::size_t ik = idx - prods[k];
130 T wnp = one + QB(Q, ik, 0, k);
131 T wpr = one + QB(Q, ik, 1, k);
132 for (std::size_t r = 0; r < R; ++r) {
133 if (r == k || n[r] == 0)
continue;
134 const std::size_t ir = idx - prods[r];
135 const T dnp = QB(B, ir, 0, k);
136 const T dpr = QB(B, ir, 1, k);
137 if (dnp == zero || dpr == zero)
138 throw NumericError(
"pfqn_lcfsqn_mva: a back probability vanished");
139 wnp += alpha[k] / alpha[r] * (QB(B, ik, 0, r) / dnp) * QB(Q, ir, 0, k);
140 wpr += alpha[r] / alpha[k] * (QB(B, ik, 1, r) / dpr) * QB(Q, ir, 1, k);
142 const T Apr =
num_pow_int(alpha[k],
static_cast<unsigned>(tot - 1)) * beta[k];
143 const T W = A * wnp + Apr * wpr;
144 if (W == zero)
throw NumericError(
"pfqn_lcfsqn_mva: zero total waiting time");
146 QB(B, idx, 0, k) = A * nk / W;
147 QB(B, idx, 1, k) = Apr * nk / W;
151 for (std::size_t k = 0; k < R; ++k) {
152 if (n[k] == 0)
continue;
153 for (std::size_t s = 0; s < 2; ++s) {
154 T q = QB(B, idx, s, k);
155 for (std::size_t r = 0; r < R; ++r) {
156 if (n[r] == 0)
continue;
157 q += QB(B, idx, s, r) * QB(Q, idx - prods[r], s, k);
159 QB(Q, idx, s, k) = q;
164 for (std::size_t k = 0; k < R; ++k) {
165 if (n[k] == 0)
continue;
166 const std::size_t ik = idx - prods[k];
168 for (std::size_t r = 0; r < R; ++r) unp += alpha[r] * Tp[ik * R + r];
169 T t = QB(B, idx, 0, k) * (one - unp) / alpha[k];
170 for (std::size_t r = 0; r < R; ++r) {
171 if (n[r] == 0)
continue;
172 t += QB(B, idx, 0, r) * Tp[(idx - prods[r]) * R + k];
180 const std::size_t last = total - 1;
181 for (std::size_t r = 0; r < R; ++r) {
182 res.
T_[r] = Tp[last * R + r];
183 for (std::size_t s = 0; s < 2; ++s) {
184 res.
Q(s, r) = QB(Q, last, s, r);
185 res.
B(s, r) = QB(B, last, s, r);
187 res.
U(0, r) = res.
T_[r] * alpha[r];
188 res.
U(1, r) = res.
T_[r] * beta[r];