RandLib 2.0.0
Probability distributions, fitting, and heavy-tail tools for C++20
Loading...
Searching...
No Matches
yule.hpp
Go to the documentation of this file.
1#pragma once
2
8
9namespace randlib
10{
11
21template <typename IntType>
22class YuleRand final : public DiscreteDistribution<IntType>
23{
24 IntType variate(detail::EngineRef g) const override { return (*this)(g); }
25
26 double rho = 0;
27 double lgamma1pRo = 0;
28
30
31public:
32 explicit YuleRand(double shape);
33 [[nodiscard]] std::string Name() const override;
34 [[nodiscard]] Support SupportType() const override { return Support::RightSemiFinite; }
35 [[nodiscard]] IntType MinValue() const override { return 1; }
36 [[nodiscard]] IntType MaxValue() const override { return std::numeric_limits<IntType>::max(); }
37
38 void SetShape(double shape);
39 [[nodiscard]] inline double GetShape() const noexcept { return rho; }
40
41 [[nodiscard]] double logP(const IntType &k) const override;
42 [[nodiscard]] double F(const IntType &k) const override;
43 [[nodiscard]] double S(const IntType &k) const override;
44 template <std::uniform_random_bit_generator G>
45 [[nodiscard]] IntType operator()(G &g) const;
46
47 template <std::uniform_random_bit_generator G>
48 [[nodiscard]] static IntType Variate(double shape, G &g);
49
50 [[nodiscard]] long double Mean() const override;
51 [[nodiscard]] long double Variance() const override;
52 [[nodiscard]] IntType Mode() const override;
53 [[nodiscard]] long double Skewness() const override;
54 [[nodiscard]] long double ExcessKurtosis() const override;
55};
56
57} // namespace randlib
58
61
62namespace randlib
63{
64
65template <typename IntType>
66YuleRand<IntType>::YuleRand(double shape) : X(shape, 1.0)
67{
68 SetShape(shape);
69}
70
71template <typename IntType>
72std::string YuleRand<IntType>::Name() const
73{
74 return "Yule(" + this->toStringWithPrecision(GetShape()) + ")";
75}
76
77template <typename IntType>
79{
80 if (!(shape > 0.0))
81 throw std::invalid_argument("Yule distribution: shape should be positive");
82 rho = shape;
83 lgamma1pRo = std::lgammal(rho + 1);
84 X.SetShape(rho);
85}
86
87template <typename IntType>
88double YuleRand<IntType>::logP(const IntType &k) const
89{
90 if (k < 1)
91 return -INFINITY;
92 double y = lgamma1pRo;
93 y += math::lfact(k - 1);
94 y -= std::lgammal(k + rho + 1);
95 y += X.GetLogShape();
96 return y;
97}
98
99template <typename IntType>
100double YuleRand<IntType>::F(const IntType &k) const
101{
102 if (k < 1)
103 return 0.0;
104 double y = lgamma1pRo;
105 y += math::lfact(k - 1);
106 y -= std::lgammal(k + rho + 1);
107 double logk = std::log(k);
108 return -std::expm1(y + logk);
109}
110
111template <typename IntType>
112double YuleRand<IntType>::S(const IntType &k) const
113{
114 if (k < 1)
115 return 1.0;
116 double y = lgamma1pRo;
117 y += math::lfact(k - 1);
118 y -= std::lgammal(k + rho + 1);
119 y = std::exp(y);
120 return k * y;
121}
122
123template <typename IntType>
124template <std::uniform_random_bit_generator G>
126{
127 double prob = 1.0 / X(g);
128 return GeometricRand<IntType>::Variate(prob, g) + 1;
129}
130
131template <typename IntType>
132template <std::uniform_random_bit_generator G>
133IntType YuleRand<IntType>::Variate(double shape, G &g)
134{
135 if (!(shape > 0.0))
136 throw std::invalid_argument("Yule distribution: shape should be positive");
137 double prob = 1.0 / ParetoRand<double>::StandardVariate(shape, g);
138 return GeometricRand<IntType>::Variate(prob, g) + 1;
139}
140
141template <typename IntType>
142long double YuleRand<IntType>::Mean() const
143{
144 return (rho <= 1) ? INFINITY : rho / (rho - 1);
145}
146
147template <typename IntType>
149{
150 if (rho <= 2)
151 return INFINITY;
152 double aux = rho / (rho - 1);
153 return aux * aux / (rho - 2);
154}
155
156template <typename IntType>
158{
159 return 1;
160}
161
162template <typename IntType>
164{
165 if (rho <= 3)
166 return INFINITY;
167 long double skewness = rho + 1;
168 skewness *= skewness;
169 skewness *= std::sqrt(rho - 2);
170 return skewness / (rho * (rho - 3));
171}
172
173template <typename IntType>
175{
176 if (rho <= 4)
177 return INFINITY;
178 long double numerator = 11 * rho * rho - 49;
179 numerator *= rho;
180 numerator -= 22;
181 long double denominator = rho * (rho - 4) * (rho - 3);
182 return rho + 3 + numerator / denominator;
183}
184
185} // namespace randlib
The DiscreteDistribution class Abstract class for all discrete distributions.
Definition discrete.hpp:21
The ParetoRand class Pareto distribution.
Definition pareto.hpp:24
static RealType StandardVariate(double shape, G &g)
Definition pareto.hpp:219
T Variate() const
Uses the engine of this object, so it is not thread-safe for one object; use operator() with one engi...
Definition distribution.hpp:133
The YuleRand class Yule distribution.
Definition yule.hpp:23
long double Variance() const override
Definition yule.hpp:148
double GetShape() const noexcept
Definition yule.hpp:39
double F(const IntType &k) const override
Definition yule.hpp:100
IntType operator()(G &g) const
Definition yule.hpp:125
IntType MinValue() const override
Definition yule.hpp:35
double S(const IntType &k) const override
Definition yule.hpp:112
IntType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition yule.hpp:157
long double Skewness() const override
Definition yule.hpp:163
IntType MaxValue() const override
Definition yule.hpp:36
Support SupportType() const override
Definition yule.hpp:34
std::string Name() const override
Definition yule.hpp:72
long double ExcessKurtosis() const override
Definition yule.hpp:174
void SetShape(double shape)
Definition yule.hpp:78
double logP(const IntType &k) const override
Definition yule.hpp:88
long double Mean() const override
Definition yule.hpp:142
YuleRand(double shape)
Definition yule.hpp:66
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
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
Support
Shape of the support of a univariate distribution.
Definition univariate.hpp:15
@ RightSemiFinite
[a, ∞)