84 "pfqn_ld_is requires transcendental arithmetic: it is a Monte Carlo estimator, "
85 "inexact by construction, and reports the log of its own estimate");
87 const std::size_t M = L.
empty() ? 0 : L.
rows();
88 const std::size_t R = N.size();
90 throw InputError(
"pfqn_ld_is: L must have as many columns as N has classes");
91 if (!Z.empty() && Z.size() != R)
throw InputError(
"pfqn_ld_is: Z has the wrong length");
93 if (n < 0)
throw InputError(
"pfqn_ld_is: negative population");
94 if (samples == 0)
throw InputError(
"pfqn_ld_is: at least one sample is required");
100 for (
int n : N) ell_l += n;
101 if (ell_l == 0)
return {one, 0.0};
102 const std::size_t ell =
static_cast<std::size_t
>(ell_l);
106 for (std::size_t r = 0; r < Z.size(); ++r)
107 if (Z[r] > zero) hasZ =
true;
108 const std::size_t S = M + (hasZ ? 1u : 0u);
109 if (S == 0)
throw InputError(
"pfqn_ld_is: no station carries any demand");
113 for (std::size_t i = 0; i < M; ++i) {
114 for (std::size_t r = 0; r < R; ++r) D(i, r) = L(i, r);
115 if (mu.
empty())
continue;
116 if (mu.
rows() != M)
throw InputError(
"pfqn_ld_is: mu has the wrong station count");
117 const std::size_t kmax = mu.
cols() < ell ? mu.
cols() : ell;
118 for (std::size_t k = 0; k < kmax; ++k) B(i, k) = mu(i, k);
119 for (std::size_t k = kmax; k < ell; ++k) B(i, k) = mu(i, mu.
cols() - 1);
122 for (std::size_t r = 0; r < R; ++r) D(S - 1, r) = Z[r];
125 for (std::size_t i = 0; i < S; ++i)
126 for (std::size_t k = 0; k < ell; ++k)
127 if (!(B(i, k) > zero))
128 throw InputError(
"pfqn_ld_is: load-dependent capacities must be strictly positive");
131 std::vector<int> x(R);
132 std::vector<std::size_t> c(ell);
133 std::vector<std::size_t> avail(R);
134 std::vector<T> A(ell + 1), Anew(ell + 1);
136 for (std::size_t s = 0; s < samples; ++s) {
140 for (std::size_t p = 0; p < ell; ++p) {
142 for (std::size_t r = 0; r < R; ++r)
143 if (x[r] > 0) avail[na++] = r;
151 A.assign(ell + 1, zero);
153 for (std::size_t m = 0; m < S; ++m) {
154 Anew.assign(ell + 1, zero);
155 for (std::size_t j = 0; j <= ell; ++j) {
156 if (A[j] == zero)
continue;
159 for (std::size_t k = j; k < ell; ++k) {
160 w *= D(m, c[k]) / B(m, k - j);
161 if (w == zero)
break;
162 Anew[k + 1] += A[j] * w;
167 acc += A[ell] * invp;
NcResult< T > pfqn_ld_is(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const Matrix< T > &mu, std::size_t samples, McRng &rng)
Importance-sampling estimate of the normalizing constant of a closed LOAD-DEPENDENT product-form netw...