58 std::uint64_t seed,
const std::vector<int>& sigma,
59 const std::vector<int>& k) {
60 const bool capped = !sigma.empty() && !k.empty();
62 "cache_prob_is requires transcendental arithmetic: the weights are Monte Carlo "
63 "quantities formed through logs and an exponential");
64 if (gamma.
cols() != m.size())
65 throw InputError(
"cache_prob_is: gamma and m disagree on the number of lists");
66 if (samples == 0)
throw InputError(
"cache_prob_is: at least one sample is required");
72 const std::size_t n = gamma.
rows();
73 const std::size_t h = m.size();
76 if (v < 0)
throw InputError(
"cache_prob_is: negative list capacity");
81 if (n == 0)
return prob;
82 if (mt == 0 ||
static_cast<long>(n) < mt) {
85 for (std::size_t i = 0; i < n; ++i) prob(i, 0) = one;
88 if (
static_cast<long>(n) == mt)
return cache_prob_erec(gamma, m, sigma, k);
92 for (std::size_t i = 0; i < n; ++i)
93 for (std::size_t j = 0; j < h; ++j) lgam(i, j) = log(T(gamma(i, j) + floorv));
96 for (std::size_t j = 0; j < h; ++j)
97 logMFact += pfqn::detail::num_logfact_int<T>(
static_cast<long>(m[j]));
98 const T logComb = pfqn::detail::num_logfact_int<T>(
static_cast<long>(n)) -
99 pfqn::detail::num_logfact_int<T>(mt) -
100 pfqn::detail::num_logfact_int<T>(
static_cast<long>(n) - mt);
101 const T logMultinom = pfqn::detail::num_logfact_int<T>(mt) - logMFact;
102 const T logProposal = -logComb - logMultinom;
107 std::mt19937_64
rng(seed);
108 std::vector<std::size_t>
perm, sel;
109 for (std::size_t s = 0; s < samples; ++s) {
110 detail::sample_without_replacement(n,
static_cast<std::size_t
>(mt),
rng,
perm, sel);
111 T logState = logMFact;
113 bool feasible =
true;
114 for (std::size_t j = 0; j < h && feasible; ++j) {
117 for (
int c = 0; c < m[j]; ++c) listCost += sigma[sel[idx + c]];
118 if (listCost > k[j]) {
123 for (
int c = 0; c < m[j]; ++c) logState += lgam(sel[idx++], j);
125 if (!feasible)
continue;
126 const T wgt = exp(T(logState - logProposal - shift));
129 for (std::size_t j = 0; j < h; ++j)
130 for (
int c = 0; c < m[j]; ++c) acc(sel[idx++], j) += wgt;
134 for (std::size_t i = 0; i < n; ++i) prob(i, 0) = one;
137 for (std::size_t i = 0; i < n; ++i) {
139 for (std::size_t j = 0; j < h; ++j) {
140 prob(i, 1 + j) = acc(i, j) / total;
141 hit += prob(i, 1 + j);
143 const T miss = one - hit;
144 prob(i, 0) = miss > zero ? miss : zero;
Matrix< T > cache_prob_erec(const Matrix< T > &gamma, const std::vector< int > &m, const std::vector< int > &sigma, const std::vector< int > &k)
Per-item hit and miss probabilities under per-list storage cost caps, pi_ij = m_j gamma(i,...
Matrix< T > cache_prob_is(const Matrix< T > &gamma, const std::vector< int > &m, std::size_t samples, std::uint64_t seed, const std::vector< int > &sigma, const std::vector< int > &k)
Importance-sampling estimate of the cache hit-probability distribution.