5#ifndef LINE_API_PFQN_MCI_H
6#define LINE_API_PFQN_MCI_H
97 "pfqn_mci requires transcendental arithmetic: it is a Monte Carlo estimator over "
98 "an exponential proposal, its integrand is evaluated in the log domain, and its "
99 "proposal rates come from a tolerance-stopped Bard-Schweitzer solve");
101 const std::size_t M = D.
empty() ? 0 : D.
rows();
102 const std::size_t R = N.size();
104 throw InputError(
"pfqn_mci: D and N disagree on the class count");
105 if (!Z.empty() && Z.size() != R)
throw InputError(
"pfqn_mci: Z has the wrong length");
107 if (n < 0)
throw InputError(
"pfqn_mci: negative population");
108 if (samples == 0)
throw InputError(
"pfqn_mci: at least one sample is required");
111 std::vector<T> Zv(R, zero);
112 for (std::size_t r = 0; r < Z.size(); ++r) Zv[r] = Z[r];
116 for (std::size_t i = 0; i < M; ++i)
117 for (std::size_t r = 0; r < R; ++r) dsum += D(i, r);
120 for (std::size_t r = 0; r < R; ++r) {
128 std::vector<double> gamma(M);
132 "pfqn_mci: the 'rm' variant is defined only for a single station; for M > 1 the "
133 "reference's rate expression broadcasts a (1 x R) row against an (M x R) matrix "
134 "and reads gamma off the wrong axis, so nothing faithful can be computed");
139 if (n > Nmax) Nmax = n;
142 for (std::size_t r = 0; r < R; ++r) {
145 if (den == zero)
throw NumericError(
"pfqn_mci: zero denominator in the 'rm' bound");
149 gamma[0] = u > 0.9 ? 1.0 / std::sqrt(
static_cast<double>(Nmax)) : 1.0 - u;
151 std::vector<T> Nt(R), Zt(R);
152 for (std::size_t r = 0; r < R; ++r) {
159 if (n > Nmax) Nmax = n;
160 for (std::size_t i = 0; i < M; ++i) {
162 for (std::size_t r = 0; r < R; ++r)
util += D(i, r) * bs.
XN[r];
165 gamma[i] = 1.0 - u > 0.01 ? 1.0 - u : 0.01;
167 gamma[i] = u > 0.9 ? 1.0 / std::sqrt(
static_cast<double>(Nmax)) : 1.0 - u;
171 for (std::size_t i = 0; i < M; ++i)
172 if (!(gamma[i] > 0.0))
174 "pfqn_mci: a proposal rate is non-positive, the station is saturated beyond what "
175 "the variant's clamp covers");
179 for (std::size_t i = 0; i < M; ++i) lconst -= std::log(gamma[i]);
182 std::vector<double> lZ(samples);
184 for (std::size_t s = 0; s < samples; ++s) {
186 for (std::size_t i = 0; i < M; ++i) {
188 if (u <= 0.0) u = 1.0 / 9007199254740992.0;
189 const double v = -std::log(u) / gamma[i];
191 lz -= (1.0 - gamma[i]) * v;
193 for (std::size_t r = 0; r < R; ++r) {
194 if (N[r] == 0)
continue;
196 for (std::size_t i = 0; i < M; ++i) inner += V[i] * D(i, r);
203 if (!std::isfinite(lG)) {
206 double m = -std::numeric_limits<double>::infinity();
NumericError(const std::string &what)
UnsupportedError(const std::string &what)
The exception types the port throws.
Dense matrix and non-owning view.
NcResult< T > pfqn_mci(const Matrix< T > &D, const std::vector< int > &N, const std::vector< T > &Z, std::size_t samples, MciVariant variant, McRng &rng)
Monte Carlo Integration estimate of the normalizing constant of a closed product-form network (Ross,...
double mc_log_factorial(long n)
log(n!) for a non-negative integer n, the factln / gammaln(1+n) of the references,...
std::mt19937_64 McRng
The generator type every Monte Carlo entry point in this tree accepts.
double mc_logmeanexp(const std::vector< double > &v)
log(mean(exp(v))), computed by factoring out the maximum so that the exponentials stay in range.
double mc_uniform01(McRng &g)
Uniform deviate on [0,1) with 53 significant bits, as a double.
MciVariant
The proposal-rate rules the reference selects between.
@ Imci
gamma = max(0.01, 1 - U), the MonteQueue 2.0 recommendation
@ Mci
gamma = 1/sqrt(max N) where U > 0.9, else 1 - U
@ Rm
repairman: a single station, rates from the balanced bound
AmvaResult< T > pfqn_bs(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z, const std::vector< AmvaSched > &type, double tol=1e-6, std::size_t maxiter=1000, const Matrix< T > &QN0=Matrix< T >())
Bard-Schweitzer approximate MVA.
T mc_exp(double lv)
exp of a log-domain value, materialized in the working arithmetic.
Number-type abstraction for the templated API port.
Bard-Schweitzer approximate MVA.
Convolution algorithm for the exact normalizing constant of a closed product-form network (Buzen 1973...
Randomness scaffolding shared by the Monte Carlo normalizing-constant estimators (pfqn_mci,...
std::vector< T > XN
(R) throughput
Return value of the normalizing-constant family, mirroring Ret.pfqnNc.