RandLib 2.0.0
Probability distributions, fitting, and heavy-tail tools for C++20
Loading...
Searching...
No Matches
exponential.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <functional>
5
11
12namespace randlib
13{
14
26template <typename RealType>
27class ExponentialRand final : public FreeRateGammaDistribution<RealType>, public ExponentialFamily<RealType, double>
28{
29 RealType variate(detail::EngineRef g) const override { return (*this)(g); }
30
31public:
32 explicit ExponentialRand(double rate = 1) : FreeRateGammaDistribution<RealType>(1, rate) {}
33
35 [[nodiscard]] static ExponentialRand FromRate(double rate) { return ExponentialRand(rate); }
36
38 [[nodiscard]] static ExponentialRand FromScale(double scale)
39 {
40 if (!(scale > 0.0))
41 throw std::invalid_argument("Exponential distribution: scale should be positive");
42 return ExponentialRand(1.0 / scale);
43 }
44 [[nodiscard]] std::string Name() const override;
45
46 double SufficientStatistic(RealType x) const override;
47 double SourceParameters() const override;
48 double SourceToNatural(double rate) const override;
49 double LogNormalizer(double theta) const override;
50 double LogNormalizerGradient(double theta) const override;
51 double CarrierMeasure(RealType) const override;
52 double CrossEntropyAdjusted(double rate) const override;
53 double EntropyAdjusted() const override;
54
55 [[nodiscard]] double f(const RealType &x) const override;
56 [[nodiscard]] double logf(const RealType &x) const override;
57 [[nodiscard]] double F(const RealType &x) const override;
58 [[nodiscard]] double S(const RealType &x) const override;
59 template <std::uniform_random_bit_generator G>
60 [[nodiscard]] RealType operator()(G &g) const;
61
62 template <std::uniform_random_bit_generator G>
63 [[nodiscard]] static RealType StandardVariate(G &g);
64
65private:
66 std::complex<double> CFImpl(double t) const override;
67
68public:
69 [[nodiscard]] long double Entropy() const;
70 [[nodiscard]] long double Moment(int n) const;
71 [[nodiscard]] long double ThirdMoment() const override { return Moment(3); }
72 [[nodiscard]] long double FourthMoment() const override { return Moment(4); }
73};
74
75} // namespace randlib
76
78
79namespace randlib
80{
81
82template <typename RealType>
84{
85 return "Exponential(" + this->toStringWithPrecision(this->GetRate()) + ")";
86}
87
88template <typename RealType>
90{
91 return x;
92}
93
94template <typename RealType>
96{
97 return this->beta;
98}
99
100template <typename RealType>
102{
103 return -rate;
104}
105
106template <typename RealType>
108{
109 return -std::log(-thetaP);
110}
111
112template <typename RealType>
114{
115 return -1.0 / thetaP;
116}
117
118template <typename RealType>
120{
121 return 0.0;
122}
123
124template <typename RealType>
126{
127 return rate * this->theta - std::log(rate);
128}
129
130template <typename RealType>
132{
133 return 1.0 - this->logBeta;
134}
135
136template <typename RealType>
137double ExponentialRand<RealType>::f(const RealType &x) const
138{
139 return (x < 0.0) ? 0.0 : this->beta * std::exp(-this->beta * x);
140}
141
142template <typename RealType>
143double ExponentialRand<RealType>::logf(const RealType &x) const
144{
145 return (x < 0.0) ? -INFINITY : this->logBeta - this->beta * x;
146}
147
148template <typename RealType>
149double ExponentialRand<RealType>::F(const RealType &x) const
150{
151 return (x > 0.0) ? -std::expm1l(-this->beta * x) : 0.0;
152}
153
154template <typename RealType>
155double ExponentialRand<RealType>::S(const RealType &x) const
156{
157 return (x > 0.0) ? std::exp(-this->beta * x) : 1.0;
158}
159
160template <typename RealType>
161template <std::uniform_random_bit_generator G>
163{
164 return this->theta * StandardVariate(g);
165}
166
167template <typename RealType>
168template <std::uniform_random_bit_generator G>
173
174template <typename RealType>
175std::complex<double> ExponentialRand<RealType>::CFImpl(double t) const
176{
177 return 1.0 / std::complex<double>(1.0, -this->theta * t);
178}
179
180template <typename RealType>
182{
183 return this->EntropyAdjusted();
184}
185
186template <typename RealType>
187long double ExponentialRand<RealType>::Moment(int n) const
188{
189 if (n < 0)
190 return 0;
191 if (n == 0)
192 return 1;
193 return std::exp(math::lfact(n) - n * this->logBeta);
194}
195
196} // namespace randlib
Definition exponential_family.hpp:14
The ExponentialRand class Exponential distribution.
Definition exponential.hpp:28
double EntropyAdjusted() const override
Definition exponential.hpp:131
double SourceParameters() const override
Definition exponential.hpp:95
static RealType StandardVariate(G &g)
Definition exponential.hpp:169
double logf(const RealType &x) const override
Definition exponential.hpp:143
long double FourthMoment() const override
Definition exponential.hpp:72
double SufficientStatistic(RealType x) const override
Definition exponential.hpp:89
std::string Name() const override
Definition exponential.hpp:83
double SourceToNatural(double rate) const override
Definition exponential.hpp:101
static ExponentialRand FromScale(double scale)
Definition exponential.hpp:38
ExponentialRand(double rate=1)
Definition exponential.hpp:32
double CrossEntropyAdjusted(double rate) const override
Definition exponential.hpp:125
static ExponentialRand FromRate(double rate)
Definition exponential.hpp:35
double LogNormalizer(double theta) const override
Definition exponential.hpp:107
long double Moment(int n) const
Definition exponential.hpp:187
RealType operator()(G &g) const
Definition exponential.hpp:162
double CarrierMeasure(RealType) const override
Definition exponential.hpp:119
double F(const RealType &x) const override
Definition exponential.hpp:149
double S(const RealType &x) const override
Definition exponential.hpp:155
double f(const RealType &x) const override
Definition exponential.hpp:137
long double Entropy() const
Definition exponential.hpp:181
long double ThirdMoment() const override
Definition exponential.hpp:71
double LogNormalizerGradient(double theta) const override
Definition exponential.hpp:113
The FreeRateGammaDistribution class Abstract class for Gamma distribution with arbitrary scale/rate...
Definition continuous/gamma.hpp:252
double theta
scale θ = 1/β
Definition continuous/gamma.hpp:38
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
Real standardNormal(G &g)
Ziggurat algorithm of Marsaglia and Tsang with 256 layers and an explicit sign bit.
Definition variates.hpp:45
Real lfact(size_t n)
Calculate log(n!) using table values for small n <= 255 and built-in lgamma function for large n > 25...
Definition math/gamma.hpp:591
Definition bivariate_normal.hpp:10