63 const std::vector<int>& N,
const std::vector<T>& Z,
64 const Matrix<T>& mu,
const std::vector<int>& groups) {
65 const std::size_t M = D.
rows();
66 const std::size_t R = D.
cols();
67 if (lambda.size() != R || N.size() != R || Z.size() != R)
68 throw InputError(
"pfqn_sens_momldmx: lambda, N, Z and D disagree on the class count");
70 throw InputError(
"pfqn_sens_momldmx: mu and D disagree on the station count");
72 std::vector<int> grp = groups.empty() ? std::vector<int>(R, 0) : groups;
74 throw InputError(
"pfqn_sens_momldmx: groups must have one label per class");
77 if (g < 0)
throw InputError(
"pfqn_sens_momldmx: group labels start at zero");
78 if (
static_cast<std::size_t
>(g) + 1 > G) G =
static_cast<std::size_t
>(g) + 1;
81 std::vector<bool> seen(G,
false);
82 for (
int g : grp) seen[
static_cast<std::size_t
>(g)] =
true;
83 for (std::size_t g = 0; g < G; ++g)
86 "pfqn_sens_momldmx: groups must label the classes consecutively with no empty group");
93 std::vector<std::size_t> openClasses, closedClasses;
94 for (std::size_t r = 0; r < R; ++r) {
96 openClasses.push_back(r);
98 if (lambda[r] != zero && N[r] > 0)
99 throw InputError(
"pfqn_sens_momldmx: an arrival rate cannot be set on a closed class");
100 closedClasses.push_back(r);
103 const std::size_t Cn = closedClasses.size();
105 std::vector<int> Nc(Cn, 0);
106 std::vector<T> Zc(Cn, zero);
109 for (std::size_t c = 0; c < Cn; ++c) {
110 Nc[c] = N[closedClasses[c]];
111 Zc[c] = Z[closedClasses[c]];
113 for (std::size_t i = 0; i < M; ++i) Dc(i, c) = D(i, closedClasses[c]);
115 if (
static_cast<int>(mu.
cols()) < (NCtot > 1 ? NCtot : 1))
117 "pfqn_sens_momldmx: the load-dependent rates must be given up to the maximum closed "
121 for (std::size_t i = 0; i < M; ++i) {
122 for (std::size_t k = 0; k < mu.
cols(); ++k) mux(i, k) = mu(i, k);
123 mux(i, mu.
cols()) = mu(i, mu.
cols() - 1);
128 const std::size_t P = M * G;
129 const auto pidx = [&](std::size_t h, std::size_t g) {
return h * G + g; };
132 for (std::size_t j = 0; j < M; ++j)
133 for (std::size_t oi = 0; oi < openClasses.size(); ++oi) {
134 const std::size_t o = openClasses[oi];
135 dLo(j, pidx(j,
static_cast<std::size_t
>(grp[o]))) += lambda[o] * D(j, o);
139 const std::vector<std::size_t> prods =
plane_sizes(Nc);
141 const std::size_t NL =
static_cast<std::size_t
>(NCtot) + 1;
143 std::vector<Matrix<T>> Pc(NT,
Matrix<T>(M, NL, zero));
144 std::vector<std::vector<Matrix<T>>> dPc(NT, std::vector<
Matrix<T>>(M,
Matrix<T>(NL, P, zero)));
145 std::vector<std::vector<Matrix<T>>> d2Pc(NT, std::vector<
Matrix<T>>(M,
Matrix<T>(NL, P, zero)));
147 std::vector<Matrix<T>> dx(NT,
Matrix<T>(Cn, P, zero));
148 std::vector<Matrix<T>> d2x(NT,
Matrix<T>(Cn, P, zero));
149 std::vector<Matrix<T>> w(NT,
Matrix<T>(M, Cn, zero));
150 std::vector<std::vector<Matrix<T>>> dw(NT, std::vector<
Matrix<T>>(M,
Matrix<T>(Cn, P, zero)));
151 std::vector<std::vector<Matrix<T>>> d2w(NT, std::vector<
Matrix<T>>(M,
Matrix<T>(Cn, P, zero)));
153 for (std::size_t i = 0; i < M; ++i) Pc[0](i, 0) = one;
155 std::vector<T> dacc(P, zero), d2acc(P, zero);
156 for (std::size_t k = 0; k < NT; ++k) {
157 std::vector<int> nvec(Cn, 0);
159 for (std::size_t c = 0; c < Cn; ++c) {
160 nvec[c] =
static_cast<int>((k / prods[c]) %
static_cast<std::size_t
>(Nc[c] + 1));
163 if (
nc == 0)
continue;
166 for (std::size_t i = 0; i < M; ++i) {
167 for (std::size_t c = 0; c < Cn; ++c) {
168 if (nvec[c] <= 0)
continue;
169 const std::size_t kc = k - prods[c];
170 const std::size_t pc = pidx(i,
static_cast<std::size_t
>(grp[closedClasses[c]]));
172 for (std::size_t p = 0; p < P; ++p) {
176 for (
int n = 1; n <=
nc; ++n) {
177 const std::size_t nu =
static_cast<std::size_t
>(n);
178 const T Pp = Pc[kc](i, nu - 1);
180 const T ECn = ec.
EC(i, nu - 1);
181 const T dECn = ec.
dEC(i, nu - 1);
182 const T d2ECn = ec.
d2EC(i, nu - 1);
183 acc += nT * ECn * Pp;
184 for (std::size_t p = 0; p < P; ++p) {
185 const T dL = dLo(i, p);
186 const T dPp = dPc[kc][i](nu - 1, p);
187 dacc[p] += nT * (dECn * dL * Pp + ECn * dPp);
188 d2acc[p] += nT * (d2ECn * dL * dL * Pp + two * dECn * dL * dPp +
189 ECn * d2Pc[kc][i](nu - 1, p));
192 w[k](i, c) = Dc(i, c) * acc;
193 for (std::size_t p = 0; p < P; ++p) {
195 dw[k][i](c, p) = Dc(i, c) * (dacc[p] + acc);
196 d2w[k][i](c, p) = Dc(i, c) * (d2acc[p] + two * dacc[p]);
198 dw[k][i](c, p) = Dc(i, c) * dacc[p];
199 d2w[k][i](c, p) = Dc(i, c) * d2acc[p];
206 for (std::size_t c = 0; c < Cn; ++c) {
208 for (std::size_t i = 0; i < M; ++i) sw += w[k](i, c);
209 const T den = Zc[c] + sw;
217 const T den2 = den * den;
218 const T den3 = den2 * den;
219 for (std::size_t p = 0; p < P; ++p) {
220 T sdw = zero, sd2w = zero;
221 for (std::size_t i = 0; i < M; ++i) {
222 sdw += dw[k][i](c, p);
223 sd2w += d2w[k][i](c, p);
225 dx[k](c, p) = -nT * sdw / den2;
226 d2x[k](c, p) = -nT * sd2w / den2 + two * nT * sdw * sdw / den3;
232 for (std::size_t i = 0; i < M; ++i) {
233 for (
int n = 1; n <=
nc; ++n) {
234 const std::size_t nu =
static_cast<std::size_t
>(n);
235 for (std::size_t c = 0; c < Cn; ++c) {
236 if (nvec[c] <= 0)
continue;
237 const std::size_t kc = k - prods[c];
238 const std::size_t pc = pidx(i,
static_cast<std::size_t
>(grp[closedClasses[c]]));
239 const T Pp = Pc[kc](i, nu - 1);
240 const T ECn = ec.
EC(i, nu - 1);
241 const T dECn = ec.
dEC(i, nu - 1);
242 const T d2ECn = ec.
d2EC(i, nu - 1);
243 const T xc = x(k, c);
244 const T t = ECn * xc * Pp;
245 Pc[k](i, nu) += Dc(i, c) * t;
246 for (std::size_t p = 0; p < P; ++p) {
247 const T dL = dLo(i, p);
248 const T dE1 = dECn * dL;
249 const T d2E1 = d2ECn * dL * dL;
250 const T dxc = dx[k](c, p);
251 const T dPp = dPc[kc][i](nu - 1, p);
252 const T dt = dE1 * xc * Pp + ECn * dxc * Pp + ECn * xc * dPp;
253 const T d2t = d2E1 * xc * Pp + ECn * d2x[k](c, p) * Pp +
254 ECn * xc * d2Pc[kc][i](nu - 1, p) +
255 two * (dE1 * dxc * Pp + dE1 * xc * dPp + ECn * dxc * dPp);
257 dPc[k][i](nu, p) += Dc(i, c) * (dt + t);
258 d2Pc[k][i](nu, p) += Dc(i, c) * (d2t + two * dt);
260 dPc[k][i](nu, p) += Dc(i, c) * dt;
261 d2Pc[k][i](nu, p) += Dc(i, c) * d2t;
268 for (
int n = 1; n <= nc; ++n) s1 += Pc[k](i, static_cast<std::size_t>(n));
270 const T p0 = one - s1;
271 Pc[k](i, 0) = p0 > epsT ? p0 : epsT;
272 for (std::size_t p = 0; p < P; ++p) {
273 T ds = zero, d2s = zero;
274 for (
int n = 1; n <=
nc; ++n) {
275 ds += dPc[k][i](
static_cast<std::size_t
>(n), p);
276 d2s += d2Pc[k][i](
static_cast<std::size_t
>(n), p);
278 dPc[k][i](0, p) = -ds;
279 d2Pc[k][i](0, p) = -d2s;
285 const std::size_t kN = NT - 1;
287 res.
XN.assign(R, zero);
291 std::vector<Matrix<T>> dQN(P,
Matrix<T>(M, R, zero));
292 std::vector<Matrix<T>> d2QN(P,
Matrix<T>(M, R, zero));
295 for (std::size_t c = 0; c < Cn; ++c) {
296 const std::size_t cls = closedClasses[c];
297 res.
XN[cls] = x(kN, c);
298 const std::size_t kc = Nc[c] > 0 ? kN - prods[c] : kN;
299 for (std::size_t i = 0; i < M; ++i) {
300 res.
CN(i, cls) = w[kN](i, c);
301 res.
QN(i, cls) = res.
XN[cls] * res.
CN(i, cls);
302 for (std::size_t p = 0; p < P; ++p) {
303 dQN[p](i, cls) = dx[kN](c, p) * w[kN](i, c) + x(kN, c) * dw[kN][i](c, p);
304 d2QN[p](i, cls) = d2x[kN](c, p) * w[kN](i, c) + two * dx[kN](c, p) * dw[kN][i](c, p) +
305 x(kN, c) * d2w[kN][i](c, p);
309 for (
int n = 1; n <= NCtot; ++n) {
310 const std::size_t nu =
static_cast<std::size_t
>(n);
311 uacc += Dc(i, c) * x(kN, c) * ec.
Eprime(i, nu - 1) / ec.
E(i, nu - 1) *
314 res.
UN(i, cls) = uacc;
320 for (std::size_t oi = 0; oi < openClasses.size(); ++oi) {
321 const std::size_t r = openClasses[oi];
322 res.
XN[r] = lambda[r];
323 for (std::size_t i = 0; i < M; ++i) {
324 const std::size_t pr = pidx(i,
static_cast<std::size_t
>(grp[r]));
326 for (std::size_t p = 0; p < P; ++p) {
330 for (
int n = 0; n <= NCtot; ++n) {
331 const std::size_t nu =
static_cast<std::size_t
>(n);
332 const T Pn = Pc[kN](i, nu);
334 const T ECn = ec.
EC(i, nu);
335 const T dECn = ec.
dEC(i, nu);
336 const T d2ECn = ec.
d2EC(i, nu);
337 acc += nT * ECn * Pn;
338 for (std::size_t p = 0; p < P; ++p) {
339 const T dL = dLo(i, p);
340 const T dPn = dPc[kN][i](nu, p);
341 dacc[p] += nT * (dECn * dL * Pn + ECn * dPn);
342 d2acc[p] += nT * (d2ECn * dL * dL * Pn + two * dECn * dL * dPn +
343 ECn * d2Pc[kN][i](nu, p));
346 const T scale = lambda[r] * D(i, r);
347 res.
QN(i, r) = scale * acc;
348 if (lambda[r] != zero) res.
CN(i, r) = res.
QN(i, r) / lambda[r];
349 for (std::size_t p = 0; p < P; ++p) {
351 dQN[p](i, r) = scale * (dacc[p] + acc);
352 d2QN[p](i, r) = scale * (d2acc[p] + two * dacc[p]);
354 dQN[p](i, r) = scale * dacc[p];
355 d2QN[p](i, r) = scale * d2acc[p];
359 for (
int n = 0; n <= NCtot; ++n) {
360 const std::size_t nu =
static_cast<std::size_t
>(n);
361 uacc += lambda[r] * ec.
Eprime(i, nu + 1) / ec.
E(i, nu + 1) * Pc[kN](i, nu);
377 for (std::size_t i = 0; i < M; ++i)
378 for (std::size_t r = 0; r < R; ++r) {
379 const std::size_t g =
static_cast<std::size_t
>(grp[r]);
380 res.
m(i, g) += res.
QN(i, r);
381 for (std::size_t j = 0; j < M; ++j)
382 for (std::size_t g2 = 0; g2 < G; ++g2)
383 res.
dm(pidx(i, g), pidx(j, g2)) += dQN[pidx(j, g2)](i, r);
384 res.
d2m(i, g) += d2QN[pidx(i, g)](i, r);
386 for (std::size_t a = 0; a < P; ++a)
387 for (std::size_t b = 0; b < P; ++b) {
388 const T d =
num_abs(T(res.
dm(a, b) - res.
dm(b, a)));
391 for (std::size_t a = 0; a < P; ++a)
392 for (std::size_t b = 0; b < P; ++b) res.
Cov(a, b) = (res.
dm(a, b) + res.
dm(b, a)) / two;
393 for (std::size_t i = 0; i < M; ++i)
394 for (std::size_t g = 0; g < G; ++g) {
395 const T d1 = res.
dm(pidx(i, g), pidx(i, g));
396 const T mg = res.
m(i, g);
398 res.
M2(i, g) = d1 + mg * mg;