21template <
typename RealType>
35 [[nodiscard]] std::string
Name()
const override;
37 void SetParameters(
double location,
double precision,
double shape,
double rate);
38 [[nodiscard]]
inline double GetLocation() const noexcept {
return mu; }
39 [[nodiscard]]
inline double GetPrecision() const noexcept {
return lambda; }
40 [[nodiscard]]
inline double GetShape() const noexcept {
return alpha; }
41 [[nodiscard]]
inline double GetRate() const noexcept {
return beta; }
46 template <std::uniform_random_bit_generator G>
61template <
typename RealType>
64 SetParameters(location, precision, shape, rate);
67template <
typename RealType>
70 return "Normal-Inverse-Gamma(" + this->toStringWithPrecision(GetLocation()) +
", " +
71 this->toStringWithPrecision(GetPrecision()) +
", " + this->toStringWithPrecision(GetShape()) +
", " +
72 this->toStringWithPrecision(GetRate()) +
")";
75template <
typename RealType>
78 if (!std::isfinite(location))
79 throw std::invalid_argument(
"Normal-Inverse-Gamma distribution: location should be finite");
80 if (!(precision > 0.0))
81 throw std::invalid_argument(
82 "Precision of Normal-Inverse-Gamma distribution should be positive, but it's equal to " +
83 std::to_string(precision));
85 throw std::invalid_argument(
86 "Shape of Normal-Inverse-Gamma distribution should be positive, but it's equal to " +
87 std::to_string(shape));
89 throw std::invalid_argument(
"Rate of Normal-Inverse-Gamma distribution should be positive, but it's equal to " +
90 std::to_string(rate));
95 this->Y.SetParameters(shape, rate);
96 alpha = this->Y.GetShape();
97 beta = this->Y.GetRate();
98 this->X.SetDegree(2 * alpha);
99 this->X.SetLocation(mu);
100 this->X.SetScale(std::sqrt(beta / (alpha * lambda)));
103 pdfCoef += alpha * this->Y.GetLogRate() - this->Y.GetLogGammaShape();
106template <
typename RealType>
109 return (point.second > 0.0) ? std::exp(logf(point)) : 0.0;
112template <
typename RealType>
115 RealType sigmaSq = point.second;
118 RealType x = point.first;
119 RealType y = (alpha + 1.5) * std::log(sigmaSq);
120 RealType degree = x - mu;
124 degree *= 0.5 / sigmaSq;
129template <
typename RealType>
132 RealType sigmaSq = point.second;
135 RealType x = point.first;
138 double marginalY = this->Y.F(sigmaSq);
141 if (sigmaSq == INFINITY)
144 return 0.5 * marginalY;
146 double lower = beta / sigmaSq;
147 double normalCoef = (x - mu) * std::sqrt(lambda / beta);
148 double logGammaAlpha = this->Y.GetLogGammaShape();
149 double shape = alpha;
151 [lower, normalCoef, logGammaAlpha, shape](
double t) {
152 double oneMinusT = 1.0 - t;
153 double u = lower + t / oneMinusT;
154 double logWeight = (shape - 1.0) * std::log(u) - u - logGammaAlpha;
155 logWeight -= 2.0 * std::log(oneMinusT);
156 double conditional = 0.5 * std::erfc(-normalCoef * std::sqrt(0.5 * u));
157 return std::exp(logWeight) * conditional;
160 return std::clamp(joint, 0.0, std::min(this->X.F(x), marginalY));
163template <
typename RealType>
164template <std::uniform_random_bit_generator G>
168 var.second = this->Y(g);
169 double coef = std::sqrt(var.second / lambda);
174template <
typename RealType>
177 return (alpha > 2.0) ? 0.0 : NAN;
180template <
typename RealType>
183 return std::make_pair(mu, 2 * beta / (2 * alpha + 3));
The ContinuousBivariateDistribution class Abstract class for all bivariate probability distribution...
Definition continuous_bivariate.hpp:18
The NormalInverseGammaRand class Normal-inverse-gamma distribution.
Definition normal_inverse_gamma.hpp:24
long double Correlation() const override
Definition normal_inverse_gamma.hpp:175
double f(const Pair< RealType > &point) const override
Definition normal_inverse_gamma.hpp:107
double logf(const Pair< RealType > &point) const override
Definition normal_inverse_gamma.hpp:113
void SetParameters(double location, double precision, double shape, double rate)
Definition normal_inverse_gamma.hpp:76
NormalInverseGammaRand(double location=0, double precision=1, double shape=1, double rate=1)
Definition normal_inverse_gamma.hpp:62
std::string Name() const override
Definition normal_inverse_gamma.hpp:68
Pair< RealType > Mode() const override
Definition normal_inverse_gamma.hpp:181
double GetLocation() const noexcept
Definition normal_inverse_gamma.hpp:38
double GetPrecision() const noexcept
Definition normal_inverse_gamma.hpp:39
Pair< RealType > operator()(G &g) const
Definition normal_inverse_gamma.hpp:165
double GetShape() const noexcept
Definition normal_inverse_gamma.hpp:40
double GetRate() const noexcept
Definition normal_inverse_gamma.hpp:41
double F(const Pair< RealType > &point) const override
Definition normal_inverse_gamma.hpp:130
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 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 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
std::pair< T, T > Pair
Definition fwd.hpp:33