24template <
typename IntType>
35 double mu = 1, delta = 6;
37 long double c1{}, c2{}, c3{}, c4{}, c{};
38 double sqrtMu = 1, sqrtMupHalfDelta = 2;
43 [[nodiscard]] std::string
Name()
const override;
45 [[nodiscard]] IntType
MinValue()
const override {
return 0; }
46 [[nodiscard]] IntType
MaxValue()
const override {
return std::numeric_limits<IntType>::max(); }
49 void SetGeneratorConstants();
53 [[nodiscard]]
inline double GetRate() const noexcept {
return lambda; }
65 [[nodiscard]]
double logP(
const IntType &k)
const override;
66 [[nodiscard]]
double F(
const IntType &k)
const override;
67 [[nodiscard]]
double S(
const IntType &k)
const override;
70 double acceptanceFunction(IntType X)
const;
71 bool generateByInversion()
const;
72 template <std::uniform_random_bit_generator G>
73 IntType variateRejection(G &g)
const;
74 template <std::uniform_random_bit_generator G>
75 IntType variateInversion(G &g)
const;
78 template <std::uniform_random_bit_generator G>
81 template <std::uniform_random_bit_generator G>
82 [[nodiscard]]
static IntType
Variate(
double rate, G &g);
84 [[nodiscard]]
long double Mean()
const override;
85 [[nodiscard]]
long double Variance()
const override;
86 [[nodiscard]] IntType
Median()
const override;
87 [[nodiscard]] IntType
Mode()
const override;
88 [[nodiscard]]
long double Skewness()
const override;
92 std::complex<double> CFImpl(
double t)
const override;
107 double significanceLevel);
140template <
typename IntType, std::uniform_random_bit_generator G>
150 probability *=
rate / k;
156 const double b = 0.931 + 2.53 *
sqrtRate, a = -0.059 + 0.02483 * b;
157 const double logInverseAlpha = std::log(1.1239 + 1.1328 / (b - 3.4)),
squeeze = 0.9277 - 3.6224 / (b - 2);
158 const double largest =
static_cast<double>(std::numeric_limits<IntType>::max());
161 const double us = 0.5 - std::fabs(u);
162 const double x = std::floor((2 * a /
us + b) * u +
rate + 0.43);
164 return (x <
largest) ?
static_cast<IntType>(x) : std::numeric_limits<IntType>::max();
170 math::stirlingError<double>(
static_cast<std::size_t
>(std::min(x,
largest)) + 1);
172 return (x <
largest) ?
static_cast<IntType>(x) : std::numeric_limits<IntType>::max();
178template <
typename IntType>
184template <
typename IntType>
187 return "Poisson(" + this->toStringWithPrecision(GetRate()) +
")";
190template <
typename IntType>
194 delta = std::max(6.0, std::min(mu, delta));
198 c2 = 1.0 / (2 * mu + delta);
200 c2 = c1 + std::exp(c2);
205 zeta = (4.0 * mu) / delta + 2;
206 c = std::exp(-(2.0 + delta) / zeta);
210 sqrtMu = std::sqrt(mu);
211 sqrtMupHalfDelta = std::sqrt(mu + 0.5 * delta);
215template <
typename IntType>
219 throw std::invalid_argument(
"Poisson distribution: rate should be positive, but it's equal to " +
220 std::to_string(rate));
223 logLambda = std::log(lambda);
224 mu = std::floor(lambda);
228 if (!generateByInversion())
229 SetGeneratorConstants();
232template <
typename IntType>
238template <
typename IntType>
244template <
typename IntType>
247 return std::log(sourceParameters);
250template <
typename IntType>
256template <
typename IntType>
259 return std::exp(theta);
262template <
typename IntType>
265 return std::exp(theta);
268template <
typename IntType>
274template <
typename IntType>
277 return parameters - lambda * std::log(parameters);
280template <
typename IntType>
283 return lambda - lambda * logLambda;
286template <
typename IntType>
297template <
typename IntType>
300 return (k >= 0.0) ?
math::qgamma(k + 1, lambda, logLambda) : 0.0;
303template <
typename IntType>
306 return (k >= 0.0) ?
math::pgamma(k + 1, lambda, logLambda) : 1.0;
309template <
typename IntType>
314 double q = X * logLambda;
320template <
typename IntType>
321bool PoissonRand<IntType>::generateByInversion()
const
328template <
typename IntType>
329template <std::uniform_random_bit_generator G>
330IntType PoissonRand<IntType>::variateRejection(G &g)
const
340 float Y = -std::fabs(N) * sqrtMu;
345 W = -0.5 * (N * N - 1.0);
347 }
else if (U <= c2) {
349 float Y = 1.0 + std::fabs(N) * sqrtMupHalfDelta;
354 W = Y * (2.0 - Y) / (2.0 * mu + delta);
356 }
else if (U <= c3) {
358 }
else if (U <= c4) {
362 float Y = delta + V * zeta;
364 W = -(2.0 + Y) / zeta;
371 }
while (++iter < ProbabilityDistribution<IntType>::MAX_ITER_REJECTION);
372 throw std::runtime_error(
"Poisson distribution: sampling failed");
375template <
typename IntType>
376template <std::uniform_random_bit_generator G>
377IntType PoissonRand<IntType>::variateInversion(G &g)
const
381 double s = Fmu, p = Pmu;
387 }
while (s < U && p > 0);
390 while (k > 0 && s > U) {
399template <
typename IntType>
400template <std::uniform_random_bit_generator G>
403 return generateByInversion() ? variateInversion(g) : variateRejection(g);
406template <
typename IntType>
407template <std::uniform_random_bit_generator G>
411 return distribution(g);
414template <
typename IntType>
417 if (generateByInversion()) {
418 for (IntType &var : outputData)
419 var = variateInversion(g);
421 for (IntType &var : outputData)
422 var = variateRejection(g);
426template <
typename IntType>
432template <
typename IntType>
438template <
typename IntType>
441 std::complex<double> y(std::cos(t) - 1.0, std::sin(t));
442 return std::exp(lambda * y);
445template <
typename IntType>
449 return std::max(std::floor(lambda + 1.0 / 3 - 0.02 / lambda), 0.0);
452template <
typename IntType>
456 return (Pmu < this->P(mu + 1)) ? mu + 1 : mu;
461template <
typename IntType>
464 return 1.0 / std::sqrt(lambda);
467template <
typename IntType>
473template <
typename IntType>
476 if (!this->allElementsAreNonNegative(sample))
478 SetRate(this->GetSampleMean(sample));
481template <
typename IntType>
483 double significanceLevel)
485 size_t n = sample.size();
487 if (significanceLevel <= 0 || significanceLevel > 1)
489 "Alpha is equal to " + this->toStringWithPrecision(significanceLevel));
493 double halfAlpha = 0.5 * significanceLevel;
495 confidenceInterval.first = ErlangRV.
Quantile(halfAlpha);
497 confidenceInterval.second = ErlangRV.
Quantile1m(halfAlpha);
500template <
typename IntType>
504 if (!this->allElementsAreNonNegative(sample))
506 double alpha = priorDistribution.
GetShape();
507 double beta = priorDistribution.
GetRate();
508 GammaRand<> posteriorDistribution(alpha + this->GetSampleSum(sample), beta + sample.size());
509 SetRate(MAP ? posteriorDistribution.
Mode() : posteriorDistribution.
Mean());
510 return posteriorDistribution;
The DiscreteDistribution class Abstract class for all discrete distributions.
Definition discrete.hpp:21
The ErlangRand class Erlang distibution.
Definition continuous/gamma.hpp:375
void SetShape(size_t shape)
Definition continuous/gamma.hpp:1100
Definition exponential_family.hpp:14
The GammaDistribution class Abstract class for Gamma distribution.
Definition continuous/gamma.hpp:31
double GetShape() const noexcept
Definition continuous/gamma.hpp:78
long double Mean() const override
Definition continuous/gamma.hpp:693
double GetRate() const noexcept
Definition continuous/gamma.hpp:86
RealType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition continuous/gamma.hpp:717
The GammaRand class Gamma distribution.
Definition continuous/gamma.hpp:295
The PoissonRand class Poisson distribution.
Definition poisson.hpp:26
double LogNormalizerGradient(double theta) const override
Definition poisson.hpp:263
void Fit(std::span< const IntType > sample, DoublePair &confidenceInterval, double significanceLevel)
Fit.
Definition poisson.hpp:482
long double Variance() const override
Definition poisson.hpp:433
double F(const IntType &k) const override
Definition poisson.hpp:298
double CrossEntropyAdjusted(double parameters) const override
Definition poisson.hpp:275
GammaRand FitBayes(std::span< const IntType > sample, const GammaDistribution<> &priorDistribution, bool MAP=false)
fit rate λ via Bayes estimation
Definition poisson.hpp:501
IntType Median() const override
Definition poisson.hpp:446
IntType operator()(G &g) const
Definition poisson.hpp:401
Support SupportType() const override
Definition poisson.hpp:44
long double ExcessKurtosis() const override
Definition poisson.hpp:468
double SufficientStatistic(IntType x) const override
Definition poisson.hpp:233
long double Mean() const override
Definition poisson.hpp:427
IntType MaxValue() const override
Definition poisson.hpp:46
void SetRate(double rate)
Definition poisson.hpp:216
double CarrierMeasure(IntType x) const override
Definition poisson.hpp:269
double GetRate() const noexcept
Definition poisson.hpp:53
IntType MinValue() const override
Definition poisson.hpp:45
double S(const IntType &k) const override
Definition poisson.hpp:304
double EntropyAdjusted() const override
Definition poisson.hpp:281
std::string Name() const override
Definition poisson.hpp:185
double LogNormalizer(double theta) const override
Definition poisson.hpp:257
long double Skewness() const override
Definition poisson.hpp:462
IntType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition poisson.hpp:453
void Fit(std::span< const IntType > sample)
fit rate λ via maximum-likelihood method
Definition poisson.hpp:474
static IntType Variate(double rate, G &g)
Definition poisson.hpp:408
double SourceToNatural(double sourceParameters) const override
Definition poisson.hpp:245
double logP(const IntType &k) const override
Definition poisson.hpp:287
double SourceParameters() const override
Definition poisson.hpp:239
PoissonRand(double rate=1.0)
Definition poisson.hpp:179
double NaturalParameters() const override
Definition poisson.hpp:251
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
T Quantile(double p) const
Definition univariate.hpp:307
T Quantile1m(double p) const
Definition univariate.hpp:324
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
#define RANDLIB_DETAIL_SUPPRESS_DEPRECATED_END
Definition fwd.hpp:26
#define RANDLIB_DETAIL_SUPPRESS_DEPRECATED_BEGIN
Definition fwd.hpp:25
#define RANDLIB_DEPRECATED_FIT_MEMBER
Definition fwd.hpp:9
constexpr long double inv_pi
Definition constants.hpp:24
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 inv_e
Definition constants.hpp:35
constexpr long double lnpi
Definition constants.hpp:21
IntType poissonVariate(double rate, G &g)
Poisson variate for a rate that changes from call to call, as in mixtures: the setup is a few element...
Definition poisson.hpp:141
Real standardNormal(G &g)
Ziggurat algorithm of Marsaglia and Tsang with 256 layers and an explicit sign bit.
Definition variates.hpp:45
bool areClose(RealType a, RealType b, RealType eps=1e-6)
Definition functions.hpp:38
Real qgamma(std::type_identity_t< Real > a, Real x, std::type_identity_t< Real > logA, std::type_identity_t< Real > lgammaA)
Calculate upper regularized incomplete gamma function, accelerated by using precalculated values of l...
Definition math/gamma.hpp:938
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
Real bd0(std::type_identity_t< Real > x, Real m)
Deviance term of the saddle-point expansions of Poisson and binomial probabilities (C.
Definition math/gamma.hpp:620
Real stirlingError(size_t n)
Definition math/gamma.hpp:598
Real pgamma(std::type_identity_t< Real > a, Real x, std::type_identity_t< Real > logA, std::type_identity_t< Real > lgammaA)
Calculate lower regularized incomplete gamma function, accelerated by using precalculated value of lo...
Definition math/gamma.hpp:896
Definition bivariate_normal.hpp:10
@ WrongSample
the sample could not have been drawn from this distribution
@ WrongLevel
the significance level is not in (0, 1)
Support
Shape of the support of a univariate distribution.
Definition univariate.hpp:15
Pair< double > DoublePair
Definition fwd.hpp:39