RandLib 2.0.0
Probability distributions, fitting, and heavy-tail tools for C++20
Loading...
Searching...
No Matches
fisher_f.hpp
Go to the documentation of this file.
1#pragma once
2
8
9namespace randlib
10{
11
21template <typename RealType>
22class FisherFRand final : public ContinuousDistribution<RealType>
23{
24 RealType variate(detail::EngineRef g) const override { return (*this)(g); }
25 void sample(detail::EngineRef g, std::span<RealType> outputData) const override;
26
27 int d1 = 2;
28 int d2 = 2;
29 double a = 0;
30 double d1_d2 = 1;
31 double c = -2;
32 double d2_d1 = 1;
33 double pdfCoef = 0;
34
36
37public:
38 FisherFRand(int degree1 = 2, int degree2 = 2);
39
40 [[nodiscard]] std::string Name() const override;
41 [[nodiscard]] Support SupportType() const override { return Support::RightSemiFinite; }
42 [[nodiscard]] RealType MinValue() const override { return 0; }
43 [[nodiscard]] RealType MaxValue() const override { return INFINITY; }
44
45 void SetDegrees(int degree1, int degree2);
46 [[nodiscard]] inline int GetFirstDegree() const noexcept { return d1; }
47 [[nodiscard]] inline int GetSecondDegree() const noexcept { return d2; }
48
49 [[nodiscard]] double f(const RealType &x) const override;
50 [[nodiscard]] double logf(const RealType &x) const override;
51 [[nodiscard]] double F(const RealType &x) const override;
52 [[nodiscard]] double S(const RealType &x) const override;
53 template <std::uniform_random_bit_generator G>
54 [[nodiscard]] RealType operator()(G &g) const;
55
56 [[nodiscard]] long double Mean() const override;
57 [[nodiscard]] long double Variance() const override;
58 [[nodiscard]] RealType Median() const override;
59 [[nodiscard]] RealType Mode() const override;
60 [[nodiscard]] long double Skewness() const override;
61 [[nodiscard]] long double ExcessKurtosis() const override;
62
63private:
64 RealType quantileImpl(double p) const override;
65 RealType quantileImpl1m(double p) const override;
66 std::complex<double> CFImpl(double t) const override;
67};
68
69} // namespace randlib
70
71namespace randlib
72{
73
74template <typename RealType>
75FisherFRand<RealType>::FisherFRand(int degree1, int degree2)
76{
77 SetDegrees(degree1, degree2);
78}
79
80template <typename RealType>
81std::string FisherFRand<RealType>::Name() const
82{
83 return "Fisher-F(" + this->toStringWithPrecision(GetFirstDegree()) + ", " +
84 this->toStringWithPrecision(GetSecondDegree()) + ")";
85}
86
87template <typename RealType>
88void FisherFRand<RealType>::SetDegrees(int degree1, int degree2)
89{
90 if (!(degree1 > 0 && degree2 > 0))
91 throw std::invalid_argument("F-distribution: degrees of should be positive");
92
93 d1 = degree1;
94 d2 = degree2;
95
96 B.SetShapes(0.5 * d1, 0.5 * d2);
97
98 a = 0.5 * d1 - 1;
99 d1_d2 = static_cast<double>(d1) / d2;
100 c = -0.5 * (d1 + d2);
101 d2_d1 = 1.0 / d1_d2;
102
103 pdfCoef = (a + 1) * std::log(d1_d2);
104 pdfCoef -= B.GetLogBetaFunction();
105}
106
107template <typename RealType>
108double FisherFRand<RealType>::f(const RealType &x) const
109{
110 if (x < 0.0)
111 return 0.0;
112 if (x == 0.0) {
113 if (a == 0.0)
114 return std::exp(pdfCoef);
115 return (a > 0) ? 0.0 : INFINITY;
116 }
117 return std::exp(logf(x));
118}
119
120template <typename RealType>
121double FisherFRand<RealType>::logf(const RealType &x) const
122{
123 if (x < 0.0)
124 return -INFINITY;
125 if (x == 0.0) {
126 if (a == 0.0)
127 return pdfCoef;
128 return (a > 0) ? -INFINITY : INFINITY;
129 }
130 double y = a * std::log(x);
131 y += c * std::log1pl(d1_d2 * x);
132 return pdfCoef + y;
133}
134
135template <typename RealType>
136double FisherFRand<RealType>::F(const RealType &x) const
137{
138 return B.F(d1_d2 * x);
139}
140
141template <typename RealType>
142double FisherFRand<RealType>::S(const RealType &x) const
143{
144 return B.S(d1_d2 * x);
145}
146
147template <typename RealType>
148template <std::uniform_random_bit_generator G>
150{
151 return d2_d1 * B(g);
152}
153
154template <typename RealType>
155void FisherFRand<RealType>::sample(detail::EngineRef g, std::span<RealType> outputData) const
156{
157 B.Sample(g, outputData);
158 for (RealType &var : outputData)
159 var = d2_d1 * var;
160}
161
162template <typename RealType>
164{
165 return (d2 > 2) ? 1 + 2.0 / (d2 - 2) : INFINITY;
166}
167
168template <typename RealType>
170{
171 if (d2 <= 4)
172 return INFINITY;
173 double variance = d2;
174 variance /= d2 - 2;
175 variance *= variance;
176 variance *= 2 * (d1 + d2 - 2);
177 variance /= d1;
178 variance /= d2 - 4;
179 return variance;
180}
181
182template <typename RealType>
184{
185 return d2_d1 * B.Median();
186}
187
188template <typename RealType>
190{
191 if (d1 <= 2)
192 return 0.0;
193 return d2_d1 * (d1 - 2) / (d2 + 2);
194}
195
196template <typename RealType>
198{
199 if (d2 <= 6)
200 return INFINITY;
201 long double skewness = 8.0 * (d2 - 4.0);
202 long double aux = d1 + d2 - 2;
203 skewness /= d1 * aux;
204 skewness = std::sqrt(skewness);
205 skewness *= d1 + aux;
206 skewness /= d2 - 6.0;
207 return skewness;
208}
209
210template <typename RealType>
212{
213 if (d2 <= 8)
214 return INFINITY;
215 long double kurtosis = d2 - 2;
216 kurtosis *= kurtosis;
217 kurtosis *= d2 - 4;
218 kurtosis /= d1;
219 kurtosis /= d1 + d2 - 2;
220 kurtosis += 5 * d2 - 22;
221 kurtosis /= d2 - 6;
222 kurtosis /= d2 - 8;
223 return 12.0 * kurtosis;
224}
225
226template <typename RealType>
227RealType FisherFRand<RealType>::quantileImpl(double p) const
228{
229 return d2_d1 * B.Quantile(p);
230}
231
232template <typename RealType>
233RealType FisherFRand<RealType>::quantileImpl1m(double p) const
234{
235 return d2_d1 * B.Quantile1m(p);
236}
237
238template <typename RealType>
239std::complex<double> FisherFRand<RealType>::CFImpl(double t) const
240{
241 return B.CF(d2_d1 * t);
242}
243
244} // namespace randlib
The BetaPrimeRand class Beta-prime distribution.
Definition beta_prime.hpp:32
The ContinuousDistribution class Abstract class for all continuous distributions.
Definition continuous.hpp:22
The FisherFRand class F-distribution.
Definition fisher_f.hpp:23
double logf(const RealType &x) const override
Definition fisher_f.hpp:121
double F(const RealType &x) const override
Definition fisher_f.hpp:136
long double Variance() const override
Definition fisher_f.hpp:169
Support SupportType() const override
Definition fisher_f.hpp:41
RealType operator()(G &g) const
Definition fisher_f.hpp:149
long double Skewness() const override
Definition fisher_f.hpp:197
long double ExcessKurtosis() const override
Definition fisher_f.hpp:211
std::string Name() const override
Definition fisher_f.hpp:81
double f(const RealType &x) const override
Definition fisher_f.hpp:108
void SetDegrees(int degree1, int degree2)
Definition fisher_f.hpp:88
RealType MaxValue() const override
Definition fisher_f.hpp:43
int GetSecondDegree() const noexcept
Definition fisher_f.hpp:47
RealType MinValue() const override
Definition fisher_f.hpp:42
int GetFirstDegree() const noexcept
Definition fisher_f.hpp:46
RealType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition fisher_f.hpp:189
FisherFRand(int degree1=2, int degree2=2)
Definition fisher_f.hpp:75
RealType Median() const override
Definition fisher_f.hpp:183
double S(const RealType &x) const override
Definition fisher_f.hpp:142
long double Mean() const override
Definition fisher_f.hpp:163
void Sample(std::span< T > outputData) const
Fills the output with variates drawn with the engine of this object.
Definition distribution.hpp:139
T Quantile(double p) const
Definition univariate.hpp:307
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
Definition bivariate_normal.hpp:10
Support
Shape of the support of a univariate distribution.
Definition univariate.hpp:15
@ RightSemiFinite
[a, ∞)