23template <
typename RealType>
30 double expHalfSigmaSq = 1.6487212707;
42 if (!(logStandardDeviation > 0.0))
43 throw std::invalid_argument(
"Log-Normal distribution: scale should be positive");
44 return LogNormalRand(logMean, logStandardDeviation * logStandardDeviation);
57 [[nodiscard]] std::string
Name()
const override;
59 [[nodiscard]] RealType
MinValue()
const override {
return 0; }
60 [[nodiscard]] RealType
MaxValue()
const override {
return INFINITY; }
64 [[nodiscard]]
inline double GetLocation()
const {
return X.Mean(); }
65 [[nodiscard]]
inline double GetScale()
const {
return X.GetScale(); }
67 [[nodiscard]]
double f(
const RealType &x)
const override;
68 [[nodiscard]]
double logf(
const RealType &x)
const override;
69 [[nodiscard]]
double F(
const RealType &x)
const override;
70 [[nodiscard]]
double S(
const RealType &x)
const override;
72 template <std::uniform_random_bit_generator G>
75 template <std::uniform_random_bit_generator G>
78 [[nodiscard]]
long double Mean()
const override;
79 [[nodiscard]]
long double Variance()
const override;
80 [[nodiscard]] RealType
Median()
const override;
81 [[nodiscard]] RealType
Mode()
const override;
82 [[nodiscard]]
long double Skewness()
const override;
86 RealType quantileImpl(
double p)
const override;
87 RealType quantileImpl1m(
double p)
const override;
88 std::complex<double> CFImpl(
double t)
const override;
145template <
typename RealType>
148 if (!(squaredScale > 0.0))
149 throw std::invalid_argument(
"Log-Normal distribution: squared scale should be positive");
150 SetLocation(location);
151 SetScale(std::sqrt(squaredScale));
154template <
typename RealType>
157 return "Log-Normal(" + this->toStringWithPrecision(GetLocation()) +
", " + this->toStringWithPrecision(GetScale()) +
161template <
typename RealType>
164 if (!std::isfinite(location))
165 throw std::invalid_argument(
"Log-Normal distribution: location should be finite");
166 X.SetLocation(location);
167 expMu = std::exp(X.GetLocation());
170template <
typename RealType>
174 throw std::invalid_argument(
"Log-Normal distribution: scale should be positive");
176 expHalfSigmaSq = std::exp(0.5 * X.Variance());
179template <
typename RealType>
182 return (x > 0.0) ? std::exp(logf(x)) : 0.0;
185template <
typename RealType>
190 double logX = std::log(x);
191 double y = X.logf(logX);
195template <
typename RealType>
198 return (x > 0.0) ? X.F(std::log(x)) : 0.0;
201template <
typename RealType>
204 return (x > 0.0) ? X.S(std::log(x)) : 1.0;
207template <
typename RealType>
208template <std::uniform_random_bit_generator G>
211 return std::exp(X(g));
214template <
typename RealType>
215template <std::uniform_random_bit_generator G>
221template <
typename RealType>
224 return expMu * expHalfSigmaSq;
227template <
typename RealType>
230 double y = expMu * expHalfSigmaSq;
231 return y * y * std::expm1l(X.Variance());
234template <
typename RealType>
237 return std::exp(X.Quantile(p));
240template <
typename RealType>
241RealType LogNormalRand<RealType>::quantileImpl1m(
double p)
const
243 return std::exp(X.Quantile1m(p));
246template <
typename RealType>
247std::complex<double> LogNormalRand<RealType>::CFImpl(
double t)
const
253 static constexpr double NORMAL_RANGE = 10;
254 const double sigma = X.GetScale(), sigmaSq = sigma * sigma;
255 const std::complex<double> w =
math::W0Lambert(std::complex<double>(0, -t * sigmaSq * expMu));
256 const std::complex<double> scaled = w / sigmaSq;
257 auto integrand = [sigma, scaled](
double u) {
258 const double v = sigma * u;
261 if (std::fabs(v) < 0.5) {
263 for (
int k = 2; k < 30 && std::fabs(term) > std::numeric_limits<double>::epsilon() * std::fabs(excess);
269 excess = std::expm1(v) - v;
271 return std::exp(-0.5 * u * u - scaled * excess);
274 math::integrate([&integrand](
double u) {
return integrand(u).real(); }, -NORMAL_RANGE, NORMAL_RANGE);
276 math::integrate([&integrand](
double u) {
return integrand(u).imag(); }, -NORMAL_RANGE, NORMAL_RANGE);
277 const std::complex<double> expectation =
279 const std::complex<double> value = std::exp(-(w * w + 2.0 * w) / (2 * sigmaSq)) * expectation;
280 if (std::isfinite(value.real()) && std::isfinite(value.imag()))
282 return this->integrateCharacteristicFunction(t);
285template <
typename RealType>
291template <
typename RealType>
294 return expMu / (expHalfSigmaSq * expHalfSigmaSq);
297template <
typename RealType>
300 double y = std::expm1l(X.Variance());
301 return (expHalfSigmaSq * expHalfSigmaSq + 2) * std::sqrt(y);
304template <
typename RealType>
307 double temp = expHalfSigmaSq * expHalfSigmaSq;
308 double c = temp * temp;
311 return a + 2 * b + 3 * c - 6;
314template <
typename RealType>
318 if (!this->allElementsArePositive(sample))
320 this->SetLocation(this->GetSampleLogMean(sample));
323template <
typename RealType>
327 if (!this->allElementsArePositive(sample))
329 double mu = X.GetLocation();
330 this->SetScale(std::sqrt(this->GetSampleLogVariance(sample, mu)));
333template <
typename RealType>
337 if (!this->allElementsArePositive(sample))
339 size_t n = sample.size();
340 long double logMean = 0.0L;
341 long double logSqDev = 0.0L;
342 for (
double var : sample) {
343 double logVar = std::log(var);
345 logSqDev += logVar * logVar;
349 logSqDev -= logMean * logMean;
351 SetLocation(logMean);
352 SetScale(std::sqrt(logSqDev));
355template <
typename RealType>
360 if (!this->allElementsArePositive(sample))
362 size_t n = sample.size();
365 double tau = X.GetPrecision();
366 double numerator = n * this->GetSampleLogMean(sample) * tau + tau0 * mu0;
367 double denominator = n * tau + tau0;
369 SetLocation(MAP ? posteriorDistribution.
Mode() : posteriorDistribution.
Mean());
370 return posteriorDistribution;
373template <
typename RealType>
379 if (!this->allElementsArePositive(sample))
381 size_t n = sample.size();
382 double alpha = priorDistribution.
GetShape();
383 double beta = priorDistribution.
GetRate();
384 double newAlpha = alpha + 0.5 * n;
385 double mu = X.GetLocation();
386 double newBeta = beta + 0.5 * n * this->GetSampleLogVariance(sample, mu);
388 SetScale(std::sqrt(MAP ? posteriorDistribution.
Mode() : posteriorDistribution.
Mean()));
389 return posteriorDistribution;
392template <
typename RealType>
398 if (!this->allElementsArePositive(sample))
400 size_t n = sample.size();
401 double alpha = priorDistribution.
GetShape();
402 double beta = priorDistribution.
GetRate();
405 DoublePair logStats = this->GetSampleLogMeanAndVariance(sample);
406 double average = logStats.first, sum = n * average;
407 double newLambda = lambda + n;
408 double newMu0 = (lambda * mu0 + sum) / newLambda;
409 double newAlpha = alpha + 0.5 * n;
410 double variance = logStats.second;
411 double aux = mu0 - average;
412 double newBeta = beta + 0.5 * n * (variance + lambda / newLambda * aux * aux);
415 :
static_cast<DoublePair>(posteriorDistribution.Mean());
416 SetLocation(newParams.first);
417 SetScale(std::sqrt(newParams.second));
418 return posteriorDistribution;
The ContinuousDistribution class Abstract class for all continuous distributions.
Definition continuous.hpp:22
The InverseGammaRand class Inverse-Gamma distribution.
Definition inverse_gamma.hpp:23
double GetRate() const noexcept
Definition inverse_gamma.hpp:49
double GetShape() const noexcept
Definition inverse_gamma.hpp:48
long double Mean() const override
Definition inverse_gamma.hpp:146
RealType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition inverse_gamma.hpp:168
The LogNormalRand class Log-Normal distribution.
Definition log_normal.hpp:25
InverseGammaRand< RealType > FitScaleBayes(std::span< const RealType > sample, const InverseGammaRand< RealType > &priorDistribution, bool MAP=false)
Set scale, using bayesian inference.
Definition log_normal.hpp:374
static LogNormalRand FromLogMeanLogStd(double logMean, double logStandardDeviation)
Definition log_normal.hpp:40
long double ExcessKurtosis() const override
Definition log_normal.hpp:305
RealType MaxValue() const override
Definition log_normal.hpp:60
double F(const RealType &x) const override
Definition log_normal.hpp:196
void FitLocation(std::span< const RealType > sample)
Fit location via maximum-likelihood.
Definition log_normal.hpp:315
static LogNormalRand FromLogMeanLogVariance(double logMean, double logVariance)
Definition log_normal.hpp:52
void FitScale(std::span< const RealType > sample)
Fit scale via maximum-likelihood.
Definition log_normal.hpp:324
LogNormalRand(double location=0, double squaredScale=1)
Definition log_normal.hpp:146
NormalInverseGammaRand< RealType > FitBayes(std::span< const RealType > sample, const NormalInverseGammaRand< RealType > &priorDistribution, bool MAP=false)
Set parameters, using bayesian inference.
Definition log_normal.hpp:394
long double Variance() const override
Definition log_normal.hpp:228
long double Mean() const override
Definition log_normal.hpp:222
double logf(const RealType &x) const override
Definition log_normal.hpp:186
void Fit(std::span< const RealType > sample)
Fit parameters via maximum-likelihood.
Definition log_normal.hpp:334
void SetLocation(double location)
Definition log_normal.hpp:162
double f(const RealType &x) const override
Definition log_normal.hpp:180
double S(const RealType &x) const override
Definition log_normal.hpp:202
double GetScale() const
Definition log_normal.hpp:65
NormalRand< RealType > FitLocationBayes(std::span< const RealType > sample, const NormalRand< RealType > &priorDistribution, bool MAP=false)
Set location, using bayesian inference.
Definition log_normal.hpp:356
RealType Median() const override
Definition log_normal.hpp:286
void SetScale(double scale)
Definition log_normal.hpp:171
RealType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition log_normal.hpp:292
RealType operator()(G &g) const
Definition log_normal.hpp:209
Support SupportType() const override
Definition log_normal.hpp:58
RealType MinValue() const override
Definition log_normal.hpp:59
double GetLocation() const
Definition log_normal.hpp:64
static RealType StandardVariate(G &g)
Definition log_normal.hpp:216
long double Skewness() const override
Definition log_normal.hpp:298
std::string Name() const override
Definition log_normal.hpp:155
The NormalInverseGammaRand class Normal-inverse-gamma distribution.
Definition normal_inverse_gamma.hpp:24
double GetLocation() const noexcept
Definition normal_inverse_gamma.hpp:38
double GetPrecision() const noexcept
Definition normal_inverse_gamma.hpp:39
double GetShape() const noexcept
Definition normal_inverse_gamma.hpp:40
double GetRate() const noexcept
Definition normal_inverse_gamma.hpp:41
The NormalRand class Normal distribution.
Definition normal.hpp:31
double GetPrecision() const
Definition normal.hpp:78
virtual void sample(detail::EngineRef g, std::span< T > outputData) const
Fills the output with variate(g); distributions with a faster bulk algorithm override it.
Definition distribution.hpp:66
RealType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition stable.hpp:1806
double GetLocation() const noexcept
Definition stable.hpp:168
long double Mean() const override
Definition stable.hpp:1790
The EngineRef class Non-owning, type-erased reference to any uniform random bit generator.
Definition engine/uniform.hpp:116
#define RANDLIB_DEPRECATED_FIT_MEMBER
Definition fwd.hpp:9
constexpr long double sqrt2pi
Definition constants.hpp:32
Real standardNormal(G &g)
Ziggurat algorithm of Marsaglia and Tsang with 256 layers and an explicit sign bit.
Definition variates.hpp:45
Real W0Lambert(Real x, std::type_identity_t< Real > epsilon=Real{1e-11})
Definition functions.hpp:689
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
@ WrongSample
the sample could not have been drawn from this distribution
Support
Shape of the support of a univariate distribution.
Definition univariate.hpp:15
Pair< double > DoublePair
Definition fwd.hpp:39