87 const std::vector<int>& N,
const std::vector<T>& Z,
89 const std::size_t M = D.
rows();
90 const std::size_t R = D.
cols();
91 if (lambda.size() != R || N.size() != R || Z.size() != R)
92 throw InputError(
"pfqn_sens_mvaldmx: lambda, N, Z and D disagree on the class count");
94 throw InputError(
"pfqn_sens_mvaldmx: mu and D disagree on the station count");
99 std::vector<std::size_t> openClasses, closedClasses;
100 for (std::size_t r = 0; r < R; ++r) {
102 openClasses.push_back(r);
104 if (lambda[r] != zero && N[r] > 0)
105 throw InputError(
"pfqn_sens_mvaldmx: an arrival rate cannot be set on a closed class");
106 closedClasses.push_back(r);
109 const std::size_t Cn = closedClasses.size();
112 "pfqn_sens_mvaldmx: at least one closed class is required; use the open-class formulas "
113 "directly otherwise");
115 std::vector<int> Nc(Cn, 0);
116 std::vector<T> Zc(Cn, zero);
119 for (std::size_t c = 0; c < Cn; ++c) {
120 Nc[c] = N[closedClasses[c]];
121 Zc[c] = Z[closedClasses[c]];
123 for (std::size_t i = 0; i < M; ++i) Dc(i, c) = D(i, closedClasses[c]);
125 if (
static_cast<int>(mu.
cols()) < NCtot)
127 "pfqn_sens_mvaldmx: the load-dependent rates must be given up to the maximum closed "
133 for (std::size_t i = 0; i < M; ++i) {
134 for (std::size_t k = 0; k < mu.
cols(); ++k) mux(i, k) = mu(i, k);
135 mux(i, mu.
cols()) = mu(i, mu.
cols() - 1);
140 const std::size_t P = M * R;
141 const auto pidx = [&](std::size_t j, std::size_t r) {
return j * R + r; };
144 for (std::size_t j = 0; j < M; ++j)
145 for (std::size_t r = 0; r < R; ++r)
146 if (N[r] < 0) dLo(j, pidx(j, r)) = lambda[r] * D(j, r);
149 const std::vector<std::size_t> prods =
plane_sizes(Nc);
151 const std::size_t NL =
static_cast<std::size_t
>(NCtot) + 1;
153 std::vector<Matrix<T>> Pc(NT,
Matrix<T>(M, NL, zero));
154 std::vector<std::vector<Matrix<T>>> dPc(NT, std::vector<
Matrix<T>>(M,
Matrix<T>(NL, P, zero)));
156 std::vector<Matrix<T>> dx(NT,
Matrix<T>(Cn, P, zero));
157 std::vector<Matrix<T>> w(NT,
Matrix<T>(M, Cn, zero));
158 std::vector<std::vector<Matrix<T>>> dw(NT, std::vector<
Matrix<T>>(M,
Matrix<T>(Cn, P, zero)));
160 for (std::size_t i = 0; i < M; ++i) Pc[0](i, 0) = one;
162 std::vector<T> dacc(P, zero);
163 for (std::size_t k = 0; k < NT; ++k) {
164 std::vector<int> nvec(Cn, 0);
166 for (std::size_t c = 0; c < Cn; ++c) {
167 nvec[c] =
static_cast<int>((k / prods[c]) %
static_cast<std::size_t
>(Nc[c] + 1));
172 for (std::size_t i = 0; i < M; ++i) {
173 for (std::size_t c = 0; c < Cn; ++c) {
174 if (nvec[c] <= 0)
continue;
175 const std::size_t kc = k - prods[c];
176 const std::size_t cls = closedClasses[c];
178 for (std::size_t p = 0; p < P; ++p) dacc[p] = zero;
179 for (
int n = 1; n <=
nc; ++n) {
180 const T Pprev = Pc[kc](i,
static_cast<std::size_t
>(n - 1));
182 acc += nT * ec.
EC(i,
static_cast<std::size_t
>(n - 1)) * Pprev;
183 for (std::size_t p = 0; p < P; ++p)
184 dacc[p] += nT * (ec.
dEC(i,
static_cast<std::size_t
>(n - 1)) * dLo(i, p) * Pprev +
185 ec.
EC(i,
static_cast<std::size_t
>(n - 1)) *
186 dPc[kc][i](
static_cast<std::size_t
>(n - 1), p));
188 w[k](i, c) = Dc(i, c) * acc;
189 for (std::size_t p = 0; p < P; ++p) {
190 T dwq = Dc(i, c) * dacc[p];
191 if (p == pidx(i, cls)) dwq += Dc(i, c) * acc;
192 dw[k][i](c, p) = dwq;
198 for (std::size_t c = 0; c < Cn; ++c) {
200 for (std::size_t i = 0; i < M; ++i) sw += w[k](i, c);
201 const T den = Zc[c] + sw;
209 const T den2 = den * den;
210 for (std::size_t p = 0; p < P; ++p) {
212 for (std::size_t i = 0; i < M; ++i) sdw += dw[k][i](c, p);
213 dx[k](c, p) = -nT / den2 * sdw;
219 for (std::size_t i = 0; i < M; ++i) {
220 for (
int n = 1; n <=
nc; ++n) {
221 const std::size_t nu =
static_cast<std::size_t
>(n);
222 for (std::size_t c = 0; c < Cn; ++c) {
223 if (nvec[c] <= 0)
continue;
224 const std::size_t kc = k - prods[c];
225 const std::size_t cls = closedClasses[c];
226 const T Pprev = Pc[kc](i, nu - 1);
227 const T ECn = ec.
EC(i, nu - 1);
228 Pc[k](i, nu) += Dc(i, c) * ECn * x(k, c) * Pprev;
229 for (std::size_t p = 0; p < P; ++p) {
230 T dt = Dc(i, c) * (ec.
dEC(i, nu - 1) * dLo(i, p) * x(k, c) * Pprev +
231 ECn * dx[k](c, p) * Pprev +
232 ECn * x(k, c) * dPc[kc][i](nu - 1, p));
233 if (p == pidx(i, cls)) dt += Dc(i, c) * ECn * x(k, c) * Pprev;
234 dPc[k][i](nu, p) += dt;
240 for (
int n = 1; n <= nc; ++n) s1 += Pc[k](i, static_cast<std::size_t>(n));
242 const T p0 = one - s1;
243 Pc[k](i, 0) = p0 > epsT ? p0 : epsT;
244 for (std::size_t p = 0; p < P; ++p) {
246 for (
int n = 1; n <= nc; ++n) ds += dPc[k][i](static_cast<std::size_t>(n), p);
247 dPc[k][i](0, p) = -ds;
253 const std::size_t kN = NT - 1;
255 res.
XN.assign(R, zero);
259 std::vector<Matrix<T>> dQN(P,
Matrix<T>(M, R, zero));
262 for (std::size_t c = 0; c < Cn; ++c) {
263 const std::size_t cls = closedClasses[c];
264 res.
XN[cls] = x(kN, c);
265 const std::size_t kc = Nc[c] > 0 ? kN - prods[c] : kN;
266 for (std::size_t i = 0; i < M; ++i) {
267 res.
CN(i, cls) = w[kN](i, c);
268 res.
QN(i, cls) = res.
XN[cls] * res.
CN(i, cls);
269 for (std::size_t p = 0; p < P; ++p)
270 dQN[p](i, cls) = dx[kN](c, p) * w[kN](i, c) + x(kN, c) * dw[kN][i](c, p);
272 for (
int n = 1; n <= NCtot; ++n) {
273 const std::size_t nu =
static_cast<std::size_t
>(n);
274 uacc += Dc(i, c) * x(kN, c) * ec.
Eprime(i, nu - 1) / ec.
E(i, nu - 1) *
277 res.
UN(i, cls) = uacc;
282 for (std::size_t oi = 0; oi < openClasses.size(); ++oi) {
283 const std::size_t r = openClasses[oi];
284 res.
XN[r] = lambda[r];
285 for (std::size_t i = 0; i < M; ++i) {
287 for (std::size_t p = 0; p < P; ++p) dacc[p] = zero;
288 for (
int n = 0; n <= NCtot; ++n) {
289 const std::size_t nu =
static_cast<std::size_t
>(n);
290 const T Pn = Pc[kN](i, nu);
292 acc += nT * ec.
EC(i, nu) * Pn;
293 for (std::size_t p = 0; p < P; ++p)
294 dacc[p] += nT * (ec.
dEC(i, nu) * dLo(i, p) * Pn +
295 ec.
EC(i, nu) * dPc[kN][i](nu, p));
297 res.
QN(i, r) = lambda[r] * D(i, r) * acc;
298 if (lambda[r] != zero) res.
CN(i, r) = res.
QN(i, r) / lambda[r];
299 for (std::size_t p = 0; p < P; ++p) {
300 T dq = lambda[r] * D(i, r) * dacc[p];
301 if (p == pidx(i, r)) dq += lambda[r] * D(i, r) * acc;
305 for (
int n = 0; n <= NCtot; ++n) {
306 const std::size_t nu =
static_cast<std::size_t
>(n);
307 uacc += lambda[r] * ec.
Eprime(i, nu + 1) / ec.
E(i, nu + 1) * Pc[kN](i, nu);
315 for (std::size_t i = 0; i < M; ++i)
316 for (std::size_t r = 0; r < R; ++r)
317 for (std::size_t j = 0; j < M; ++j)
318 for (std::size_t s = 0; s < R; ++s)
319 res.
QCovFull(i * R + r, j * R + s) = dQN[pidx(j, s)](i, r);
321 for (std::size_t a = 0; a < M * R; ++a)
322 for (std::size_t b = 0; b < M * R; ++b) {
326 for (std::size_t a = 0; a < M * R; ++a)
327 for (std::size_t b = a + 1; b < M * R; ++b) {
336 for (std::size_t i = 0; i < M; ++i) {
338 for (std::size_t r = 0; r < R; ++r) {
339 for (std::size_t s = 0; s < R; ++s) {
341 tot += res.
QCov[i](r, s);