2
0
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:
jzmaddock
2020-07-24 20:11:48 +01:00
parent 8792935679
commit fa8f763df9
2 changed files with 29 additions and 1 deletions

View File

@@ -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);
//

View File

@@ -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.