RandLib 2.0.0
Probability distributions, fitting, and heavy-tail tools for C++20
Loading...
Searching...
No Matches
raised_cosine.hpp
Go to the documentation of this file.
1#pragma once
2
7
8namespace randlib
9{
10
17template <typename RealType>
19{
20 RealType variate(detail::EngineRef g) const override { return (*this)(g); }
21
22 double mu = 0;
23 double s = randlib::consts::pi;
24 double s_pi = 1;
26
27protected:
28 RaisedCosineDistribution(double location, double scale);
29
30public:
31 [[nodiscard]] Support SupportType() const override { return Support::Finite; }
32 [[nodiscard]] RealType MinValue() const override { return mu - s; }
33 [[nodiscard]] RealType MaxValue() const override { return mu + s; }
34
35protected:
36 void SetLocation(double location);
37 void SetScale(double scale);
38
39public:
40 [[nodiscard]] inline double GetLocation() const noexcept { return mu; }
41 [[nodiscard]] inline double GetScale() const noexcept { return s; }
42
43 [[nodiscard]] double f(const RealType &x) const override;
44 [[nodiscard]] double logf(const RealType &x) const override;
45 [[nodiscard]] double F(const RealType &x) const override;
46 [[nodiscard]] double S(const RealType &x) const override;
47
48 template <std::uniform_random_bit_generator G>
49 [[nodiscard]] static RealType StandardVariate(G &g);
50 template <std::uniform_random_bit_generator G>
51 [[nodiscard]] RealType operator()(G &g) const;
52
53 [[nodiscard]] long double Mean() const override;
54 [[nodiscard]] long double Variance() const override;
55 [[nodiscard]] RealType Median() const override;
56 [[nodiscard]] RealType Mode() const override;
57 [[nodiscard]] long double Skewness() const override;
58 [[nodiscard]] long double ExcessKurtosis() const override;
59
60private:
61 std::complex<double> CFImpl(double t) const override;
62};
63
68template <typename RealType>
69class RaisedCosineRand final : public RaisedCosineDistribution<RealType>
70{
71public:
72 RaisedCosineRand(double location = 0, double scale = randlib::consts::pi)
73 : RaisedCosineDistribution<RealType>(location, scale)
74 {
75 }
76 [[nodiscard]] std::string Name() const override;
77
80};
81
91template <typename RealType>
92class RaabGreenRand final : public RaisedCosineDistribution<RealType>
93{
94public:
95 RaabGreenRand() : RaisedCosineDistribution<RealType>(0.0, randlib::consts::pi) {}
96 [[nodiscard]] std::string Name() const override;
97};
98
99} // namespace randlib
100
102
103namespace randlib
104{
105
106template <typename RealType>
108{
109 SetLocation(location);
110 SetScale(scale);
111}
112
113template <typename RealType>
115{
116 if (!std::isfinite(location))
117 throw std::invalid_argument("Raised cosine distribution: location should be finite");
118 mu = location;
119}
120
121template <typename RealType>
123{
124 if (!(scale > 0.0))
125 throw std::invalid_argument("Raised-Cosine distribution: scale should be positive");
126 s = scale;
127 s_pi = s * randlib::consts::inv_pi;
128 log2S = std::log(2 * s);
129}
130
131template <typename RealType>
132double RaisedCosineDistribution<RealType>::f(const RealType &x) const
133{
134 double xAdj = (x - mu) / s_pi;
135 if (xAdj <= -static_cast<double>(randlib::consts::pi) || xAdj >= static_cast<double>(randlib::consts::pi))
136 return 0.0;
137 double y = std::cos(xAdj) + 1.0;
138 return 0.5 * y / s;
139}
140
141template <typename RealType>
142double RaisedCosineDistribution<RealType>::logf(const RealType &x) const
143{
144 double xAdj = (x - mu) / s_pi;
145 if (xAdj <= -static_cast<double>(randlib::consts::pi) || xAdj >= static_cast<double>(randlib::consts::pi))
146 return -INFINITY;
147 double y = std::cos(xAdj);
148 y = std::log1pl(y);
149 return y - log2S;
150}
151
152template <typename RealType>
153double RaisedCosineDistribution<RealType>::F(const RealType &x) const
154{
155 double xAdj = (x - mu) / s;
156 if (xAdj <= -1)
157 return 0.0;
158 if (xAdj >= 1)
159 return 1.0;
160 double y = std::sin(xAdj * randlib::consts::pi);
162 y += xAdj + 1;
163 return 0.5 * y;
164}
165
166template <typename RealType>
167double RaisedCosineDistribution<RealType>::S(const RealType &x) const
168{
169 double xAdj = (x - mu) / s;
170 if (xAdj <= -1)
171 return 1.0;
172 if (xAdj >= 1)
173 return 0.0;
174 double y = std::sin(xAdj * randlib::consts::pi);
176 y += xAdj;
177 return 0.5 - 0.5 * y;
178}
179
180template <typename RealType>
181template <std::uniform_random_bit_generator G>
183{
186 RealType XSq = X * X;
187 RealType U = 2 * detail::uniform01<RealType>(g);
188 int a = 0, b = -1;
189 RealType W = 0.0, V = 1.0;
190 size_t iter = 0;
191 do {
192 a += 2;
193 b += 2;
194 V *= XSq / (a * b);
195 W += V;
196 if (U >= W)
197 return X;
198 a += 2;
199 b += 2;
200 V *= XSq / (a * b);
201 W -= V;
202 if (U <= W) {
203 if (X == 0.0)
204 return 0.0;
205 return (X > 0.0) ? randlib::consts::pi - X : -randlib::consts::pi - X;
206 }
208 throw std::runtime_error("Raised-Cosine distribution: sampling failed");
209}
210
211template <typename RealType>
212template <std::uniform_random_bit_generator G>
214{
215 return mu + s_pi * StandardVariate(g);
216}
217
218template <typename RealType>
220{
221 return mu;
222}
223
224template <typename RealType>
226{
227 static constexpr double coef = 1.0 / 3 - 2.0 / randlib::consts::pi_sq;
228 return s * s * coef;
229}
230
231template <typename RealType>
232std::complex<double> RaisedCosineDistribution<RealType>::CFImpl(double t) const
233{
235 double st = s * t;
236 double u = static_cast<double>(randlib::consts::pi - st);
237 double sinc = (u == 0.0) ? 1.0 : std::sin(u) / u;
238 double y = randlib::consts::pi_sq * sinc / (st * (randlib::consts::pi + st));
239 return y * std::exp(std::complex<double>(0.0, mu * t));
240}
241
242template <typename RealType>
244{
245 return mu;
246}
247
248template <typename RealType>
250{
251 return mu;
252}
253
254template <typename RealType>
256{
257 return 0.0l;
258}
259
260template <typename RealType>
262{
263 static constexpr long double numerator = 1.2 * (90.0 - randlib::consts::pi_sq * randlib::consts::pi_sq);
264 static constexpr long double denominator = randlib::consts::pi_sq - 6.0;
265 static constexpr long double y = numerator / (denominator * denominator);
266 return y;
267}
268template <typename RealType>
270{
271 return "Raised cosine(" + this->toStringWithPrecision(this->GetLocation()) + ", " +
272 this->toStringWithPrecision(this->GetScale()) + ")";
273}
274template <typename RealType>
276{
277 return "Raab Green";
278}
279
280} // namespace randlib
The ContinuousDistribution class Abstract class for all continuous distributions.
Definition continuous.hpp:22
The ProbabilityDistribution class Abstract class for all probability distributions.
Definition distribution.hpp:28
The RaabGreenRand class Raab-Green distribution.
Definition raised_cosine.hpp:93
std::string Name() const override
Definition raised_cosine.hpp:275
RaabGreenRand()
Definition raised_cosine.hpp:95
The RaisedCosineDistribution class Abstract class for Raised-cosine distribution.
Definition raised_cosine.hpp:19
RaisedCosineDistribution(double location, double scale)
Definition raised_cosine.hpp:107
double F(const RealType &x) const override
Definition raised_cosine.hpp:153
double S(const RealType &x) const override
Definition raised_cosine.hpp:167
double logf(const RealType &x) const override
Definition raised_cosine.hpp:142
long double Skewness() const override
Definition raised_cosine.hpp:255
double GetLocation() const noexcept
Definition raised_cosine.hpp:40
RealType MinValue() const override
Definition raised_cosine.hpp:32
RealType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition raised_cosine.hpp:249
long double Mean() const override
Definition raised_cosine.hpp:219
static RealType StandardVariate(G &g)
Definition raised_cosine.hpp:182
void SetLocation(double location)
Definition raised_cosine.hpp:114
RealType MaxValue() const override
Definition raised_cosine.hpp:33
RealType Median() const override
Definition raised_cosine.hpp:243
void SetScale(double scale)
Definition raised_cosine.hpp:122
Support SupportType() const override
Definition raised_cosine.hpp:31
double f(const RealType &x) const override
Definition raised_cosine.hpp:132
double GetScale() const noexcept
Definition raised_cosine.hpp:41
RealType operator()(G &g) const
Definition raised_cosine.hpp:213
long double Variance() const override
Definition raised_cosine.hpp:225
long double ExcessKurtosis() const override
Definition raised_cosine.hpp:261
The RaisedCosineRand class Raised-cosine distribution.
Definition raised_cosine.hpp:70
std::string Name() const override
Definition raised_cosine.hpp:269
RaisedCosineRand(double location=0, double scale=randlib::consts::pi)
Definition raised_cosine.hpp:72
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
constexpr long double inv_pi
Definition constants.hpp:24
constexpr long double ln2
Definition constants.hpp:18
constexpr long double half_pi
Definition constants.hpp:23
constexpr long double pi
Definition constants.hpp:22
constexpr long double pi_sq
Definition constants.hpp:39
constexpr long double lnpi
Definition constants.hpp:21
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