LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
cache_miss_is.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_API_CACHE_MISS_IS_H
6#define LINE_API_CACHE_MISS_IS_H
7
8/**
9 * @file
10 * @ingroup api_cache
11 * Cache miss rates from the importance-sampling hit probabilities.
12 *
13 * Templated port of matlab/src/api/cache/cache_miss_is.m: the per-item miss
14 * probabilities come from cache_prob_is, and the miss rates are the request
15 * rates weighted by them. The normalizing constant is estimated alongside by
16 * cache_is and returned, as the reference does.
17 *
18 * With no request rates the reference returns the mean miss probability as the
19 * global rate and leaves the per-user and per-item vectors empty; that
20 * contract is kept.
21 *
22 * Arithmetic. static_assert(has_transcendental) -- it is the importance
23 * sampler of cache_prob_is with a linear map on top.
24 */
25
26#include <cstddef>
27#include <vector>
28
31#include "line/num/number.h"
32#include "line/util/error.h"
33#include "line/util/matrix.h"
34
35namespace line {
36namespace cache {
37
38template <class T>
40 T M; ///< global miss rate
41 std::vector<T> MU; ///< (u) per-user miss rate; empty when no lambda given
42 std::vector<T> MI; ///< (n) per-item miss rate; empty when no lambda given
43 std::vector<T> pi0; ///< (n) per-item miss probability
44 T lE; ///< log of the normalizing constant estimate
45};
46
47/**
48 * @brief Cache miss rates from the importance-sampling hit probabilities.
49 *
50 * @param gamma (n x h) access factors
51 * @param m (h) list capacities
52 * @param lambda (u x n) per-user per-item request rates, MATLAB's
53 * lambda(:,:,1); empty for the mean miss probability alone
54 * @param samples number of Monte Carlo samples
55 * @param seed seed of the sampling stream
56 * @param sigma (n) per-item storage cost; empty for uncapped lists
57 * @param cap (h) per-list cost cap; empty for uncapped lists
58 */
59template <class T>
60CacheMissIsResult<T> cache_miss_is(const Matrix<T>& gamma, const std::vector<int>& m,
61 const Matrix<T>& lambda, std::size_t samples,
62 std::uint64_t seed, const std::vector<int>& sigma,
63 const std::vector<int>& cap) {
65 "cache_miss_is requires transcendental arithmetic: it is the cache_prob_is "
66 "importance sampler with a linear map on top");
67 if (gamma.cols() != m.size())
68 throw InputError("cache_miss_is: gamma and m disagree on the number of lists");
69
70 const T zero = num_traits<T>::from_int(0);
71 const std::size_t n = gamma.rows();
72
74 res.M = zero;
75 res.lE = cache_is(gamma, m, samples, seed, sigma, cap).lE;
76 const Matrix<T> pij = cache_prob_is(gamma, m, samples, seed, sigma, cap);
77 res.pi0.assign(n, zero);
78 for (std::size_t k = 0; k < n; ++k) res.pi0[k] = pij(k, 0);
79
80 if (lambda.empty()) {
81 for (std::size_t k = 0; k < n; ++k) res.M += res.pi0[k];
82 if (n > 0) res.M /= num_traits<T>::from_int(static_cast<long>(n));
83 return res;
84 }
85 if (lambda.cols() != n)
86 throw InputError("cache_miss_is: lambda and gamma disagree on the number of items");
87
88 const std::size_t u = lambda.rows();
89 res.MU.assign(u, zero);
90 for (std::size_t v = 0; v < u; ++v)
91 for (std::size_t k = 0; k < n; ++k) res.MU[v] += lambda(v, k) * res.pi0[k];
92
93 res.MI.assign(n, zero);
94 for (std::size_t k = 0; k < n; ++k) {
95 T s = zero;
96 for (std::size_t v = 0; v < u; ++v) s += lambda(v, k);
97 res.MI[k] = s * res.pi0[k];
98 res.M += res.MI[k];
99 }
100 return res;
101}
102
103/** cache_miss_is without storage cost caps. */
104template <class T>
105CacheMissIsResult<T> cache_miss_is(const Matrix<T>& gamma, const std::vector<int>& m,
106 const Matrix<T>& lambda, std::size_t samples,
107 std::uint64_t seed) {
108 return cache_miss_is(gamma, m, lambda, samples, seed, std::vector<int>(), std::vector<int>());
109}
110
111/** cache_miss_is with the MATLAB default of 1e5 samples. */
112template <class T>
113CacheMissIsResult<T> cache_miss_is(const Matrix<T>& gamma, const std::vector<int>& m,
114 const Matrix<T>& lambda) {
115 return cache_miss_is(gamma, m, lambda, static_cast<std::size_t>(100000),
116 static_cast<std::uint64_t>(0));
117}
118
119} // namespace cache
120} // namespace line
121
122#endif // LINE_API_CACHE_MISS_IS_H
Importance-sampling estimate of the cache normalizing constant.
Importance-sampling estimate of the cache hit-probability distribution.
InputError(const std::string &what)
Definition error.h:39
std::size_t cols() const
Definition matrix.h:90
std::size_t rows() const
Definition matrix.h:89
bool empty() const
Definition matrix.h:92
The exception types the port throws.
Dense matrix and non-owning view.
CacheIsResult< T > cache_is(const Matrix< T > &gamma_in, const std::vector< int > &m, std::size_t samples, std::uint64_t seed, const std::vector< int > &sigma_in, const std::vector< int > &k)
Importance-sampling estimate of the cache normalizing constant.
Definition cache_is.h:113
CacheMissIsResult< T > cache_miss_is(const Matrix< T > &gamma, const std::vector< int > &m, const Matrix< T > &lambda, std::size_t samples, std::uint64_t seed, const std::vector< int > &sigma, const std::vector< int > &cap)
Cache miss rates from the importance-sampling hit probabilities.
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.
Number-type abstraction for the templated API port.
T lE
log of the normalizing constant estimate
std::vector< T > MI
(n) per-item miss rate; empty when no lambda given
std::vector< T > pi0
(n) per-item miss probability
std::vector< T > MU
(u) per-user miss rate; empty when no lambda given