Loading...
Searching...
No Matches
cdf.h
Go to the documentation of this file.
1#ifndef _BBM_CDF_H_
2#define _BBM_CDF_H_
3
4#include <numeric>
5#include <algorithm>
6
7#include "util/named.h"
9
10/************************************************************************/
11/*! \file cdf.h
12
13 \brief Discrete Cummulative Distribution Function (cdf) constructed from a
14 set of samples and accompanying sampling method.
15*************************************************************************/
16
17namespace bbm {
18
19 /**********************************************************************/
20 /*! \brief CDF data structure
21
22 \tparam C = container type to store CDF as well as to provide samples for
23 construction.
24
25 Requires that the container 'C' is a range.
26 ***********************************************************************/
27 template<typename C> requires std::ranges::range<C>
28 struct cdf
29 {
31 using index_type = index_t<value_type>;
32
33 //! \brief Trivial constructor
34 inline constexpr cdf(void) : _cdf() {}
35
36 /********************************************************************/
37 /*! \brief Constructor
38
39 \param samples: a iterable container of samples (in order).
40
41 The samples will be integrated into a CDF and normalized.
42 *********************************************************************/
43 inline constexpr cdf(const C& samples) : _cdf(samples)
44 {
45 if(bbm::size(samples) != 0)
46 {
47 std::partial_sum(bbm::begin(_cdf), bbm::end(_cdf), bbm::begin(_cdf));
48 auto norm = *std::prev(bbm::end(_cdf));
49 std::transform(bbm::begin(_cdf), bbm::end(_cdf), bbm::begin(_cdf), [&norm](auto in) { return in / norm; });
50 }
51 }
52
53 //! \brief Copy Constructor
54 inline constexpr cdf(const cdf& src) : _cdf(src._cdf) {}
55
56 //! \brief Assigmemnt
57 inline constexpr cdf operator=(const cdf& src)
58 {
59 if(&src == this) return *this;
60 _cdf = src._cdf;
61 return *this;
62 }
63
64 //! \brief number of samples
65 inline size_t size(void) const { return _cdf.size(); }
66
67 /********************************************************************/
68 /*! \brief sample the CDF given a random variable xi
69
70 \param xi = random variable between 0 and 1
71 \param mask = enable/disable lanes.
72 \returns sampled index, the pdf, and the residual
73
74 The value type and index type are determined by the container itself.
75 The random variable is expected to be provided in the same data type as
76 the value type of the container. Hence, if the container stores a
77 packet type, the we also expect the random variable be given as a
78 packet, and the index type to have the same number of channels.
79
80 The returned type is a tuple of:
81 + the sampled index based on xi
82 + the corresponding pdf of the sample
83 + the residual, i.e., the rescaled entropy of xi that was not used to determine the sample.
84 *********************************************************************/
85 inline auto sample(const value_type& xi, index_mask_t<index_type> mask=true) const
86 {
87 // make sure xi is in range
88 mask &= bbm::cast<index_mask_t<index_type>>((xi >= 0) && (xi <= 1));
89
90 // find index
91 index_type idx = bbm::binary_search(_cdf, [&](const value_type& val) { return val < xi; }, mask);
92
93 // compute pdf and residual
94 mask &= (idx < bbm::size(_cdf));
95
96 value_type eval = bbm::lookup<value_type>(_cdf, idx, mask);
97 value_type prev = bbm::lookup<value_type>(_cdf, idx-1, mask && (idx >= 1));
98
99 value_type pdf = eval - prev;
100 value_type residual = bbm::select(mask, (xi - prev) / pdf, 0);
101
102 // Done.
103 return make_named<"index", "pdf", "residual">(idx, pdf, residual);
104 }
105
106 /********************************************************************/
107 /*! \brief querry the PDF that an index will be sampled.
108
109 \param idx = index to sample (must be in [0, size()-1]
110 \param mask = enable/disable lanes
111 \returns the pdf, which is equivalent to the normalized sample value.
112 *********************************************************************/
113 inline auto pdf(const index_type& idx, index_mask_t<index_type> mask=true) const
114 {
115 mask &= (idx < bbm::size(_cdf));
116
117 // querry _cdf
118 value_type eval = bbm::lookup<value_type>(_cdf, idx, mask);
119 value_type prev = bbm::lookup<value_type>(_cdf, idx-1, mask && (idx >= 1));
120
121 // compute pdf
122 return (eval - prev);
123 }
124
125 private:
126 //////////////////
127 //! \brief Data
128 //////////////////
129 std::decay_t<C> _cdf;
130 };
131
132} // end bbm namespace
133
134#endif /* _BBM_CDF_H_ */
Extensions for STL iterators/ranges.
Definition: aggregatebsdf.h:29
constexpr named< anonymize_t< T >, NAMES... > make_named(T &&t)
Make a named of a gettable type (with size == #NAMES); renames if the type is a named container.
Definition: named.h:293
constexpr auto select(MASK &&mask, const A &a, const A &b)
Definition: backbone.h:255
auto end(T &&t)
Definition: iterator_util.h:43
size_t size(T &&t)
Definition: iterator_util.h:22
std::decay_t< decltype(*bbm::begin(std::declval< T >()))> iterable_value_t
Definition: iterator_util.h:61
auto begin(T &&t)
Definition: iterator_util.h:29
CDF data structure.
Definition: cdf.h:29
size_t size(void) const
number of samples
Definition: cdf.h:65
bbm::iterable_value_t< C > value_type
Definition: cdf.h:30
std::decay_t< C > _cdf
Data.
Definition: cdf.h:129
index_t< value_type > index_type
Definition: cdf.h:31
constexpr cdf(const cdf &src)
Copy Constructor.
Definition: cdf.h:54
auto sample(const value_type &xi, index_mask_t< index_type > mask=true) const
sample the CDF given a random variable xi
Definition: cdf.h:85
constexpr cdf(void)
Trivial constructor.
Definition: cdf.h:34
constexpr cdf operator=(const cdf &src)
Assigmemnt.
Definition: cdf.h:57
auto pdf(const index_type &idx, index_mask_t< index_type > mask=true) const
querry the PDF that an index will be sampled.
Definition: cdf.h:113
constexpr cdf(const C &samples)
Constructor.
Definition: cdf.h:43
A wrapper for STL containers such as tuple, pair, and array. These containers force the programmer to...