RandLib 2.0.0
Probability distributions, fitting, and heavy-tail tools for C++20
Loading...
Searching...
No Matches
uniform_discrete.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <span>
4
9
10namespace randlib
11{
12
21template <typename IntType>
22class UniformDiscreteRand final : public DiscreteDistribution<IntType>
23{
24 IntType variate(detail::EngineRef g) const override { return (*this)(g); }
25
26 size_t n = 1;
27 IntType a = 0;
28 IntType b = 0;
29 double nInv = 1;
30 double logN = 0;
31
32public:
33 UniformDiscreteRand(IntType minValue = 0, IntType maxValue = 1);
34 [[nodiscard]] std::string Name() const override;
35 [[nodiscard]] Support SupportType() const override { return Support::Finite; }
36 [[nodiscard]] IntType MinValue() const override { return a; }
37 [[nodiscard]] IntType MaxValue() const override { return b; }
38
39 void SetBoundaries(IntType minValue, IntType maxValue);
40
41 [[nodiscard]] double P(const IntType &k) const override;
42 [[nodiscard]] double logP(const IntType &k) const override;
43 [[nodiscard]] double F(const IntType &k) const override;
44
45 template <std::uniform_random_bit_generator G>
46 [[nodiscard]] IntType operator()(G &g) const;
47
48 template <std::uniform_random_bit_generator G>
49 [[nodiscard]] static IntType StandardVariate(IntType minValue, IntType maxValue, G &g);
50
51 [[nodiscard]] long double Mean() const override;
52 [[nodiscard]] long double Variance() const override;
53 [[nodiscard]] IntType Median() const override;
54 [[nodiscard]] IntType Mode() const override;
55 [[nodiscard]] long double Skewness() const override;
56 [[nodiscard]] long double ExcessKurtosis() const override;
57
58private:
59 std::complex<double> CFImpl(double t) const override;
60
61public:
62 [[nodiscard]] long double Entropy() const;
63 [[nodiscard]] double LikelihoodFunction(std::span<const IntType> sample) const override;
64 [[nodiscard]] double LogLikelihoodFunction(std::span<const IntType> sample) const override;
65
70 RANDLIB_DEPRECATED_FIT_MEMBER void Fit(std::span<const IntType> sample);
71};
72
73} // namespace randlib
74
75namespace randlib
76{
77
78template <typename IntType>
79UniformDiscreteRand<IntType>::UniformDiscreteRand(IntType minValue, IntType maxValue)
80{
81 SetBoundaries(minValue, maxValue);
82}
83
84template <typename IntType>
86{
87 return "Uniform Discrete(" + this->toStringWithPrecision(MinValue()) + ", " +
88 this->toStringWithPrecision(MaxValue()) + ")";
89}
90
91template <typename IntType>
92void UniformDiscreteRand<IntType>::SetBoundaries(IntType minValue, IntType maxValue)
93{
94 if (!(minValue <= maxValue))
95 throw std::invalid_argument(
96 "Uniform discrete distribution: minimum value shouldn't be greater than maximum value");
97
98 a = minValue;
99 b = maxValue;
100
101 n = b - a + 1;
102 nInv = 1.0 / n;
103 logN = std::log(n);
104}
105
106template <typename IntType>
107double UniformDiscreteRand<IntType>::P(const IntType &k) const
108{
109 return (k < a || k > b) ? 0.0 : nInv;
110}
111
112template <typename IntType>
113double UniformDiscreteRand<IntType>::logP(const IntType &k) const
114{
115 return (k < a || k > b) ? -INFINITY : -logN;
116}
117
118template <typename IntType>
119double UniformDiscreteRand<IntType>::F(const IntType &k) const
120{
121 if (k < a)
122 return 0.0;
123 if (k > b)
124 return 1.0;
125 return (k - a + 1) * nInv;
126}
127
128template <typename IntType>
129template <std::uniform_random_bit_generator G>
131{
132 return a + static_cast<IntType>(detail::uniformBelow(g, n));
133}
134
135template <typename IntType>
136template <std::uniform_random_bit_generator G>
137IntType UniformDiscreteRand<IntType>::StandardVariate(IntType minValue, IntType maxValue, G &g)
138{
139 if (maxValue <= minValue)
140 return minValue;
141 auto n = static_cast<std::uint64_t>(maxValue - minValue) + 1;
142 return minValue + static_cast<IntType>(detail::uniformBelow(g, n));
143}
144
145template <typename IntType>
147{
148 return 0.5 * (b + a);
149}
150
151template <typename IntType>
153{
154 double nm1 = n - 1;
155 double np1 = n + 1;
156 return nm1 * np1 / 12;
157}
158
159template <typename IntType>
161{
162 return (b + a) >> 1;
163}
164
165template <typename IntType>
167{
169 return 0.5 * (a + b);
170}
171
172template <typename IntType>
174{
175 return 0.0;
176}
177
178template <typename IntType>
180{
181 double kurt = n;
182 kurt *= n;
183 --kurt;
184 kurt = 2.0 / kurt;
185 ++kurt;
186 return -1.2 * kurt;
187}
188
189template <typename IntType>
190std::complex<double> UniformDiscreteRand<IntType>::CFImpl(double t) const
191{
192 const double period = 2 * static_cast<double>(randlib::consts::pi);
193 const double reduced = std::remainder(t, period);
194 if (reduced == 0.0)
195 return 1.0;
196 const double halfAngle = 0.5 * reduced;
197 const double amplitude = std::sin(n * halfAngle) / (n * std::sin(halfAngle));
198 const double phase = (0.5 * static_cast<double>(a) + 0.5 * static_cast<double>(b)) * reduced;
199 return amplitude * std::complex<double>(std::cos(phase), std::sin(phase));
200}
201
202template <typename IntType>
204{
205 return logN;
206}
207
208template <typename IntType>
209double UniformDiscreteRand<IntType>::LikelihoodFunction(std::span<const IntType> sample) const
210{
211 bool sampleIsInsideInterval =
212 this->allElementsAreNotSmallerThan(a, sample) && this->allElementsAreNotGreaterThan(b, sample);
213 return sampleIsInsideInterval ? std::pow(n, -static_cast<double>(sample.size())) : 0.0;
214}
215
216template <typename IntType>
217double UniformDiscreteRand<IntType>::LogLikelihoodFunction(std::span<const IntType> sample) const
218{
219 bool sampleIsInsideInterval =
220 this->allElementsAreNotSmallerThan(a, sample) && this->allElementsAreNotGreaterThan(b, sample);
221 int sample_size = sample.size();
222 return sampleIsInsideInterval ? -sample_size * logN : -INFINITY;
223}
224
225template <typename IntType>
226void UniformDiscreteRand<IntType>::Fit(std::span<const IntType> sample)
227{
228 IntType minVar = *std::min_element(sample.begin(), sample.end());
229 IntType maxVar = *std::max_element(sample.begin(), sample.end());
230 this->SetBoundaries(minVar, maxVar);
231}
232
233} // namespace randlib
The DiscreteDistribution class Abstract class for all discrete distributions.
Definition discrete.hpp:21
virtual void sample(detail::EngineRef g, std::span< T > outputData) const
Fills the output with variate(g); distributions with a faster bulk algorithm override it.
Definition distribution.hpp:66
The UniformDiscreteRand class Uniform discrete distribution.
Definition uniform_discrete.hpp:23
IntType operator()(G &g) const
Definition uniform_discrete.hpp:130
IntType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition uniform_discrete.hpp:166
static IntType StandardVariate(IntType minValue, IntType maxValue, G &g)
Definition uniform_discrete.hpp:137
void SetBoundaries(IntType minValue, IntType maxValue)
Definition uniform_discrete.hpp:92
long double Entropy() const
Definition uniform_discrete.hpp:203
IntType MinValue() const override
Definition uniform_discrete.hpp:36
IntType MaxValue() const override
Definition uniform_discrete.hpp:37
void Fit(std::span< const IntType > sample)
fit bounds via maximum-likelihood method
Definition uniform_discrete.hpp:226
IntType Median() const override
Definition uniform_discrete.hpp:160
std::string Name() const override
Definition uniform_discrete.hpp:85
Support SupportType() const override
Definition uniform_discrete.hpp:35
double LikelihoodFunction(std::span< const IntType > sample) const override
Definition uniform_discrete.hpp:209
UniformDiscreteRand(IntType minValue=0, IntType maxValue=1)
Definition uniform_discrete.hpp:79
double P(const IntType &k) const override
Definition uniform_discrete.hpp:107
long double Variance() const override
Definition uniform_discrete.hpp:152
double LogLikelihoodFunction(std::span< const IntType > sample) const override
Definition uniform_discrete.hpp:217
long double Skewness() const override
Definition uniform_discrete.hpp:173
long double ExcessKurtosis() const override
Definition uniform_discrete.hpp:179
double logP(const IntType &k) const override
Definition uniform_discrete.hpp:113
long double Mean() const override
Definition uniform_discrete.hpp:146
double F(const IntType &k) const override
Definition uniform_discrete.hpp:119
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
#define RANDLIB_DEPRECATED_FIT_MEMBER
Definition fwd.hpp:9
constexpr long double pi
Definition constants.hpp:22
std::uint64_t uniformBelow(G &g, std::uint64_t n)
Definition engine/uniform.hpp:100
Definition bivariate_normal.hpp:10
Support
Shape of the support of a univariate distribution.
Definition univariate.hpp:15