mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
Fix bug in student's T quantile for denormalized degrees_of_freedom.
This commit is contained in:
@@ -673,7 +673,28 @@ T ibeta_inv_imp(T a, T b, T p, T q, const Policy& pol, T* py)
|
||||
invert = !invert;
|
||||
xs = 1 - xs;
|
||||
}
|
||||
T xg = pow(a * p * boost::math::beta(a, b, pol), 1/a);
|
||||
if (a < tools::min_value<T>())
|
||||
return invert ? 1 : 0; // nothing interesting going on here.
|
||||
//
|
||||
// The call to beta may overflow, plus the alternative using lgamma may do the same
|
||||
// if T is a type where 1/T is infinite for small values (denorms for example).
|
||||
//
|
||||
T bet = 0;
|
||||
T xg;
|
||||
bool overflow = false;
|
||||
try {
|
||||
bet = boost::math::beta(a, b, pol);
|
||||
}
|
||||
catch (const std::runtime_error&)
|
||||
{
|
||||
overflow = true;
|
||||
}
|
||||
if (overflow || !(boost::math::isfinite)(bet))
|
||||
{
|
||||
xg = exp((boost::math::lgamma(a + 1, pol) + boost::math::lgamma(b + 1) - boost::math::lgamma(a + b + 1) + log(p) - log(b) + log(a + b)) / a);
|
||||
}
|
||||
else
|
||||
xg = pow(a * p * bet, 1/a);
|
||||
x = xg / (1 + xg);
|
||||
y = 1 / (1 + xg);
|
||||
//
|
||||
|
||||
@@ -381,6 +381,13 @@ void test_spots(RealType)
|
||||
boost::math::quantile(
|
||||
students_t_distribution<RealType>(static_cast<RealType>(0x0fffffff)), static_cast<RealType>(0.25f))),
|
||||
static_cast<RealType>(0.25f), tolerance);
|
||||
//
|
||||
// Bug cases:
|
||||
//
|
||||
if (std::numeric_limits<RealType>::is_specialized && std::numeric_limits<RealType>::has_denorm)
|
||||
{
|
||||
BOOST_CHECK_THROW(boost::math::quantile(students_t_distribution<RealType>((std::numeric_limits<RealType>::min)() / 2), static_cast<RealType>(0.0025f)), std::overflow_error);
|
||||
}
|
||||
}
|
||||
|
||||
// Student's t pdf tests.
|
||||
|
||||
Reference in New Issue
Block a user