104 const std::vector<T>& Z,
const T& atol) {
105 const std::size_t M = L.
rows(), R = L.
cols();
106 if (M == 0 || R == 0)
throw InputError(
"pfqn_procomom: empty demand matrix");
107 if (N.size() != R)
throw InputError(
"pfqn_procomom: L and N disagree on the class count");
108 if (Z.size() != R)
throw InputError(
"pfqn_procomom: L and Z disagree on the class count");
113 for (std::size_t r = 0; r < R; ++r) {
114 if (N[r] < 0)
throw InputError(
"pfqn_procomom: negative population");
117 const std::size_t NP =
static_cast<std::size_t
>(sumN) + 1;
121 std::vector<T> Zs(R, zero);
122 for (std::size_t r = 0; r < R; ++r) {
124 for (std::size_t i = 1; i < M; ++i)
125 if (L(i, r) > mx) mx = L(i, r);
126 if (mx < atol) mx = one;
127 for (std::size_t i = 0; i < M; ++i)
Ls(i, r) = L(i, r) / mx;
131 const std::vector<std::vector<int>> Dn =
132 detail::comom_basis(
static_cast<int>(R),
static_cast<int>(M));
133 const std::size_t numDn = Dn.size();
134 const std::size_t basisSize = numDn * M;
135 const std::vector<int> zeroDn(R, 0);
138 const auto phash = [&](
const std::vector<int>& dn, std::size_t i) ->
long {
140 if (pos < 0)
return -1;
141 return static_cast<long>(pos) *
static_cast<long>(M) +
static_cast<long>(i) - 1;
146 res.
Q.assign(M, zero);
149 for (std::size_t station = 0; station < M; ++station) {
152 for (std::size_t r = 0; r < R; ++r) {
153 const T tmp = Lr(station, r);
154 Lr(station, r) = Lr(M - 1, r);
159 for (std::size_t kk = 1; kk <= M; ++kk) pk(static_cast<std::size_t>(phash(zeroDn, kk)), 0) = one;
161 std::vector<int> Ncur(R, 0);
162 for (std::size_t r = 0; r < R; ++r) {
163 for (
int Nr = 1; Nr <= N[r]; ++Nr) {
169 std::size_t numRows = 0;
170 for (std::size_t d = 0; d < numDn; ++d) {
173 for (std::size_t c = r; c + 1 < R; ++c) s1 += Dn[d][c];
174 if (r + 1 <= R - 1 && s1 > 0) {
178 for (std::size_t c = 0; c <= r; ++c) s3 += Dn[d][c];
179 numRows += (s3 < static_cast<int>(M)) ? (M + r) : 1;
182 Matrix<T> Ag(numRows, basisSize, zero), Bg(numRows, basisSize, zero),
183 DCg(numRows, basisSize, zero), DDg(numRows, basisSize, zero);
185 for (std::size_t d = 0; d < numDn; ++d) {
186 const std::vector<int>& dv = Dn[d];
189 for (std::size_t c = r; c + 1 < R; ++c) s1 += dv[c];
190 if (r + 1 <= R - 1 && s1 > 0) {
192 for (std::size_t c = r + 1; c + 1 < R; ++c) s2 += dv[c];
193 for (std::size_t k = 1; k <= M; ++k) {
194 const long cA = phash(dv, k);
195 Ag(row,
static_cast<std::size_t
>(cA)) = one;
197 Bg(row,
static_cast<std::size_t
>(cA)) = one;
199 std::vector<int> sh = dv;
201 const long cB = phash(sh, k);
202 if (cB >= 0) Bg(row,
static_cast<std::size_t
>(cB)) = one;
208 for (std::size_t c = 0; c <= r; ++c) s3 += dv[c];
209 if (s3 <
static_cast<int>(M)) {
210 for (std::size_t k = 1; k + 1 <= M; ++k) {
211 Ag(row,
static_cast<std::size_t
>(phash(dv, k + 1))) = one;
212 Ag(row,
static_cast<std::size_t
>(phash(dv, 1))) = -one;
213 for (std::size_t s = 0; s < r; ++s) {
214 std::vector<int> sh = dv;
216 const long c = phash(sh, k + 1);
217 if (c >= 0) Ag(row,
static_cast<std::size_t
>(c)) = -Lr(k - 1, s);
219 Bg(row,
static_cast<std::size_t
>(phash(dv, k + 1))) = Lr(k - 1, r);
222 for (std::size_t s = 0; s < r; ++s) {
223 Ag(row,
static_cast<std::size_t
>(phash(dv, 1))) =
225 std::vector<int> sh = dv;
227 const long cb = phash(sh, 1);
229 Ag(row,
static_cast<std::size_t
>(cb)) = -Zs[s];
230 DCg(row,
static_cast<std::size_t
>(cb)) = Lr(M - 1, s);
232 for (std::size_t k = 1; k + 1 <= M; ++k) {
233 const long c = phash(sh, k + 1);
234 if (c >= 0) Ag(row,
static_cast<std::size_t
>(c)) = -Lr(k - 1, s);
240 Ag(row,
static_cast<std::size_t
>(phash(dv, 1))) =
242 Bg(row,
static_cast<std::size_t
>(phash(dv, 1))) = Zs[r];
243 for (std::size_t k = 1; k + 1 <= M; ++k)
244 Bg(row,
static_cast<std::size_t
>(phash(dv, k + 1))) = Lr(k - 1, r);
245 DDg(row,
static_cast<std::size_t
>(phash(dv, 1))) = Lr(M - 1, r);
249 if (row != numRows)
throw NumericError(
"pfqn_procomom: row count mismatch");
253 for (
int x : Ncur) sumNcur += x;
254 const T tol = line::detail::lstsq_tolerance(Ag);
255 for (
int n = 0; n <= sumNcur; ++n) {
256 std::vector<T> rhs(numRows, zero);
257 for (std::size_t i = 0; i < numRows; ++i) {
259 for (std::size_t j = 0; j < basisSize; ++j)
260 s += Bg(i, j) * pklast(j,
static_cast<std::size_t
>(n));
263 T sc = zero, sd = zero;
264 for (std::size_t j = 0; j < basisSize; ++j) {
265 sc += DCg(i, j) * pk(j,
static_cast<std::size_t
>(n) - 1);
266 sd += DDg(i, j) * pklast(j,
static_cast<std::size_t
>(n) - 1);
268 s += nn * sc + nn * sd;
274 for (std::size_t j = 0; j < basisSize; ++j)
275 pk(j,
static_cast<std::size_t
>(n)) = sol.
x[j];
280 const std::size_t outRow =
static_cast<std::size_t
>(phash(zeroDn, 1));
282 for (std::size_t j = 0; j < NP; ++j) total += pk(outRow, j);
284 for (std::size_t j = 0; j < NP; ++j) res.
Pr(station, j) = pk(outRow, j) / total;
287 for (std::size_t i = 0; i < M; ++i) {
289 for (std::size_t j = 0; j < NP; ++j) q += num_traits<T>::from_int(
static_cast<long>(j)) * res.
Pr(i, j);
325 const std::vector<T>& Z,
const std::vector<T>& mu,
int m) {
326 const std::size_t R = L.size();
327 if (R == 0)
throw InputError(
"pfqn_procomom2: empty demand vector");
328 if (N.size() != R)
throw InputError(
"pfqn_procomom2: L and N disagree on the class count");
329 if (Z.size() != R)
throw InputError(
"pfqn_procomom2: L and Z disagree on the class count");
330 if (m < 1)
throw InputError(
"pfqn_procomom2: the multiplicity must be at least one");
335 for (std::size_t r = 0; r < R; ++r) {
336 if (N[r] < 0)
throw InputError(
"pfqn_procomom2: negative population");
339 const std::size_t dim =
static_cast<std::size_t
>(sumN) + 1;
342 std::vector<T> mu_(dim, one);
344 if (mu.size() <
static_cast<std::size_t
>(sumN))
345 throw InputError(
"pfqn_procomom2: mu must supply a rate for every population up to sum(N)");
346 for (std::size_t n = 1; n < dim; ++n) {
347 if (mu[n - 1] <= zero)
348 throw InputError(
"pfqn_procomom2: the load-dependent rates must be positive");
355 for (std::size_t r = 0; r < R; ++r) {
357 for (
int n = sumN; n >= 1; --n) {
358 const std::size_t row =
static_cast<std::size_t
>(sumN - n);
363 Tm(dim - 1, dim - 1) = Z[r];
364 res.
Tr.push_back(Tm);
369 for (std::size_t i = 0; i < dim; ++i)
370 for (std::size_t k = 0; k < dim; ++k) {
371 if (A(i, k) == zero)
continue;
372 for (std::size_t j = 0; j < dim; ++j) C(i, j) += A(i, k) * Bm(k, j);
377 Matrix<T> F(dim, dim, zero), B(dim, dim, zero);
378 for (std::size_t i = 0; i < dim; ++i) {
382 for (std::size_t r = 0; r < R; ++r) {
384 for (std::size_t i = 0; i < dim; ++i) P(i, i) = one;
385 for (
int e = 0; e < N[r]; ++e) P =
matmul(P, res.
Tr[r]);
387 for (std::size_t i = 0; i < dim; ++i)
388 for (std::size_t j = 0; j < dim; ++j) P(i, j) /= fac;
396 std::vector<T> v(dim, zero);
397 for (std::size_t i = 0; i < dim; ++i) v[i] = F(i, dim - 1);
399 for (std::size_t i = 0; i < dim; ++i) G += v[i];
402 res.
pk.assign(dim, zero);
404 for (std::size_t i = 0; i < dim; ++i) res.
pk[dim - 1 - i] = v[i] / G;