RandLib 2.0.0
Probability distributions, fitting, and heavy-tail tools for C++20
Loading...
Searching...
No Matches
cantor.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4
9
10namespace randlib
11{
12
19class CantorRand final : public SingularDistribution
20{
21 double variate(detail::EngineRef g) const override { return (*this)(g); }
22
23 static constexpr int n = 30;
25 static constexpr std::array<double, n> table = [] {
26 std::array<double, n> powers{};
27 double power = 1.0;
28 for (double &p : powers)
29 p = power /= 3.0;
30 return powers;
31 }();
32
33public:
34 CantorRand();
35 [[nodiscard]] std::string Name() const override;
36 [[nodiscard]] Support SupportType() const override { return Support::Finite; }
37 [[nodiscard]] double MinValue() const override { return 0; }
38 [[nodiscard]] double MaxValue() const override { return 1; }
39
40 [[nodiscard]] double F(const double &x) const override;
41 template <std::uniform_random_bit_generator G>
42 [[nodiscard]] double operator()(G &g) const;
43
44 [[nodiscard]] long double Mean() const override;
45 [[nodiscard]] long double Variance() const override;
46 [[nodiscard]] double Median() const override;
47 [[nodiscard]] long double Skewness() const override;
48 [[nodiscard]] long double ExcessKurtosis() const override;
49
50private:
51 double quantileImpl(double p, double initValue) const override;
52 double quantileImpl(double p) const override;
53 double quantileImpl1m(double p, double initValue) const override;
54 double quantileImpl1m(double p) const override;
55
56 std::complex<double> CFImpl(double t) const override;
57};
58
59} // namespace randlib
60
63
64namespace randlib
65{
66
68{
69}
70
71inline std::string CantorRand::Name() const
72{
73 return "Cantor";
74}
75
76inline double CantorRand::F(const double &x) const
77{
78 if (x <= 0.0)
79 return 0.0;
80 if (x >= 1.0)
81 return 1.0;
82 double a = 0.0, b = 1.0;
83 double v = 0.5, d = 0.5, delta = 1.0;
84 while (delta > math::detail::minimumTolerance) {
85 delta = (b - a) / 3.0;
86 if (x < a + delta) {
87 b = a + delta;
88 d *= 0.5;
89 v -= d;
90 } else if (x > b - delta) {
91 a = b - delta;
92 d *= 0.5;
93 v += d;
94 } else
95 return v;
96 }
97 return v;
98}
99
100template <std::uniform_random_bit_generator G>
101double CantorRand::operator()(G &g) const
102{
103 long double sum = 0.0;
104 for (int i = 0; i != n; ++i) {
105 sum += table[i] * BernoulliRand::StandardVariate(g);
106 }
107 return sum + sum;
108}
109
110inline long double CantorRand::Mean() const
111{
112 return 0.5;
113}
114
115inline long double CantorRand::Variance() const
116{
117 return 0.125;
118}
119
120inline double CantorRand::quantileImpl(double p, double) const
121{
122 return math::findRoot([this, p](double x) { return F(x) - p; }, 0.0, 1.0);
123}
124
125inline double CantorRand::quantileImpl(double p) const
126{
127 return quantileImpl(p, p);
128}
129
130inline double CantorRand::quantileImpl1m(double p, double) const
131{
132 return math::findRoot([this, p](double x) { return S(x) - p; }, 0.0, 1.0);
133}
134
135inline double CantorRand::quantileImpl1m(double p) const
136{
137 return quantileImpl1m(p, 1.0 - p);
138}
139
140inline std::complex<double> CantorRand::CFImpl(double t) const
141{
142 double prod = 1.0;
143 for (int i = 0; i != n; ++i)
144 prod *= std::cos(t * table[i]);
145 std::complex<double> y(0.0, 0.5 * t);
146 y = std::exp(y);
147 return y * prod;
148}
149
150inline double CantorRand::Median() const
151{
152 return 1.0 / 3;
153}
154
155inline long double CantorRand::Skewness() const
156{
157 return 0.0l;
158}
159
160inline long double CantorRand::ExcessKurtosis() const
161{
162 return -1.6l;
163}
164
165} // namespace randlib
static int StandardVariate(G &g)
Definition bernoulli.hpp:106
The CantorRand class Cantor distribution.
Definition cantor.hpp:20
long double Skewness() const override
Definition cantor.hpp:155
long double Mean() const override
Definition cantor.hpp:110
CantorRand()
Definition cantor.hpp:67
double F(const double &x) const override
Definition cantor.hpp:76
double MaxValue() const override
Definition cantor.hpp:38
double MinValue() const override
Definition cantor.hpp:37
Support SupportType() const override
Definition cantor.hpp:36
long double ExcessKurtosis() const override
Definition cantor.hpp:160
double Median() const override
Definition cantor.hpp:150
long double Variance() const override
Definition cantor.hpp:115
double operator()(G &g) const
Definition cantor.hpp:101
std::string Name() const override
Definition cantor.hpp:71
virtual double S(const T &x) const
Definition distribution.hpp:197
The SingularDistribution class Abstract class for all singular distributions.
Definition singular.hpp:18
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
constexpr long double minimumTolerance
Definition constants.hpp:44
Real findRoot(const F &f, std::type_identity_t< Real > a, std::type_identity_t< Real > b, int maxIterations=200)
Definition roots.hpp:205
Definition bivariate_normal.hpp:10
Support
Shape of the support of a univariate distribution.
Definition univariate.hpp:15