RandLib 2.0.0
Probability distributions, fitting, and heavy-tail tools for C++20
Loading...
Searching...
No Matches
frechet.hpp
Go to the documentation of this file.
1#pragma once
2
7
8namespace randlib
9{
10
17template <typename RealType>
18class FrechetRand final : public ContinuousDistribution<RealType>
19{
20 RealType variate(detail::EngineRef g) const override { return (*this)(g); }
21
22 double alpha = 1;
23 double s = 1;
24 double m = 0;
25 double alphaInv = 1;
26 double pdfCoef = 0;
27
28public:
29 FrechetRand(double shape = 1, double scale = 1, double location = 0);
30
31 [[nodiscard]] std::string Name() const override;
32 [[nodiscard]] Support SupportType() const override { return Support::RightSemiFinite; }
33 [[nodiscard]] RealType MinValue() const override { return m; }
34 [[nodiscard]] RealType MaxValue() const override { return INFINITY; }
35
36 void SetParameters(double shape, double scale, double location);
37 [[nodiscard]] inline double GetShape() const noexcept { return alpha; }
38 [[nodiscard]] inline double GetScale() const noexcept { return s; }
39 [[nodiscard]] inline double GetLocation() const noexcept { return m; }
40
41 [[nodiscard]] double f(const RealType &x) const override;
42 [[nodiscard]] double logf(const RealType &x) const override;
43 [[nodiscard]] double F(const RealType &x) const override;
44 [[nodiscard]] double S(const RealType &x) const override;
45 template <std::uniform_random_bit_generator G>
46 [[nodiscard]] RealType operator()(G &g) const;
47
48 [[nodiscard]] long double Mean() const override;
49 [[nodiscard]] long double Variance() const override;
50 [[nodiscard]] RealType Median() const override;
51 [[nodiscard]] RealType Mode() const override;
52 [[nodiscard]] long double Skewness() const override;
53 [[nodiscard]] long double ExcessKurtosis() const override;
54
55private:
56 RealType quantileImpl(double p) const override;
57 RealType quantileImpl1m(double p) const override;
58 std::complex<double> CFImpl(double t) const override;
59
60public:
61 [[nodiscard]] long double Entropy() const;
62};
63
64} // namespace randlib
65
67
68namespace randlib
69{
70
71template <typename RealType>
72FrechetRand<RealType>::FrechetRand(double shape, double scale, double location)
73{
74 SetParameters(shape, scale, location);
75}
76
77template <typename RealType>
78std::string FrechetRand<RealType>::Name() const
79{
80 return "Frechet(" + this->toStringWithPrecision(GetShape()) + ", " + this->toStringWithPrecision(GetScale()) +
81 ", " + this->toStringWithPrecision(GetLocation()) + ")";
82}
83
84template <typename RealType>
85void FrechetRand<RealType>::SetParameters(double shape, double scale, double location)
86{
87 if (!std::isfinite(location))
88 throw std::invalid_argument("Frechet distribution: location should be finite");
89 if (!(shape > 0.0))
90 throw std::invalid_argument("Frechet distribution: shape should be positive");
91 if (!(scale > 0.0))
92 throw std::invalid_argument("Frechet distribution: scale should be positive");
93 alpha = shape;
94 alphaInv = 1.0 / alpha;
95 s = scale;
96 pdfCoef = std::log(alpha / s);
97 m = location;
98}
99
100template <typename RealType>
101double FrechetRand<RealType>::f(const RealType &x) const
102{
103 return (x <= m) ? 0.0 : std::exp(logf(x));
104}
105
106template <typename RealType>
107double FrechetRand<RealType>::logf(const RealType &x) const
108{
109 if (x <= m)
110 return -INFINITY;
111 double xAdj = (x - m) / s;
112 double logxAdj = std::log(xAdj);
113 double a = alpha * logxAdj;
114 double expA = std::exp(-a);
115 return pdfCoef - a - expA - logxAdj;
116}
117
118template <typename RealType>
119double FrechetRand<RealType>::F(const RealType &x) const
120{
121 if (x <= m)
122 return 0.0;
123 double xAdj = (x - m) / s;
124 double xPow = std::pow(xAdj, -alpha);
125 return std::exp(-xPow);
126}
127
128template <typename RealType>
129double FrechetRand<RealType>::S(const RealType &x) const
130{
131 if (x <= m)
132 return 1.0;
133 double xAdj = (x - m) / s;
134 double xPow = std::pow(xAdj, -alpha);
135 return -std::expm1l(-xPow);
136}
137
138template <typename RealType>
139template <std::uniform_random_bit_generator G>
141{
142 return m + s / std::pow(detail::standardExponential<RealType>(g), alphaInv);
143}
144
145template <typename RealType>
147{
148 if (alpha <= 1.0)
149 return INFINITY;
150 return m + s * std::tgammal(1.0 - alphaInv);
151}
152
153template <typename RealType>
155{
156 if (alpha <= 2.0)
157 return INFINITY;
158 long double var = std::tgammal(1.0 - alphaInv);
159 var *= var;
160 var = std::tgammal(1.0 - 2 * alphaInv) - var;
161 return s * s * var;
162}
163
164template <typename RealType>
165RealType FrechetRand<RealType>::quantileImpl(double p) const
166{
167 RealType y = -std::log(p);
168 y = s / std::pow(y, alphaInv);
169 return y + m;
170}
171
172template <typename RealType>
173RealType FrechetRand<RealType>::quantileImpl1m(double p) const
174{
175 RealType y = -std::log1pl(-p);
176 y = s / std::pow(y, alphaInv);
177 return y + m;
178}
179
180template <typename RealType>
181std::complex<double> FrechetRand<RealType>::CFImpl(double t) const
182{
183 return this->integrateCharacteristicFunction(t);
184}
185
186template <typename RealType>
188{
189 return m + s / std::pow(randlib::consts::ln2, alphaInv);
190}
191
192template <typename RealType>
194{
195 RealType y = alpha / (1.0 + alpha);
196 y = std::pow(y, alphaInv);
197 return m + s * y;
198}
199
200template <typename RealType>
202{
203 if (alpha <= 3.0)
204 return INFINITY;
205 long double x = std::tgammal(1.0 - alphaInv);
206 long double y = std::tgammal(1.0 - 2.0 * alphaInv);
207 long double z = std::tgammal(1.0 - 3.0 * alphaInv);
208 long double numerator = 2 * x * x - 3 * y;
209 numerator *= x;
210 numerator += z;
211 long double denominator = y - x * x;
212 denominator = std::pow(denominator, 1.5);
213 return numerator / denominator;
214}
215
216template <typename RealType>
218{
219 if (alpha <= 4.0)
220 return INFINITY;
221 long double x = std::tgammal(1.0 - alphaInv);
222 long double y = std::tgammal(1.0 - 2.0 * alphaInv);
223 long double z = std::tgammal(1.0 - 3.0 * alphaInv);
224 long double w = std::tgammal(1.0 - 4.0 * alphaInv);
225 long double numerator = w - 4 * z * x + 3 * y * y;
226 long double denominator = y - x * x;
227 denominator *= denominator;
228 return numerator / denominator - 6.0;
229}
230
231template <typename RealType>
233{
234 return 1.0 + randlib::consts::egamma * (1.0 + alphaInv) + std::log(s / alpha);
235}
236
237} // namespace randlib
The ContinuousDistribution class Abstract class for all continuous distributions.
Definition continuous.hpp:22
The FrechetRand class Frechet distribution.
Definition frechet.hpp:19
FrechetRand(double shape=1, double scale=1, double location=0)
Definition frechet.hpp:72
double S(const RealType &x) const override
Definition frechet.hpp:129
long double ExcessKurtosis() const override
Definition frechet.hpp:217
RealType Median() const override
Definition frechet.hpp:187
double GetShape() const noexcept
Definition frechet.hpp:37
RealType MinValue() const override
Definition frechet.hpp:33
void SetParameters(double shape, double scale, double location)
Definition frechet.hpp:85
double GetScale() const noexcept
Definition frechet.hpp:38
long double Entropy() const
Definition frechet.hpp:232
double logf(const RealType &x) const override
Definition frechet.hpp:107
long double Mean() const override
Definition frechet.hpp:146
double GetLocation() const noexcept
Definition frechet.hpp:39
double F(const RealType &x) const override
Definition frechet.hpp:119
double f(const RealType &x) const override
Definition frechet.hpp:101
RealType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition frechet.hpp:193
RealType operator()(G &g) const
Definition frechet.hpp:140
Support SupportType() const override
Definition frechet.hpp:32
long double Variance() const override
Definition frechet.hpp:154
std::string Name() const override
Definition frechet.hpp:78
long double Skewness() const override
Definition frechet.hpp:201
RealType MaxValue() const override
Definition frechet.hpp:34
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
constexpr long double ln2
Definition constants.hpp:18
constexpr long double egamma
Definition constants.hpp:36
Real standardNormal(G &g)
Ziggurat algorithm of Marsaglia and Tsang with 256 layers and an explicit sign bit.
Definition variates.hpp:45
Definition bivariate_normal.hpp:10
Support
Shape of the support of a univariate distribution.
Definition univariate.hpp:15
@ RightSemiFinite
[a, ∞)