17template <
typename RealType>
26 static constexpr double CK = 10.5;
29 VonMisesRand(
double location = 0,
double concentration = 1);
31 [[nodiscard]] std::string
Name()
const override;
37 double cdfSeries(
double x)
const;
40 double lowerTail(
double d)
const;
41 double cdfErfcAux(RealType x)
const;
42 double cdfErfc(RealType x)
const;
43 double ccdfErfc(RealType x)
const;
46 [[nodiscard]]
double f(
const RealType &x)
const override;
47 [[nodiscard]]
double logf(
const RealType &x)
const override;
48 [[nodiscard]]
double F(
const RealType &x)
const override;
49 [[nodiscard]]
double S(
const RealType &x)
const override;
50 template <std::uniform_random_bit_generator G>
55 [[nodiscard]] RealType
Median()
const override;
56 [[nodiscard]] RealType
Mode()
const override;
59 std::complex<double> CFImpl(
double t)
const override;
69template <
typename RealType>
75template <
typename RealType>
78 return "von Mises(" + this->toStringWithPrecision(this->GetLocation()) +
", " +
79 this->toStringWithPrecision(this->GetConcentration()) +
")";
82template <
typename RealType>
85 if (!(concentration > 0.0))
86 throw std::invalid_argument(
"von Mises distribution: concentration parameter should be positive");
92 static constexpr double a[] = {28.0, 0.5, 100.0, 5.0};
93 p = std::ceil(a[0] + a[1] * k - a[2] / (k + a[3]));
97template <
typename RealType>
101 double sinX = std::sin(x), cosX = std::cos(x);
103 double sn = std::sin(px), cn = std::cos(px);
105 for (
int n = p - 1; n > 0; --n) {
122template <
typename RealType>
123double VonMisesRand<RealType>::cdfErfcAux(RealType x)
const
128 double r = std::sqrt((54.0 / (347.0 / v + 26.0 - c) - 6.0 + c) / 12.0);
129 double z = -std::sin(0.5 * x) * r;
130 double twoZSq = 2.0 * z * z;
132 double y = (c - 2 * twoZSq - 16.0) / 3.0;
133 y = ((twoZSq + 1.75) * twoZSq + 83.5) / v - y;
135 return z * (1.0 - twoZSq / y);
138template <
typename RealType>
139double VonMisesRand<RealType>::cdfErfc(RealType x)
const
141 double arg = cdfErfcAux(x);
142 return 0.5 * std::erfc(arg);
145template <
typename RealType>
146double VonMisesRand<RealType>::ccdfErfc(RealType x)
const
148 double arg = cdfErfcAux(x);
149 return 0.5 * std::erfc(-arg);
152template <
typename RealType>
155 return (x < this->MinValue() || x > this->MaxValue()) ? 0.0 : std::exp(logf(x));
158template <
typename RealType>
161 if (x < this->MinValue() || x > this->MaxValue())
163 double y = k * std::cos(x - this->loc) - logI0k;
168template <
typename RealType>
171 if (x <= this->MinValue())
173 if (x >= this->MaxValue())
175 double xAdj = x - this->loc;
177 return cdfErfc(xAdj);
179 return (xAdj <= 0) ? lowerTail(xAdj) : 1.0 - lowerTail(-xAdj);
182template <
typename RealType>
185 static constexpr double SMALL_TAIL = 1e-3;
186 const double series = cdfSeries(d);
187 if (series >= SMALL_TAIL)
192template <
typename RealType>
195 if (x <= this->MinValue())
197 if (x >= this->MaxValue())
199 double xAdj = x - this->loc;
201 return ccdfErfc(xAdj);
202 return (xAdj >= 0) ? lowerTail(-xAdj) : 1.0 - lowerTail(xAdj);
205template <
typename RealType>
206template <std::uniform_random_bit_generator G>
215 RealType theta = s * V / U;
217 ((k * theta * theta < 4.0 * (1.0 - U)) || (k * std::cos(theta) >= 2 * std::log(U) + k)))
218 return this->loc + theta;
220 throw std::runtime_error(
"von Mises distribution: sampling failed");
223template <
typename RealType>
229template <
typename RealType>
234 return -std::expm1l(var);
237template <
typename RealType>
241 if (t != std::round(t))
243 double tloc = t * this->loc;
244 double cosTloc = std::cos(tloc), sinTloc = std::sin(tloc);
245 std::complex<double> y(cosTloc, sinTloc);
247 return y * std::exp(z);
250template <
typename RealType>
256template <
typename RealType>
The CircularDistribution class Abstract class for all continuous circular distributions.
Definition circular.hpp:19
The ProbabilityDistribution class Abstract class for all probability distributions.
Definition distribution.hpp:28
virtual std::complex< double > CFImpl(double t) const
Definition univariate.hpp:365
The VonMisesRand class Von-Mises distribution.
Definition von_mises.hpp:19
double S(const RealType &x) const override
Definition von_mises.hpp:193
long double CircularMean() const override
Definition von_mises.hpp:224
RealType operator()(G &g) const
Definition von_mises.hpp:207
VonMisesRand(double location=0, double concentration=1)
Definition von_mises.hpp:70
double logf(const RealType &x) const override
Definition von_mises.hpp:159
double GetConcentration() const noexcept
Definition von_mises.hpp:34
double F(const RealType &x) const override
Definition von_mises.hpp:169
long double CircularVariance() const override
Definition von_mises.hpp:230
double f(const RealType &x) const override
Definition von_mises.hpp:153
RealType Median() const override
Definition von_mises.hpp:251
void SetConcentration(double concentration)
Definition von_mises.hpp:83
std::string Name() const override
Definition von_mises.hpp:76
RealType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition von_mises.hpp:257
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
constexpr long double ln2
Definition constants.hpp:18
constexpr long double pi
Definition constants.hpp:22
constexpr long double e
Definition constants.hpp:15
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
Real logBesselI(std::type_identity_t< Real > nu, Real x)
Calculates logarithm of modified Bessel function of the 1st kind.
Definition functions.hpp:577
Real integrate(const F &f, std::type_identity_t< Real > a, std::type_identity_t< Real > b, std::type_identity_t< Real > tolerance=1e-11, int maxSubdivisions=512)
Global adaptive Gauss-Kronrod quadrature (QUADPACK QAG).
Definition quadrature.hpp:226
Definition bivariate_normal.hpp:10