Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85075 - in trunk: boost/math/bindings boost/math/distributions boost/math/special_functions/detail libs/math/test
From: john_at_[hidden]
Date: 2013-07-18 13:31:42


Author: johnmaddock
Date: 2013-07-18 13:31:42 EDT (Thu, 18 Jul 2013)
New Revision: 85075
URL: http://svn.boost.org/trac/boost/changeset/85075

Log:
Don't throw exceptions from itrunc/iround if all we're doing is checking to see if the argument is an integer.
Don't propagate no-throw policies inside MPFR's itrunc/iround.
Use normal approximation to student's t quantile when the degrees of freedom is big enough.
Fixes #8837.

Text files modified:
   trunk/boost/math/bindings/mpfr.hpp | 24 ++++++++++++------------
   trunk/boost/math/distributions/hypergeometric.hpp | 6 +++---
   trunk/boost/math/special_functions/detail/t_distribution_inv.hpp | 10 ++++++++--
   trunk/libs/math/test/test_students_t.cpp | 29 +++++++++++++++++++++++++++++
   4 files changed, 52 insertions(+), 17 deletions(-)

Modified: trunk/boost/math/bindings/mpfr.hpp
==============================================================================
--- trunk/boost/math/bindings/mpfr.hpp Thu Jul 18 13:09:02 2013 (r85074)
+++ trunk/boost/math/bindings/mpfr.hpp 2013-07-18 13:31:42 EDT (Thu, 18 Jul 2013) (r85075)
@@ -115,9 +115,9 @@
 }
 
 template <class Policy>
-inline int iround(mpfr_class const& x, const Policy& pol)
+inline int iround(mpfr_class const& x, const Policy&)
 {
- return boost::math::tools::real_cast<int>(boost::math::round(x, pol));
+ return boost::math::tools::real_cast<int>(boost::math::round(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
 }
 template <class T, class U, class Policy>
 inline int iround(__gmp_expr<T,U> const& x, const Policy& pol)
@@ -126,9 +126,9 @@
 }
 
 template <class Policy>
-inline long lround(mpfr_class const& x, const Policy& pol)
+inline long lround(mpfr_class const& x, const Policy&)
 {
- return boost::math::tools::real_cast<long>(boost::math::round(x, pol));
+ return boost::math::tools::real_cast<long>(boost::math::round(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
 }
 template <class T, class U, class Policy>
 inline long lround(__gmp_expr<T,U> const& x, const Policy& pol)
@@ -137,9 +137,9 @@
 }
 
 template <class Policy>
-inline long long llround(mpfr_class const& x, const Policy& pol)
+inline long long llround(mpfr_class const& x, const Policy&)
 {
- return boost::math::tools::real_cast<long long>(boost::math::round(x, pol));
+ return boost::math::tools::real_cast<long long>(boost::math::round(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
 }
 template <class T, class U, class Policy>
 inline long long llround(__gmp_expr<T,U> const& x, const Policy& pol)
@@ -148,9 +148,9 @@
 }
 
 template <class Policy>
-inline int itrunc(mpfr_class const& x, const Policy& pol)
+inline int itrunc(mpfr_class const& x, const Policy&)
 {
- return boost::math::tools::real_cast<int>(boost::math::trunc(x, pol));
+ return boost::math::tools::real_cast<int>(boost::math::trunc(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
 }
 template <class T, class U, class Policy>
 inline int itrunc(__gmp_expr<T,U> const& x, const Policy& pol)
@@ -159,9 +159,9 @@
 }
 
 template <class Policy>
-inline long ltrunc(mpfr_class const& x, const Policy& pol)
+inline long ltrunc(mpfr_class const& x, const Policy&)
 {
- return boost::math::tools::real_cast<long>(boost::math::trunc(x, pol));
+ return boost::math::tools::real_cast<long>(boost::math::trunc(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
 }
 template <class T, class U, class Policy>
 inline long ltrunc(__gmp_expr<T,U> const& x, const Policy& pol)
@@ -170,9 +170,9 @@
 }
 
 template <class Policy>
-inline long long lltrunc(mpfr_class const& x, const Policy& pol)
+inline long long lltrunc(mpfr_class const& x, const Policy&)
 {
- return boost::math::tools::real_cast<long long>(boost::math::trunc(x, pol));
+ return boost::math::tools::real_cast<long long>(boost::math::trunc(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
 }
 template <class T, class U, class Policy>
 inline long long lltrunc(__gmp_expr<T,U> const& x, const Policy& pol)

Modified: trunk/boost/math/distributions/hypergeometric.hpp
==============================================================================
--- trunk/boost/math/distributions/hypergeometric.hpp Thu Jul 18 13:09:02 2013 (r85074)
+++ trunk/boost/math/distributions/hypergeometric.hpp 2013-07-18 13:31:42 EDT (Thu, 18 Jul 2013) (r85075)
@@ -136,7 +136,7 @@
       BOOST_MATH_STD_USING
       static const char* function = "boost::math::pdf(const hypergeometric_distribution<%1%>&, const %1%&)";
       RealType r = static_cast<RealType>(x);
- unsigned u = itrunc(r);
+ unsigned u = itrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
       if(u != r)
       {
          return boost::math::policies::raise_domain_error<RealType>(
@@ -165,7 +165,7 @@
       BOOST_MATH_STD_USING
       static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
       RealType r = static_cast<RealType>(x);
- unsigned u = itrunc(r);
+ unsigned u = itrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
       if(u != r)
       {
          return boost::math::policies::raise_domain_error<RealType>(
@@ -194,7 +194,7 @@
       BOOST_MATH_STD_USING
       static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)";
       RealType r = static_cast<RealType>(c.param);
- unsigned u = itrunc(r);
+ unsigned u = itrunc(r, typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type());
       if(u != r)
       {
          return boost::math::policies::raise_domain_error<RealType>(

Modified: trunk/boost/math/special_functions/detail/t_distribution_inv.hpp
==============================================================================
--- trunk/boost/math/special_functions/detail/t_distribution_inv.hpp Thu Jul 18 13:09:02 2013 (r85074)
+++ trunk/boost/math/special_functions/detail/t_distribution_inv.hpp 2013-07-18 13:31:42 EDT (Thu, 18 Jul 2013) (r85075)
@@ -372,7 +372,13 @@
    else
    {
 calculate_real:
- if(df < 3)
+ if(df > 0x10000000)
+ {
+ result = -boost::math::erfc_inv(2 * u, pol) * constants::root_two<T>();
+ if((pexact) && (df >= 1e20))
+ *pexact = true;
+ }
+ else if(df < 3)
       {
          //
          // Use a roughly linear scheme to choose between Shaw's
@@ -395,7 +401,7 @@
          // where we use Shaw's tail series.
          // The crossover point is roughly exponential in -df:
          //
- T crossover = ldexp(1.0f, iround(T(df / -0.654f), pol));
+ T crossover = ldexp(1.0f, iround(T(df / -0.654f), typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type()));
          if(u > crossover)
          {
             result = boost::math::detail::inverse_students_t_hill(df, u, pol);

Modified: trunk/libs/math/test/test_students_t.cpp
==============================================================================
--- trunk/libs/math/test/test_students_t.cpp Thu Jul 18 13:09:02 2013 (r85074)
+++ trunk/libs/math/test/test_students_t.cpp 2013-07-18 13:31:42 EDT (Thu, 18 Jul 2013) (r85075)
@@ -354,6 +354,35 @@
          static_cast<RealType>(1.42262528146180931868169289781115099L), // t.
          tolerance);
 
+ if(boost::is_floating_point<RealType>::value)
+ {
+ BOOST_CHECK_CLOSE(boost::math::cdf(
+ students_t_distribution<RealType>(1e30f),
+ boost::math::quantile(
+ students_t_distribution<RealType>(1e30f), static_cast<RealType>(0.25f))),
+ static_cast<RealType>(0.25f), tolerance);
+ BOOST_CHECK_CLOSE(boost::math::cdf(
+ students_t_distribution<RealType>(1e20f),
+ boost::math::quantile(
+ students_t_distribution<RealType>(1e20f), static_cast<RealType>(0.25f))),
+ static_cast<RealType>(0.25f), tolerance);
+ BOOST_CHECK_CLOSE(boost::math::cdf(
+ students_t_distribution<RealType>(0x7FFFFFFF),
+ boost::math::quantile(
+ students_t_distribution<RealType>(0x7FFFFFFF), static_cast<RealType>(0.25f))),
+ static_cast<RealType>(0.25f), tolerance);
+ BOOST_CHECK_CLOSE(boost::math::cdf(
+ students_t_distribution<RealType>(0x10000000),
+ boost::math::quantile(
+ students_t_distribution<RealType>(0x10000000), static_cast<RealType>(0.25f))),
+ static_cast<RealType>(0.25f), tolerance);
+ BOOST_CHECK_CLOSE(boost::math::cdf(
+ students_t_distribution<RealType>(0x0fffffff),
+ boost::math::quantile(
+ students_t_distribution<RealType>(0x0fffffff), static_cast<RealType>(0.25f))),
+ static_cast<RealType>(0.25f), tolerance);
+ }
+
   // Student's t pdf tests.
   // for PDF checks, use 100 eps tolerance expressed as a percent:
    tolerance = boost::math::tools::epsilon<RealType>() * 10000;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk