Skip to content

Commit

Permalink
Merge pull request #713 from boostorg/issue710
Browse files Browse the repository at this point in the history
Update limits used in erf/erfc approximations.
  • Loading branch information
jzmaddock committed Nov 2, 2021
2 parents 923ed19 + 08ff95d commit afaa03a
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
4 changes: 2 additions & 2 deletions include/boost/math/special_functions/erf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ T erf_imp(T z, bool invert, const Policy& pol, const std::integral_constant<int,
result = z * (Y + tools::evaluate_polynomial(P, zz) / tools::evaluate_polynomial(Q, zz));
}
}
else if(invert ? (z < 28) : (z < 5.8f))
else if(invert ? (z < 28) : (z < 5.93f))
{
//
// We'll be calculating erfc:
Expand Down Expand Up @@ -483,7 +483,7 @@ T erf_imp(T z, bool invert, const Policy& pol, const std::integral_constant<int,
result = z * (Y + tools::evaluate_polynomial(P, T(z * z)) / tools::evaluate_polynomial(Q, T(z * z)));
}
}
else if(invert ? (z < 110) : (z < 6.4f))
else if(invert ? (z < 110) : (z < 6.6f))
{
//
// We'll be calculating erfc:
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ test-suite special_fun :
[ run test_jacobi_zeta.cpp test_instances//test_instances pch_light ../../test/build//boost_unit_test_framework ]
[ run test_heuman_lambda.cpp test_instances//test_instances pch_light ../../test/build//boost_unit_test_framework ]
[ run test_erf.cpp test_instances//test_instances pch_light ../../test/build//boost_unit_test_framework ]
[ run erf_limits_test.cpp ]
[ run test_expint.cpp test_instances//test_instances pch_light ../../test/build//boost_unit_test_framework ]
[ run test_factorials.cpp pch ../../test/build//boost_unit_test_framework ]
[ run test_gamma.cpp test_instances//test_instances pch_light ../../test/build//boost_unit_test_framework ]
Expand Down
73 changes: 73 additions & 0 deletions test/erf_limits_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// (C) Copyright John Maddock 2021.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//
// This test verifies that the limits we use in the numerical approximations to erf/erc
// are indeed correct. The values tested must of course match the values used in erf.hpp.
// See https://github.com/boostorg/math/issues/710
//

#define BOOST_TEST_MODULE erf_limits

#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/math/special_functions/erf.hpp>
#include <boost/test/included/unit_test.hpp>

#include <cfloat>

BOOST_AUTO_TEST_CASE(limits_53_digits)
{
double arg = 5.93f;

double t = (double)boost::math::erf(boost::multiprecision::cpp_bin_float_50(arg));
BOOST_CHECK_EQUAL(t, 1.0);

arg = 5.9;
BOOST_CHECK_LT(boost::math::erf(arg), 1.0);

arg = 28;
t = (double)boost::math::erfc(boost::multiprecision::cpp_bin_float_50(arg));
BOOST_CHECK_EQUAL(t, 0.0);

arg = 27.2;

BOOST_CHECK_GT(boost::math::erfc(arg), 0.0);
}

BOOST_AUTO_TEST_CASE(limits_64_digits)
{
float arg = 6.6f;

boost::multiprecision::cpp_bin_float_double_extended t = (boost::multiprecision::cpp_bin_float_double_extended)boost::math::erf(boost::multiprecision::cpp_bin_float_50(arg));
BOOST_CHECK_EQUAL(t, 1.0);

#if (LDBL_MANT_DIG == 64) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
arg = 6.5;
BOOST_CHECK_LT(boost::math::erf(static_cast<long double>(arg)), 1.0L);
#endif
arg = 110;
t = (boost::multiprecision::cpp_bin_float_double_extended)boost::math::erfc(boost::multiprecision::cpp_bin_float_50(arg));
BOOST_CHECK_EQUAL(t, 0.0);

#if (LDBL_MANT_DIG == 64) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
arg = 106.5;
BOOST_CHECK_GT(boost::math::erfc(static_cast<long double>(arg)), 0.0L);
#endif
}

BOOST_AUTO_TEST_CASE(limits_113_digits)
{
//
// This limit is not actually used in the code, logged here for future reference...
//
float arg = 8.8f;

boost::multiprecision::cpp_bin_float_quad t = (boost::multiprecision::cpp_bin_float_quad)boost::math::erf(boost::multiprecision::cpp_bin_float_50(arg));
BOOST_CHECK_EQUAL(t, 1.0);

arg = 110;
t = (boost::multiprecision::cpp_bin_float_quad)boost::math::erfc(boost::multiprecision::cpp_bin_float_50(arg));
BOOST_CHECK_EQUAL(t, 0.0);
}

0 comments on commit afaa03a

Please sign in to comment.