20template <
typename RealType>
36 explicit StudentTRand(
double degree = 1.0,
double location = 0.0,
double scale = 1.0);
38 [[nodiscard]] std::string
Name()
const override;
40 [[nodiscard]] RealType
MinValue()
const override {
return -INFINITY; }
41 [[nodiscard]] RealType
MaxValue()
const override {
return INFINITY; }
46 [[nodiscard]]
inline double GetDegree() const noexcept {
return nu; }
47 [[nodiscard]]
inline double GetLocation() const noexcept {
return mu; }
48 [[nodiscard]]
inline double GetScale() const noexcept {
return sigma; }
50 [[nodiscard]]
double f(
const RealType &x)
const override;
51 [[nodiscard]]
double logf(
const RealType &x)
const override;
54 double log1pSquareOverDegree(
double x0)
const;
55 double lowerTail(
double x0)
const;
58 [[nodiscard]]
double F(
const RealType &x)
const override;
59 [[nodiscard]]
double S(
const RealType &x)
const override;
60 template <std::uniform_random_bit_generator G>
63 [[nodiscard]]
long double Mean()
const override;
64 [[nodiscard]]
long double Variance()
const override;
65 [[nodiscard]] RealType
Median()
const override;
66 [[nodiscard]] RealType
Mode()
const override;
67 [[nodiscard]]
long double Skewness()
const override;
71 RealType quantileImpl(
double p)
const override;
72 RealType quantileImpl1m(
double p)
const override;
73 std::complex<double> CFImpl(
double t)
const override;
84template <
typename RealType>
88 SetLocation(location);
92template <
typename RealType>
95 if (mu == 0.0 && sigma == 1.0)
96 return "Student-t(" + this->toStringWithPrecision(GetDegree()) +
")";
97 return "Student-t(" + this->toStringWithPrecision(GetDegree()) +
", " + this->toStringWithPrecision(GetLocation()) +
98 ", " + this->toStringWithPrecision(GetScale()) +
")";
101template <
typename RealType>
105 throw std::invalid_argument(
"Student-t distribution: degree parameter should be positive");
107 Y.SetParameters(0.5 * nu, 1.0);
109 nup1Half = 0.5 * (nu + 1);
110 pdfCoef = Y.GetLogGammaShapeRatio();
112 logBetaFun = -pdfCoef;
113 pdfCoef -= 0.5 * std::log(nu);
116template <
typename RealType>
119 if (!std::isfinite(location))
120 throw std::invalid_argument(
"Student-t distribution: location should be finite");
124template <
typename RealType>
128 throw std::invalid_argument(
"Student-t distribution: scale should be positive");
130 logSigma = std::log(sigma);
133template <
typename RealType>
139 double xSq = x0 * x0;
143 double tmp = 2.0 + xSq;
144 return 1.0 / (sigma * tmp * std::sqrt(tmp));
150 return std::exp(logf(x));
153template <
typename RealType>
157 double absX = std::fabs(x0);
159 return std::log1pl(x0 * x0 / nu);
160 double logRatio = 2 * std::log(absX) - std::log(nu);
161 return logRatio + std::log1pl(std::exp(-logRatio));
164template <
typename RealType>
170 double log1pXsqNu = log1pSquareOverDegree(x0);
180 double y = -nup1Half * log1pXsqNu;
181 return pdfCoef + y - logSigma;
184template <
typename RealType>
190 ((x0 < -1.0) ? std::atan(-1.0 / x0) :
randlib::consts::half_pi + std::atan(x0));
193 double xSq = x0 * x0, u = xSq / (nu + xSq);
194 return 0.5 - 0.5 *
math::ibeta(u, 0.5, 0.5 * nu, logBetaFun, std::log(xSq) - std::log(nu + xSq),
195 std::log(nu) - std::log(nu + xSq));
197 double logT = -log1pSquareOverDegree(x0);
198 double t = std::exp(logT);
201 return 0.5 * std::exp(0.5 * nu * logT - std::log(0.5 * nu) - logBetaFun);
203 double log1mT = std::log1pl(-t);
204 return 0.5 *
math::ibeta(t, 0.5 * nu, 0.5, logBetaFun, logT, log1mT);
207template <
typename RealType>
210 double x0 = (x - mu) / sigma;
213 return (x0 < 0.0) ? lowerTail(x0) : 1.0 - lowerTail(-x0);
216template <
typename RealType>
219 double x0 = (x - mu) / sigma;
222 return (x0 > 0.0) ? lowerTail(-x0) : 1.0 - lowerTail(x0);
225template <
typename RealType>
226template <std::uniform_random_bit_generator G>
234template <
typename RealType>
238 for (RealType &var : outputData)
239 var = mu + sigma *
CauchyRand<RealType>::StandardVariate(g);
242 for (RealType &var : outputData)
243 var = mu + sigma * detail::standardNormal<RealType>(g) / var;
247template <
typename RealType>
250 return (nu > 1) ? mu : NAN;
253template <
typename RealType>
257 return sigma * sigma * nu / (nu - 2);
258 return (nu > 1) ? INFINITY : NAN;
261template <
typename RealType>
264 double x = std::sqrt(nu) * t * sigma;
265 double vHalf = 0.5 * nu;
266 double y = vHalf * std::log(x);
267 y -= Y.GetLogGammaFunction();
270 double costmu = std::cos(t * mu), sintmu = std::sin(t * mu);
271 std::complex<double> cf(costmu, sintmu);
272 return std::exp(y) * cf;
275template <
typename RealType>
276RealType StudentTRand<RealType>::quantileImpl(
double p)
const
278 double temp = p - 0.5;
281 double pq = p * (1.0 - p);
283 return sigma * 2.0 * temp * std::sqrt(0.5 / pq) + mu;
285 double alpha = 2 * std::sqrt(pq);
286 double beta = std::cos(std::acos(alpha) / 3.0) / alpha - 1;
287 return mu + sigma * 2 *
math::sign(temp) * std::sqrt(beta);
292template <
typename RealType>
293RealType StudentTRand<RealType>::quantileImpl1m(
double p)
const
295 double temp = 0.5 - p;
298 double pq = p * (1.0 - p);
300 return sigma * 2 * temp * std::sqrt(0.5 / pq) + mu;
302 double alpha = 2 * std::sqrt(pq);
303 double beta = std::cos(std::acos(alpha) / 3.0) / alpha - 1;
304 return mu + sigma * 2 *
math::sign(temp) * std::sqrt(beta);
309template <
typename RealType>
315template <
typename RealType>
321template <
typename RealType>
324 return (nu > 3) ? 0.0 : NAN;
327template <
typename RealType>
331 return 6.0 / (nu - 4);
332 return (nu > 2) ? INFINITY : NAN;
The CauchyRand class Cauchy distribution.
Definition cauchy.hpp:26
static RealType StandardVariate(G &g)
Definition cauchy.hpp:101
The ContinuousDistribution class Abstract class for all continuous distributions.
Definition continuous.hpp:22
RealType quantileImpl(double p, RealType initValue) const override
Definition continuous.hpp:140
RealType quantileImpl1m(double p, RealType initValue) const override
Definition continuous.hpp:152
The NakagamiRand class Nakagami distribution.
Definition nakagami.hpp:96
void Sample(std::span< T > outputData) const
Fills the output with variates drawn with the engine of this object.
Definition distribution.hpp:139
The StudentTRand class Student's t-distribution.
Definition student_t.hpp:22
double GetLocation() const noexcept
Definition student_t.hpp:47
long double Variance() const override
Definition student_t.hpp:254
long double ExcessKurtosis() const override
Definition student_t.hpp:328
StudentTRand(double degree=1.0, double location=0.0, double scale=1.0)
Definition student_t.hpp:85
RealType MaxValue() const override
Definition student_t.hpp:41
double f(const RealType &x) const override
Definition student_t.hpp:134
std::string Name() const override
Definition student_t.hpp:93
long double Skewness() const override
Definition student_t.hpp:322
void SetScale(double scale)
Definition student_t.hpp:125
void SetLocation(double location)
Definition student_t.hpp:117
double S(const RealType &x) const override
Definition student_t.hpp:217
void SetDegree(double degree)
Definition student_t.hpp:102
RealType operator()(G &g) const
Definition student_t.hpp:227
long double Mean() const override
Definition student_t.hpp:248
RealType Mode() const override
Mode is the value, which has the largest probability to happen, or, in the case of continuous distrib...
Definition student_t.hpp:316
double GetScale() const noexcept
Definition student_t.hpp:48
RealType Median() const override
Definition student_t.hpp:310
double F(const RealType &x) const override
Definition student_t.hpp:208
RealType MinValue() const override
Definition student_t.hpp:40
double logf(const RealType &x) const override
Definition student_t.hpp:165
Support SupportType() const override
Definition student_t.hpp:39
double GetDegree() const noexcept
Definition student_t.hpp:46
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 pi
Definition constants.hpp:22
constexpr long double ln3
Definition constants.hpp:19
constexpr long double sqrt3
Definition constants.hpp:29
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
int sign(Real x)
Definition functions.hpp:232
Real ibeta(Real x, std::type_identity_t< Real > a, std::type_identity_t< Real > b, std::type_identity_t< Real > logBetaFun, std::type_identity_t< Real > logX, std::type_identity_t< Real > log1mX)
Fast calculation of regularized beta function, using precalculated values.
Definition math/beta.hpp:250
Real logBesselK(std::type_identity_t< Real > nu, Real x)
Calculates logarithm of modified Bessel function of the 2nd kind.
Definition functions.hpp:637
Definition bivariate_normal.hpp:10
Support
Shape of the support of a univariate distribution.
Definition univariate.hpp:15