RandLib 2.0.0
Probability distributions, fitting, and heavy-tail tools for C++20
Loading...
Searching...
No Matches
exponentially_modified_gaussian.hpp
Go to the documentation of this file.
1#pragma once
2
9
10namespace randlib
11{
12
22template <typename RealType>
24{
25 RealType variate(detail::EngineRef g) const override { return (*this)(g); }
26
29
30 double a = 1;
32 double c = 0.5;
33 double v = 1;
34
35public:
36 explicit ExponentiallyModifiedGaussianRand(double location = 0, double variance = 1, double rate = 1);
37
38 [[nodiscard]] std::string Name() const override;
39 [[nodiscard]] Support SupportType() const override { return Support::Infinite; }
40 [[nodiscard]] RealType MinValue() const override { return -INFINITY; }
41 [[nodiscard]] RealType MaxValue() const override { return INFINITY; }
42
43 void SetParameters(double location, double variance, double rate);
44 [[nodiscard]] inline double GetLocation() const { return X.GetLocation(); }
45 [[nodiscard]] inline double GetScale() const { return X.GetScale(); }
46 [[nodiscard]] inline double GetRate() const { return Y.GetRate(); }
47
48private:
49 DoublePair faux(const RealType &x) const;
50 double exponentialTerm(const RealType &x) const;
51
52public:
53 [[nodiscard]] double f(const RealType &x) const override;
54 [[nodiscard]] double logf(const RealType &x) const override;
55 [[nodiscard]] double F(const RealType &x) const override;
56 [[nodiscard]] double S(const RealType &x) const override;
57 template <std::uniform_random_bit_generator G>
58 [[nodiscard]] RealType operator()(G &g) const;
59
60 template <std::uniform_random_bit_generator G>
61 [[nodiscard]] static RealType StandardVariate(G &g);
62
63 [[nodiscard]] long double Mean() const override;
64 [[nodiscard]] long double Variance() const override;
65 [[nodiscard]] long double Skewness() const override;
66 [[nodiscard]] long double ExcessKurtosis() const override;
67
68private:
69 std::complex<double> CFImpl(double t) const override;
70};
71
72} // namespace randlib
73
74namespace randlib
75{
76
77template <typename RealType>
79 double rate)
80{
81 SetParameters(location, variance, rate);
82}
83
84template <typename RealType>
86{
87 return "Exponentially modified Gaussian(" + this->toStringWithPrecision(GetLocation()) + ", " +
88 this->toStringWithPrecision(X.Variance()) + ", " + this->toStringWithPrecision(GetRate()) + ")";
89}
90
91template <typename RealType>
92void ExponentiallyModifiedGaussianRand<RealType>::SetParameters(double location, double variance, double rate)
93{
94 if (!std::isfinite(location))
95 throw std::invalid_argument("Exponentially modified Gaussian distribution: location should be finite");
96 if (!(variance > 0))
97 throw std::invalid_argument("Exponentially modified Gaussian distribution: variance should be positive");
98 if (!(rate > 0))
99 throw std::invalid_argument("Exponentially modified Gaussian distribution: rate should be positive");
100
101 X.SetLocation(location);
102 X.SetVariance(variance);
103 Y.SetRate(rate);
104
105 double mu = X.GetLocation();
106 double sigma = X.GetScale();
107 double beta = Y.GetRate();
108 double var = sigma * sigma;
109 a = 0.5 * beta * var;
110 c = mu + a;
111 a += c;
112 b = randlib::consts::inv_sqrt2 / sigma;
113 v = beta * sigma;
114}
115
116template <typename RealType>
118{
121 double lambda = Y.GetRate();
122 double z = (a - x) * b;
123 if (z >= 0) {
124 double w = (x - X.GetLocation()) * b;
125 return std::make_pair(0.5 * lambda * math::erfcx(z), -w * w);
126 }
127 return std::make_pair(0.5 * lambda * std::erfc(z), lambda * (c - x));
128}
129
130template <typename RealType>
132{
133 auto [y, exponent] = faux(x);
134 return y * std::exp(exponent);
135}
136
137template <typename RealType>
139{
140 auto [y, exponent] = faux(x);
141 return std::log(y) + exponent;
142}
143
144template <typename RealType>
146{
148 double w = (x - X.GetLocation()) / X.GetScale();
149 if (w < v)
150 return 0.5 * std::exp(-0.5 * w * w) * math::erfcx((v - w) * randlib::consts::inv_sqrt2);
151 return std::exp(v * (0.5 * v - w)) * X.F(x - v * X.GetScale());
152}
153
154template <typename RealType>
156{
157 return std::max(X.F(x) - exponentialTerm(x), 0.0);
158}
159
160template <typename RealType>
162{
163 return std::min(X.S(x) + exponentialTerm(x), 1.0);
164}
165
166template <typename RealType>
167template <std::uniform_random_bit_generator G>
169{
170 return X(g) + Y(g);
171}
172
173template <typename RealType>
174template <std::uniform_random_bit_generator G>
179
180template <typename RealType>
182{
183 return X.Mean() + Y.Mean();
184}
185
186template <typename RealType>
188{
189 return X.Variance() + Y.Variance();
190}
191
192template <typename RealType>
193std::complex<double> ExponentiallyModifiedGaussianRand<RealType>::CFImpl(double t) const
194{
195 return X.CF(t) * Y.CF(t);
196}
197
198template <typename RealType>
200{
201 long double sigma = X.GetScale();
202 long double lambda = Y.GetRate();
203 long double tmp = 1.0 / (sigma * lambda);
204 long double tmpSq = tmp * tmp;
205 long double y = 1.0 + tmpSq;
206 y = y * y * y;
207 y = std::sqrt(y);
208 y = tmpSq * tmp / y;
209 return y + y;
210}
211
212template <typename RealType>
214{
215 long double sigma = X.GetScale();
216 long double lambda = Y.GetRate();
217 long double tmp = 1.0 / (sigma * lambda);
218 tmp *= tmp;
219 long double numerator = 1.0 + 2.0 * tmp + 3.0 * tmp * tmp;
220 long double denominator = 1.0 + tmp;
221 denominator *= denominator;
222 long double y = numerator / denominator - 1.0;
223 return 3.0 * y;
224}
225
226} // namespace randlib
The ContinuousDistribution class Abstract class for all continuous distributions.
Definition continuous.hpp:22
The ExponentialRand class Exponential distribution.
Definition exponential.hpp:28
The ExponentiallyModifiedGaussianRand class Exponentially-modified Gaussian distribution.
Definition exponentially_modified_gaussian.hpp:24
ExponentiallyModifiedGaussianRand(double location=0, double variance=1, double rate=1)
βσ
Definition exponentially_modified_gaussian.hpp:78
long double Mean() const override
Definition exponentially_modified_gaussian.hpp:181
long double ExcessKurtosis() const override
Definition exponentially_modified_gaussian.hpp:213
double F(const RealType &x) const override
Definition exponentially_modified_gaussian.hpp:155
Support SupportType() const override
Definition exponentially_modified_gaussian.hpp:39
RealType MaxValue() const override
Definition exponentially_modified_gaussian.hpp:41
double GetScale() const
Definition exponentially_modified_gaussian.hpp:45
std::string Name() const override
Definition exponentially_modified_gaussian.hpp:85
RealType MinValue() const override
Definition exponentially_modified_gaussian.hpp:40
long double Variance() const override
Definition exponentially_modified_gaussian.hpp:187
double GetLocation() const
Definition exponentially_modified_gaussian.hpp:44
long double Skewness() const override
Definition exponentially_modified_gaussian.hpp:199
void SetParameters(double location, double variance, double rate)
Definition exponentially_modified_gaussian.hpp:92
double f(const RealType &x) const override
Definition exponentially_modified_gaussian.hpp:131
double logf(const RealType &x) const override
Definition exponentially_modified_gaussian.hpp:138
double S(const RealType &x) const override
Definition exponentially_modified_gaussian.hpp:161
double GetRate() const
Definition exponentially_modified_gaussian.hpp:46
static RealType StandardVariate(G &g)
Definition exponentially_modified_gaussian.hpp:175
RealType operator()(G &g) const
Definition exponentially_modified_gaussian.hpp:168
The NormalRand class Normal distribution.
Definition normal.hpp:31
std::complex< double > CF(double t) const
Definition univariate.hpp:357
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
constexpr long double inv_sqrt2
Definition constants.hpp:28
Real standardNormal(G &g)
Ziggurat algorithm of Marsaglia and Tsang with 256 layers and an explicit sign bit.
Definition variates.hpp:45
Real erfcx(Real x)
Definition functions.hpp:525
Definition bivariate_normal.hpp:10
Support
Shape of the support of a univariate distribution.
Definition univariate.hpp:15
@ Infinite
(-∞, ∞)
Pair< double > DoublePair
Definition fwd.hpp:39