LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
cache_prob_erec.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_PROB_EREC_H
6#define LINE_API_CACHE_PROB_EREC_H
7
8/**
9 * @file
10 * @ingroup api_cache
11 * Exact per-item hit and miss probabilities of a multi-list cache.
12 *
13 * Templated port of matlab/src/api/cache/cache_prob_erec.m, cross-checked
14 * against jar/src/main/java/jline/api/cache/Cache_prob_erec.java.
15 *
16 * The probability that item i sits in list j is the ratio of normalizing
17 * constants
18 *
19 * prob(i,1+j) = m(j) gamma(i,j) E(gamma without item i, m - e_j) / E(gamma,m)
20 *
21 * and prob(i,1) = 1 - sum_j prob(i,1+j) is the miss probability. Both
22 * constants come from cache_erec, so every operation is a field operation and
23 * the exact instantiation returns the probabilities as rationals; in that
24 * arithmetic the row sums are exactly one, which is the conservation law the
25 * test suite asserts with == rather than a tolerance.
26 *
27 * The MATLAB reference wraps the miss probability in abs(), which only matters
28 * when the hit probabilities sum above one -- impossible in exact arithmetic
29 * and a rounding artefact in double. The abs() is kept for bit-compatibility
30 * with MATLAB and the JAR.
31 */
32
33#include <cstddef>
34#include <vector>
35
37#include "line/num/number.h"
38#include "line/util/error.h"
39#include "line/util/matrix.h"
40
41namespace line {
42namespace cache {
43
44template <class T>
45Matrix<T> cache_prob_erec(const Matrix<T>& gamma, const std::vector<int>& m,
46 const std::vector<int>& sigma, const std::vector<int>& k);
47
48/**
49 * @brief Exact per-item hit and miss probabilities of a multi-list cache.
50 *
51 * @param gamma (n x h) access factors
52 * @param m (h) list capacities
53 * @return (n x (h+1)) matrix; column 0 is the miss probability, column 1+j the
54 * probability of a hit in list j
55 */
56template <class T>
57Matrix<T> cache_prob_erec(const Matrix<T>& gamma, const std::vector<int>& m) {
58 return cache_prob_erec(gamma, m, std::vector<int>(), std::vector<int>());
59}
60
61/**
62 * Per-item hit and miss probabilities under per-list storage cost caps,
63 * pi_ij = m_j gamma(i,j) E_i(m - e_j, k - sigma_i e_j) / E(m,k). An EMPTY
64 * sigma or k selects the unconstrained expression.
65 *
66 * @param gamma (n x h) access factors
67 * @param m (h) list capacities
68 * @param sigma (n) per-item storage costs; empty for none
69 * @param k (h) per-list storage cost caps; empty for none
70 * @return (n x (h+1)) matrix; column 0 is the miss probability, column 1+j the
71 * probability of a hit in list j
72 */
73template <class T>
74Matrix<T> cache_prob_erec(const Matrix<T>& gamma, const std::vector<int>& m,
75 const std::vector<int>& sigma, const std::vector<int>& k) {
76 const std::size_t n = gamma.rows();
77 const std::size_t h = gamma.cols();
78 if (h != m.size())
79 throw InputError("cache_prob_erec: gamma and m disagree on the number of lists");
80 const bool capped = !sigma.empty() && !k.empty();
81
82 const T E = cache_erec(gamma, m, sigma, k);
83 if (E == num_traits<T>::from_int(0))
84 throw NumericError("cache_prob_erec: the normalizing constant is zero");
85
86 Matrix<T> prob(n, h + 1, num_traits<T>::from_int(0));
87 for (std::size_t i = 0; i < n; ++i) {
88 T hits = num_traits<T>::from_int(0);
89 for (std::size_t j = 0; j < h; ++j) {
90 std::vector<int> mj = m;
91 mj[j] -= 1;
93 if (!capped) {
94 Ei = cache_erec(detail::gamma_without_row(gamma, i), mj);
95 } else {
96 std::vector<int> kij = k;
97 kij[j] -= sigma[i];
98 if (kij[j] >= 0) {
99 std::vector<int> si;
100 si.reserve(n - 1);
101 for (std::size_t a = 0; a < n; ++a)
102 if (a != i) si.push_back(sigma[a]);
103 Ei = cache_erec(detail::gamma_without_row(gamma, i), mj, si, kij);
104 }
105 }
106 const T p = num_traits<T>::from_int(static_cast<long>(m[j])) * gamma(i, j) * Ei / E;
107 prob(i, j + 1) = p;
108 hits += p;
109 }
110 prob(i, 0) = num_abs(T(num_traits<T>::from_int(1) - hits));
111 }
112 return prob;
113}
114
115} // namespace cache
116} // namespace line
117
118#endif // LINE_API_CACHE_PROB_EREC_H
Exact recursive normalizing constant of a multi-list cache model.
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
NumericError(const std::string &what)
Definition error.h:45
The exception types the port throws.
Dense matrix and non-owning view.
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,...
T cache_erec(const Matrix< T > &gamma, const std::vector< int > &m)
Exact recursive normalizing constant of a multi-list cache model.
Definition cache_erec.h:201
T num_abs(const T &v)
Definition number.h:172
Number-type abstraction for the templated API port.