|
Boost-Commit : |
From: john_at_[hidden]
Date: 2008-01-23 05:41:08
Author: johnmaddock
Date: 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
New Revision: 42920
URL: http://svn.boost.org/trac/boost/changeset/42920
Log:
Added error handling to the rounding functions.
Added better error handling to the non-central chi squared, and updated the tests.
Added:
sandbox/math_toolkit/libs/math/test/compile_test/dist_nc_chi_squ_incl_test.cpp (contents, props changed)
Text files modified:
sandbox/math_toolkit/boost/math/concepts/real_concept.hpp | 36 +++++++++++-----------
sandbox/math_toolkit/boost/math/concepts/std_real_concept.hpp | 36 +++++++++++-----------
sandbox/math_toolkit/boost/math/distributions/non_central_chi_squared.hpp | 39 ++++++++++++++++++++----
sandbox/math_toolkit/boost/math/distributions/poisson.hpp | 2
sandbox/math_toolkit/boost/math/policies/error_handling.hpp | 64 ++++++++++++++++++++++++++++++++++++++++
sandbox/math_toolkit/boost/math/policies/policy.hpp | 9 +++++
sandbox/math_toolkit/boost/math/special_functions/bessel.hpp | 10 +++---
sandbox/math_toolkit/boost/math/special_functions/beta.hpp | 4 +-
sandbox/math_toolkit/boost/math/special_functions/cos_pi.hpp | 12 +++---
sandbox/math_toolkit/boost/math/special_functions/detail/bessel_ik.hpp | 2
sandbox/math_toolkit/boost/math/special_functions/detail/bessel_jy.hpp | 2
sandbox/math_toolkit/boost/math/special_functions/detail/t_distribution_inv.hpp | 4 +-
sandbox/math_toolkit/boost/math/special_functions/factorials.hpp | 2
sandbox/math_toolkit/boost/math/special_functions/gamma.hpp | 6 +-
sandbox/math_toolkit/boost/math/special_functions/modf.hpp | 36 +++++++++++++++++-----
sandbox/math_toolkit/boost/math/special_functions/round.hpp | 43 +++++++++++++++++++++++---
sandbox/math_toolkit/boost/math/special_functions/sin_pi.hpp | 12 +++---
sandbox/math_toolkit/boost/math/special_functions/trunc.hpp | 43 +++++++++++++++++++++++---
sandbox/math_toolkit/libs/math/test/Jamfile.v2 | 1
sandbox/math_toolkit/libs/math/test/test_nc_chi_squared.cpp | 44 +++++++++++++-------------
sandbox/math_toolkit/libs/math/test/test_round.cpp | 61 ++++++++++++++++++++++++++++++++++++++
21 files changed, 357 insertions(+), 111 deletions(-)
Modified: sandbox/math_toolkit/boost/math/concepts/real_concept.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/concepts/real_concept.hpp (original)
+++ sandbox/math_toolkit/boost/math/concepts/real_concept.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -313,46 +313,46 @@
//
// Conversion and truncation routines:
//
-template <>
-inline int iround<concepts::real_concept>(const concepts::real_concept& v)
+template <class Policy>
+inline int iround(const concepts::real_concept& v, const Policy& pol)
{
- return iround(v.value());
+ return iround(v.value(), pol);
}
-template <>
-inline long lround<concepts::real_concept>(const concepts::real_concept& v)
+template <class Policy>
+inline long lround(const concepts::real_concept& v, const Policy& pol)
{
- return lround(v.value());
+ return lround(v.value(), pol);
}
#ifdef BOOST_HAS_LONG_LONG
-template <>
-inline long long llround<concepts::real_concept>(const concepts::real_concept& v)
+template <class Policy>
+inline long long llround(const concepts::real_concept& v, const Policy& pol)
{
- return llround(v.value());
+ return llround(v.value(), pol);
}
#endif
-template <>
-inline int itrunc<concepts::real_concept>(const concepts::real_concept& v)
+template <class Policy>
+inline int itrunc(const concepts::real_concept& v, const Policy& pol)
{
- return itrunc(v.value());
+ return itrunc(v.value(), pol);
}
-template <>
-inline long ltrunc<concepts::real_concept>(const concepts::real_concept& v)
+template <class Policy>
+inline long ltrunc(const concepts::real_concept& v, const Policy& pol)
{
- return ltrunc(v.value());
+ return ltrunc(v.value(), pol);
}
#ifdef BOOST_HAS_LONG_LONG
-template <>
-inline long long lltrunc<concepts::real_concept>(const concepts::real_concept& v)
+template <class Policy>
+inline long long lltrunc(const concepts::real_concept& v, const Policy& pol)
{
- return lltrunc(v.value());
+ return lltrunc(v.value(), pol);
}
#endif
Modified: sandbox/math_toolkit/boost/math/concepts/std_real_concept.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/concepts/std_real_concept.hpp (original)
+++ sandbox/math_toolkit/boost/math/concepts/std_real_concept.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -282,46 +282,46 @@
//
// Conversion and truncation routines:
//
-template <>
-inline int iround<concepts::std_real_concept>(const concepts::std_real_concept& v)
+template <class Policy>
+inline int iround(const concepts::std_real_concept& v, const Policy& pol)
{
- return iround(v.value());
+ return iround(v.value(), pol);
}
-template <>
-inline long lround<concepts::std_real_concept>(const concepts::std_real_concept& v)
+template <class Policy>
+inline long lround(const concepts::std_real_concept& v, const Policy& pol)
{
- return lround(v.value());
+ return lround(v.value(), pol);
}
#ifdef BOOST_HAS_LONG_LONG
-template <>
-inline long long llround<concepts::std_real_concept>(const concepts::std_real_concept& v)
+template <class Policy>
+inline long long llround(const concepts::std_real_concept& v, const Policy& pol)
{
- return llround(v.value());
+ return llround(v.value(), pol);
}
#endif
-template <>
-inline int itrunc<concepts::std_real_concept>(const concepts::std_real_concept& v)
+template <class Policy>
+inline int itrunc(const concepts::std_real_concept& v, const Policy& pol)
{
- return itrunc(v.value());
+ return itrunc(v.value(), pol);
}
-template <>
-inline long ltrunc<concepts::std_real_concept>(const concepts::std_real_concept& v)
+template <class Policy>
+inline long ltrunc(const concepts::std_real_concept& v, const Policy& pol)
{
- return ltrunc(v.value());
+ return ltrunc(v.value(), pol);
}
#ifdef BOOST_HAS_LONG_LONG
-template <>
-inline long long lltrunc<concepts::std_real_concept>(const concepts::std_real_concept& v)
+template <class Policy>
+inline long long lltrunc(const concepts::std_real_concept& v, const Policy& pol)
{
- return lltrunc(v.value());
+ return lltrunc(v.value(), pol);
}
#endif
Modified: sandbox/math_toolkit/boost/math/distributions/non_central_chi_squared.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/distributions/non_central_chi_squared.hpp (original)
+++ sandbox/math_toolkit/boost/math/distributions/non_central_chi_squared.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -70,7 +70,7 @@
// k is chosen as the peek of the Poisson weights, which
// will occur *before* the largest term.
//
- int k = iround(lambda);
+ int k = iround(lambda, pol);
// Forwards and backwards Poisson weights:
T poisf = boost::math::gamma_p_derivative(1 + k, lambda, pol);
T poisb = poisf * k / lambda;
@@ -87,7 +87,8 @@
// stable direction for the gamma function
// recurrences:
//
- for(int i = k; static_cast<boost::uintmax_t>(i) < max_iter; ++i)
+ int i;
+ for(i = k; static_cast<boost::uintmax_t>(i-k) < max_iter; ++i)
{
T term = poisf * gamf;
sum += term;
@@ -97,6 +98,11 @@
if((sum == 0) || (term / sum < errtol))
break;
}
+ //Error check:
+ if(static_cast<boost::uintmax_t>(i-k) >= max_iter)
+ policies::raise_evaluation_error(
+ "cdf(non_central_chi_squared_distribution<%1%>, %1%)",
+ "Series did not converge, closest value was %1%", sum, pol);
//
// Now backwards iteration: the gamma
// function recurrences are unstable in this
@@ -153,7 +159,8 @@
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
T errtol = ldexp(1.0, -boost::math::policies::digits<T, Policy>());
- for(int i = 1; static_cast<boost::uintmax_t>(i) < max_iter; ++i)
+ int i;
+ for(i = 1; static_cast<boost::uintmax_t>(i) < max_iter; ++i)
{
tk = tk * x / (f + 2 * i);
uk = uk * lambda / i;
@@ -163,6 +170,11 @@
if(term / sum < errtol)
break;
}
+ //Error check:
+ if(static_cast<boost::uintmax_t>(i) >= max_iter)
+ policies::raise_evaluation_error(
+ "cdf(non_central_chi_squared_distribution<%1%>, %1%)",
+ "Series did not converge, closest value was %1%", sum, pol);
return sum;
}
@@ -185,7 +197,7 @@
//
BOOST_MATH_STD_USING
// Special case:
- if(x == 0)
+ if(y == 0)
return 0;
boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
T errtol = ldexp(1.0, -boost::math::policies::digits<T, Policy>());
@@ -200,7 +212,7 @@
// function, which ocurrs *after* the largest term in the
// sum.
//
- int k = iround(del);
+ int k = iround(del, pol);
T a = n / 2 + k;
// Central chi squared term for forward iteration:
T gamkf = boost::math::gamma_p(a, x, pol);
@@ -256,6 +268,12 @@
++i;
}while((errorf / sum > errtol) && (static_cast<boost::uintmax_t>(i) < max_iter));
+ //Error check:
+ if(static_cast<boost::uintmax_t>(i) >= max_iter)
+ policies::raise_evaluation_error(
+ "cdf(non_central_chi_squared_distribution<%1%>, %1%)",
+ "Series did not converge, closest value was %1%", sum, pol);
+
return sum;
}
@@ -511,14 +529,21 @@
v = pdf(dist, lower_bound);
}while(maxval < v);
- boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+ boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
- return tools::brent_find_minima(
+ RealType result = tools::brent_find_minima(
pdf_minimizer<RealType, Policy>(dist),
lower_bound,
upper_bound,
policies::digits<RealType, Policy>(),
max_iter).first;
+ if(max_iter == policies::get_max_root_iterations<Policy>())
+ {
+ return policies::raise_evaluation_error<RealType>(function, "Unable to locate solution in a reasonable time:"
+ " either there is no answer to the mode of the non central chi squared distribution"
+ " or the answer is infinite. Current best guess is %1%", result, Policy());
+ }
+ return result;
}
template <class RealType, class Policy>
Modified: sandbox/math_toolkit/boost/math/distributions/poisson.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/distributions/poisson.hpp (original)
+++ sandbox/math_toolkit/boost/math/distributions/poisson.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -341,7 +341,7 @@
&& k < max_factorial<RealType>::value)
{ // k is small enough (for float 34, double 170 ...) to use factorial(k).
return exp(-mean) * pow(mean, k) /
- unchecked_factorial<RealType>(itrunc(floork));
+ unchecked_factorial<RealType>(itrunc(floork, Policy()));
}
else
{ // Need to use log(factorial(k)) = lgamma(k+1)
Modified: sandbox/math_toolkit/boost/math/policies/error_handling.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/policies/error_handling.hpp (original)
+++ sandbox/math_toolkit/boost/math/policies/error_handling.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -37,6 +37,12 @@
evaluation_error(const std::string& s) : std::runtime_error(s){}
};
+class rounding_error : public std::runtime_error
+{
+public:
+ rounding_error(const std::string& s) : std::runtime_error(s){}
+};
+
namespace policies{
//
// Forward declarations of user error handlers,
@@ -54,6 +60,8 @@
T user_denorm_error(const char* function, const char* message, const T& val);
template <class T>
T user_evaluation_error(const char* function, const char* message, const T& val);
+template <class T>
+T user_rounding_error(const char* function, const char* message, const T& val);
namespace detail
{
@@ -362,6 +370,53 @@
return user_evaluation_error(function, message, val);
}
+template <class T>
+inline T raise_rounding_error(
+ const char* function,
+ const char* message,
+ const T& val,
+ const ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&)
+{
+ raise_error<boost::math::rounding_error, T>(function, message, val);
+ // we never get here:
+ return T(0);
+}
+
+template <class T>
+inline T raise_rounding_error(
+ const char* ,
+ const char* ,
+ const T& val,
+ const ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&)
+{
+ // This may or may not do the right thing, but the user asked for the error
+ // to be ignored so here we go anyway:
+ return val;
+}
+
+template <class T>
+inline T raise_rounding_error(
+ const char* ,
+ const char* ,
+ const T& val,
+ const ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&)
+{
+ errno = ERANGE;
+ // This may or may not do the right thing, but the user asked for the error
+ // to be silent so here we go anyway:
+ return val;
+}
+
+template <class T>
+inline T raise_rounding_error(
+ const char* function,
+ const char* message,
+ const T& val,
+ const ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&)
+{
+ return user_rounding_error(function, message, val);
+}
+
} // namespace detail
template <class T, class Policy>
@@ -419,6 +474,15 @@
val, policy_type());
}
+template <class T, class Policy>
+inline T raise_rounding_error(const char* function, const char* message, const T& val, const Policy&)
+{
+ typedef typename Policy::rounding_error_type policy_type;
+ return detail::raise_rounding_error(
+ function, message ? message : "Value %1% can not be represented in the target integer type.",
+ val, policy_type());
+}
+
//
// checked_narrowing_cast:
//
Modified: sandbox/math_toolkit/boost/math/policies/policy.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/policies/policy.hpp (original)
+++ sandbox/math_toolkit/boost/math/policies/policy.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -54,6 +54,9 @@
#ifndef BOOST_MATH_EVALUATION_ERROR_POLICY
#define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error
#endif
+#ifndef BOOST_MATH_ROUNDING_ERROR_POLICY
+#define BOOST_MATH_ROUNDING_ERROR_POLICY throw_on_error
+#endif
#ifndef BOOST_MATH_UNDERFLOW_ERROR_POLICY
#define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error
#endif
@@ -178,6 +181,7 @@
BOOST_MATH_META_INT(error_policy_type, underflow_error, BOOST_MATH_UNDERFLOW_ERROR_POLICY)
BOOST_MATH_META_INT(error_policy_type, denorm_error, BOOST_MATH_DENORM_ERROR_POLICY)
BOOST_MATH_META_INT(error_policy_type, evaluation_error, BOOST_MATH_EVALUATION_ERROR_POLICY)
+BOOST_MATH_META_INT(error_policy_type, rounding_error, BOOST_MATH_ROUNDING_ERROR_POLICY)
//
// Policy types for internal promotion:
@@ -398,6 +402,7 @@
typedef typename detail::find_arg<arg_list, is_underflow_error<mpl::_1>, underflow_error<> >::type underflow_error_type;
typedef typename detail::find_arg<arg_list, is_denorm_error<mpl::_1>, denorm_error<> >::type denorm_error_type;
typedef typename detail::find_arg<arg_list, is_evaluation_error<mpl::_1>, evaluation_error<> >::type evaluation_error_type;
+ typedef typename detail::find_arg<arg_list, is_rounding_error<mpl::_1>, rounding_error<> >::type rounding_error_type;
private:
//
// Now work out the precision:
@@ -440,6 +445,7 @@
typedef underflow_error<> underflow_error_type;
typedef denorm_error<> denorm_error_type;
typedef evaluation_error<> evaluation_error_type;
+ typedef rounding_error<> rounding_error_type;
#if BOOST_MATH_DIGITS10_POLICY == 0
typedef digits2<> precision_type;
#else
@@ -463,6 +469,7 @@
typedef underflow_error<> underflow_error_type;
typedef denorm_error<> denorm_error_type;
typedef evaluation_error<> evaluation_error_type;
+ typedef rounding_error<> rounding_error_type;
#if BOOST_MATH_DIGITS10_POLICY == 0
typedef digits2<> precision_type;
#else
@@ -500,6 +507,7 @@
typedef typename detail::find_arg<arg_list, is_underflow_error<mpl::_1>, typename Policy::underflow_error_type >::type underflow_error_type;
typedef typename detail::find_arg<arg_list, is_denorm_error<mpl::_1>, typename Policy::denorm_error_type >::type denorm_error_type;
typedef typename detail::find_arg<arg_list, is_evaluation_error<mpl::_1>, typename Policy::evaluation_error_type >::type evaluation_error_type;
+ typedef typename detail::find_arg<arg_list, is_rounding_error<mpl::_1>, typename Policy::rounding_error_type >::type rounding_error_type;
//
// Now work out the precision:
//
@@ -534,6 +542,7 @@
underflow_error_type,
denorm_error_type,
evaluation_error_type,
+ rounding_error_type,
precision_type,
promote_float_type,
promote_double_type,
Modified: sandbox/math_toolkit/boost/math/special_functions/bessel.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/bessel.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/bessel.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -129,7 +129,7 @@
if(floor(v) == v)
{
T r = cyl_bessel_j_imp(v, -x, t, pol);
- if(iround(v) & 1)
+ if(iround(v, pol) & 1)
r = -r;
return r;
}
@@ -165,7 +165,7 @@
if(fabs(x) > asymptotic_bessel_j_limit<T>(v, tag_type()))
return asymptotic_bessel_j_large_x_2(v, x);
else
- return bessel_jn(iround(v), x, pol);
+ return bessel_jn(iround(v, pol), x, pol);
}
return cyl_bessel_j_imp(v, x, bessel_no_int_tag(), pol);
}
@@ -228,7 +228,7 @@
if(floor(v) == v)
{
T r = cyl_bessel_i_imp(v, -x, pol);
- if(iround(v) & 1)
+ if(iround(v, pol) & 1)
r = -r;
return r;
}
@@ -337,12 +337,12 @@
if((fabs(x) > asymptotic_bessel_y_limit<T>(tag_type())) && (fabs(x) > 5 * abs(v)))
{
T r = asymptotic_bessel_y_large_x_2(static_cast<T>(abs(v)), x);
- if((v < 0) && (itrunc(v) & 1))
+ if((v < 0) && (itrunc(v, pol) & 1))
r = -r;
return r;
}
else
- return bessel_yn(itrunc(v), x, pol);
+ return bessel_yn(itrunc(v, pol), x, pol);
}
return cyl_neumann_imp<T>(v, x, bessel_no_int_tag(), pol);
}
Modified: sandbox/math_toolkit/boost/math/special_functions/beta.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/beta.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/beta.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -1060,7 +1060,7 @@
else if(a > 15)
{
// sidestep so we can use the series representation:
- int n = itrunc(floor(b));
+ int n = itrunc(floor(b), pol);
if(n == b)
--n;
T bbar = b - n;
@@ -1082,7 +1082,7 @@
// the formula here for the non-normalised case is tricky to figure
// out (for me!!), and requires two pochhammer calculations rather
// than one, so leave it for now....
- int n = itrunc(floor(b));
+ int n = itrunc(floor(b), pol);
T bbar = b - n;
if(bbar <= 0)
{
Modified: sandbox/math_toolkit/boost/math/special_functions/cos_pi.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/cos_pi.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/cos_pi.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -17,8 +17,8 @@
namespace boost{ namespace math{
-template <class T>
-T cos_pi(T x)
+template <class T, class Policy>
+T cos_pi(T x, const Policy& pol)
{
BOOST_MATH_STD_USING // ADL of std names
// cos of pi*x:
@@ -31,7 +31,7 @@
}
T rem = floor(x);
- if(itrunc(rem) & 1)
+ if(itrunc(rem, pol) & 1)
invert = !invert;
rem = x - rem;
if(rem > 0.5f)
@@ -46,10 +46,10 @@
return invert ? -rem : rem;
}
-template <class T, class Policy>
-inline T cos_pi(T x, const Policy&)
+template <class T>
+inline T cos_pi(T x)
{
- return cos_pi(x);
+ return cos_pi(x, policies::policy<>());
}
} // namespace math
Modified: sandbox/math_toolkit/boost/math/special_functions/detail/bessel_ik.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/detail/bessel_ik.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/detail/bessel_ik.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -234,7 +234,7 @@
v = -v; // v is non-negative from here
kind |= need_k;
}
- n = iround(v);
+ n = iround(v, pol);
u = v - n; // -1/2 <= u < 1/2
BOOST_MATH_INSTRUMENT_VARIABLE(n);
BOOST_MATH_INSTRUMENT_VARIABLE(u);
Modified: sandbox/math_toolkit/boost/math/special_functions/detail/bessel_jy.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/detail/bessel_jy.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/detail/bessel_jy.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -225,7 +225,7 @@
v = -v; // v is non-negative from here
kind = need_j|need_y; // need both for reflection formula
}
- n = iround(v);
+ n = iround(v, pol);
u = v - n; // -1/2 <= u < 1/2
if (x == 0)
Modified: sandbox/math_toolkit/boost/math/special_functions/detail/t_distribution_inv.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/detail/t_distribution_inv.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/detail/t_distribution_inv.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -205,7 +205,7 @@
//
T tolerance = ldexp(1.0f, (2 * policies::digits<T, Policy>()) / 3);
- switch(itrunc(df))
+ switch(itrunc(df, Policy()))
{
case 1:
{
@@ -369,7 +369,7 @@
// where we use Shaw's tail series.
// The crossover point is roughly exponential in -df:
//
- T crossover = ldexp(1.0f, iround(df / -0.654f));
+ T crossover = ldexp(1.0f, iround(df / -0.654f, pol));
if(u > crossover)
{
result = boost::math::detail::inverse_students_t_hill(df, u, pol);
Modified: sandbox/math_toolkit/boost/math/special_functions/factorials.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/factorials.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/factorials.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -163,7 +163,7 @@
// handle it, split the product up into three parts:
//
T xp1 = x + 1;
- unsigned n2 = itrunc(floor(xp1));
+ unsigned n2 = itrunc(floor(xp1), pol);
if(n2 == xp1)
return 0;
T result = boost::math::tgamma_delta_ratio(xp1, -static_cast<T>(n2), pol);
Modified: sandbox/math_toolkit/boost/math/special_functions/gamma.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/gamma.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/gamma.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -165,7 +165,7 @@
}
if((floor(z) == z) && (z < max_factorial<T>::value))
{
- result *= unchecked_factorial<T>(itrunc(z) - 1);
+ result *= unchecked_factorial<T>(itrunc(z, pol) - 1);
}
else
{
@@ -370,7 +370,7 @@
BOOST_MATH_INSTRUMENT_CODE(prefix);
if((floor(z) == z) && (z < max_factorial<T>::value))
{
- prefix *= unchecked_factorial<T>(itrunc(z) - 1);
+ prefix *= unchecked_factorial<T>(itrunc(z, pol) - 1);
}
else
{
@@ -1095,7 +1095,7 @@
//
if((z <= max_factorial<T>::value) && (z + delta <= max_factorial<T>::value))
{
- return unchecked_factorial<T>((unsigned)itrunc(z) - 1) / unchecked_factorial<T>((unsigned)itrunc(z + delta) - 1);
+ return unchecked_factorial<T>((unsigned)itrunc(z, pol) - 1) / unchecked_factorial<T>((unsigned)itrunc(z + delta) - 1);
}
}
if(fabs(delta) < 20)
Modified: sandbox/math_toolkit/boost/math/special_functions/modf.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/modf.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/modf.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -15,33 +15,53 @@
namespace boost{ namespace math{
+template <class T, class Policy>
+inline T modf(const T& v, T* ipart, const Policy& pol)
+{
+ *ipart = trunc(v, pol);
+ return v - *ipart;
+}
template <class T>
inline T modf(const T& v, T* ipart)
{
- *ipart = trunc(v);
- return v - *ipart;
+ return modf(v, ipart, policies::policy<>());
}
+template <class T, class Policy>
+inline T modf(const T& v, int* ipart, const Policy& pol)
+{
+ *ipart = itrunc(v, pol);
+ return v - *ipart;
+}
template <class T>
inline T modf(const T& v, int* ipart)
{
- *ipart = itrunc(v);
- return v - *ipart;
+ return modf(v, ipart, policies::policy<>());
}
+template <class T, class Policy>
+inline T modf(const T& v, long* ipart, const Policy& pol)
+{
+ *ipart = ltrunc(v, pol);
+ return v - *ipart;
+}
template <class T>
inline T modf(const T& v, long* ipart)
{
- *ipart = ltrunc(v);
- return v - *ipart;
+ return modf(v, ipart, policies::policy<>());
}
#ifdef BOOST_HAS_LONG_LONG
+template <class T, class Policy>
+inline T modf(const T& v, long long* ipart, const Policy& pol)
+{
+ *ipart = lltrunc(v, pol);
+ return v - *ipart;
+}
template <class T>
inline T modf(const T& v, long long* ipart)
{
- *ipart = lltrunc(v);
- return v - *ipart;
+ return modf(v, ipart, policies::policy<>());
}
#endif
Modified: sandbox/math_toolkit/boost/math/special_functions/round.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/round.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/round.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -11,15 +11,24 @@
#endif
#include <boost/math/tools/config.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
namespace boost{ namespace math{
-template <class T>
-inline T round(const T& v)
+template <class T, class Policy>
+inline T round(const T& v, const Policy& pol)
{
BOOST_MATH_STD_USING
+ if(!(boost::math::isfinite)(v))
+ return policies::raise_rounding_error("boost::math::round<%1%>(%1%)", 0, v, pol);
return floor(v + 0.5f);
}
+template <class T>
+inline T round(const T& v)
+{
+ return round(v, policies::policy<>());
+}
//
// The following functions will not compile unless T has an
// implicit convertion to the integer types. For user-defined
@@ -29,24 +38,48 @@
// namespace as the UDT: these will then be found via argument
// dependent lookup. See our concept archetypes for examples.
//
+template <class T, class Policy>
+inline int iround(const T& v, const Policy& pol)
+{
+ T r = boost::math::round(v, pol);
+ if(fabs(r) > (std::numeric_limits<int>::max)())
+ return static_cast<int>(policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, pol));
+ return static_cast<int>(r);
+}
template <class T>
inline int iround(const T& v)
{
- return static_cast<int>(boost::math::round(v));
+ return iround(v, policies::policy<>());
}
+template <class T, class Policy>
+inline long lround(const T& v, const Policy& pol)
+{
+ T r = boost::math::round(v, pol);
+ if(fabs(r) > (std::numeric_limits<long>::max)())
+ return static_cast<long int>(policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", 0, v, pol));
+ return static_cast<long int>(r);
+}
template <class T>
inline long lround(const T& v)
{
- return static_cast<long int>(boost::math::round(v));
+ return lround(v, policies::policy<>());
}
#ifdef BOOST_HAS_LONG_LONG
+template <class T, class Policy>
+inline long long llround(const T& v, const Policy& pol)
+{
+ T r = boost::math::round(v, pol);
+ if(fabs(r) > (std::numeric_limits<long long>::max)())
+ return static_cast<long long>(policies::raise_rounding_error("boost::math::llround<%1%>(%1%)", 0, v, pol));
+ return static_cast<long long>(r);
+}
template <class T>
inline long long llround(const T& v)
{
- return static_cast<long long>(boost::math::round(v));
+ return llround(v, policies::policy<>());
}
#endif
Modified: sandbox/math_toolkit/boost/math/special_functions/sin_pi.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/sin_pi.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/sin_pi.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -17,8 +17,8 @@
namespace boost{ namespace math{
-template <class T>
-T sin_pi(T x)
+template <class T, class Policy>
+T sin_pi(T x, const Policy& pol)
{
BOOST_MATH_STD_USING // ADL of std names
if(x < 0)
@@ -36,7 +36,7 @@
invert = false;
T rem = floor(x);
- if(itrunc(rem) & 1)
+ if(itrunc(rem, pol) & 1)
invert = !invert;
rem = x - rem;
if(rem > 0.5f)
@@ -48,10 +48,10 @@
return invert ? -rem : rem;
}
-template <class T, class Policy>
-inline T sin_pi(T x, const Policy&)
+template <class T>
+inline T sin_pi(T x)
{
- return boost::math::sin_pi(x);
+ return boost::math::sin_pi(x, policies::policy<>());
}
} // namespace math
Modified: sandbox/math_toolkit/boost/math/special_functions/trunc.hpp
==============================================================================
--- sandbox/math_toolkit/boost/math/special_functions/trunc.hpp (original)
+++ sandbox/math_toolkit/boost/math/special_functions/trunc.hpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -11,15 +11,24 @@
#endif
#include <boost/math/tools/config.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
namespace boost{ namespace math{
-template <class T>
-inline T trunc(const T& v)
+template <class T, class Policy>
+inline T trunc(const T& v, const Policy& pol)
{
BOOST_MATH_STD_USING
+ if(!(boost::math::isfinite)(v))
+ return policies::raise_rounding_error("boost::math::trunc<%1%>(%1%)", 0, v, pol);
return (v >= 0) ? floor(v) : ceil(v);
}
+template <class T>
+inline T trunc(const T& v)
+{
+ return trunc(v, policies::policy<>());
+}
//
// The following functions will not compile unless T has an
// implicit convertion to the integer types. For user-defined
@@ -29,24 +38,48 @@
// namespace as the UDT: these will then be found via argument
// dependent lookup. See our concept archetypes for examples.
//
+template <class T, class Policy>
+inline int itrunc(const T& v, const Policy& pol)
+{
+ T r = boost::math::trunc(v, pol);
+ if(fabs(r) > (std::numeric_limits<int>::max)())
+ return static_cast<int>(policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", 0, v, pol));
+ return static_cast<int>(r);
+}
template <class T>
inline int itrunc(const T& v)
{
- return static_cast<int>(boost::math::trunc(v));
+ return itrunc(v, policies::policy<>());
}
+template <class T, class Policy>
+inline long ltrunc(const T& v, const Policy& pol)
+{
+ T r = boost::math::trunc(v, pol);
+ if(fabs(r) > (std::numeric_limits<long>::max)())
+ return static_cast<long>(policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, v, pol));
+ return static_cast<long>(r);
+}
template <class T>
inline long ltrunc(const T& v)
{
- return static_cast<long int>(boost::math::trunc(v));
+ return ltrunc(v, policies::policy<>());
}
#ifdef BOOST_HAS_LONG_LONG
+template <class T, class Policy>
+inline long long lltrunc(const T& v, const Policy& pol)
+{
+ T r = boost::math::trunc(v, pol);
+ if(fabs(r) > (std::numeric_limits<long long>::max)())
+ return static_cast<long long>(policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, pol));
+ return static_cast<long long>(r);
+}
template <class T>
inline long long lltrunc(const T& v)
{
- return static_cast<long long>(boost::math::trunc(v));
+ return lltrunc(v, policies::policy<>());
}
#endif
Modified: sandbox/math_toolkit/libs/math/test/Jamfile.v2
==============================================================================
--- sandbox/math_toolkit/libs/math/test/Jamfile.v2 (original)
+++ sandbox/math_toolkit/libs/math/test/Jamfile.v2 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -349,6 +349,7 @@
compile compile_test/dist_gamma_incl_test.cpp ;
compile compile_test/dist_lognormal_incl_test.cpp ;
compile compile_test/dist_neg_binom_incl_test.cpp ;
+compile compile_test/dist_nc_chi_squ_incl_test.cpp ;
compile compile_test/dist_normal_incl_test.cpp ;
compile compile_test/dist_poisson_incl_test.cpp ;
compile compile_test/dist_students_t_incl_test.cpp ;
Added: sandbox/math_toolkit/libs/math/test/compile_test/dist_nc_chi_squ_incl_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/math_toolkit/libs/math/test/compile_test/dist_nc_chi_squ_incl_test.cpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -0,0 +1,25 @@
+// Copyright John Maddock 2008.
+// 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)
+//
+// Basic sanity check that header <boost/math/distributions/non_central_chi_squared.hpp>
+// #includes all the files that it needs to.
+//
+#include <boost/math/distributions/non_central_chi_squared.hpp>
+//
+// Note this header includes no other headers, this is
+// important if this test is to be meaningful:
+//
+#include "test_compile_result.hpp"
+
+void check()
+{
+ TEST_DIST_FUNC(non_central_chi_squared)
+}
+
+template class boost::math::non_central_chi_squared_distribution<float, boost::math::policies::policy<> >;
+template class boost::math::non_central_chi_squared_distribution<double, boost::math::policies::policy<> >;
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template class boost::math::non_central_chi_squared_distribution<long double, boost::math::policies::policy<> >;
+#endif
Modified: sandbox/math_toolkit/libs/math/test/test_nc_chi_squared.cpp
==============================================================================
--- sandbox/math_toolkit/libs/math/test/test_nc_chi_squared.cpp (original)
+++ sandbox/math_toolkit/libs/math/test/test_nc_chi_squared.cpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -438,30 +438,30 @@
value_type pt = data[i][2];
BOOST_CHECK_CLOSE_EX(pt, p, precision, i);
}
- //
- // Sanity check mode as well, note this may well overflow
- // since we don't know how to compute PDF's (and hence the mode)
- // for large values of the parameters, in addition accuracy of
- // the mode is at *best* the square root of the accuracy of the PDF:
- //
- try
- {
- value_type m = mode(boost::math::non_central_chi_squared_distribution<value_type>(data[i][0], data[i][1]));
- value_type p = pdf(boost::math::non_central_chi_squared_distribution<value_type>(data[i][0], data[i][1]), m);
- BOOST_CHECK_EX(pdf(boost::math::non_central_chi_squared_distribution<value_type>(data[i][0], data[i][1]), m * (1 + sqrt(precision))) <= p, i);
- BOOST_CHECK_EX(pdf(boost::math::non_central_chi_squared_distribution<value_type>(data[i][0], data[i][1]), m * (1 - sqrt(precision))) <= p, i);
- }
- catch(const std::overflow_error&)
- {
- }
- //
- // Sanity check degrees-of-freedom finder, don't bother at float
- // precision though as there's not enough data in the probability
- // values to get back to the correct degrees of freedom or
- // non-cenrality parameter:
- //
if(boost::math::tools::digits<value_type>() > 50)
{
+ //
+ // Sanity check mode, note this may well overflow
+ // since we don't know how to compute PDF's (and hence the mode)
+ // for large values of the parameters, in addition accuracy of
+ // the mode is at *best* the square root of the accuracy of the PDF:
+ //
+ try
+ {
+ value_type m = mode(boost::math::non_central_chi_squared_distribution<value_type>(data[i][0], data[i][1]));
+ value_type p = pdf(boost::math::non_central_chi_squared_distribution<value_type>(data[i][0], data[i][1]), m);
+ BOOST_CHECK_EX(pdf(boost::math::non_central_chi_squared_distribution<value_type>(data[i][0], data[i][1]), m * (1 + sqrt(precision) * 10)) <= p, i);
+ BOOST_CHECK_EX(pdf(boost::math::non_central_chi_squared_distribution<value_type>(data[i][0], data[i][1]), m * (1 - sqrt(precision)) * 10) <= p, i);
+ }
+ catch(const std::overflow_error&)
+ {
+ }
+ //
+ // Sanity check degrees-of-freedom finder, don't bother at float
+ // precision though as there's not enough data in the probability
+ // values to get back to the correct degrees of freedom or
+ // non-cenrality parameter:
+ //
try{
if((data[i][3] < 0.99) && (data[i][3] != 0))
{
Modified: sandbox/math_toolkit/libs/math/test/test_round.cpp
==============================================================================
--- sandbox/math_toolkit/libs/math/test/test_round.cpp (original)
+++ sandbox/math_toolkit/libs/math/test/test_round.cpp 2008-01-23 05:41:06 EST (Wed, 23 Jan 2008)
@@ -152,6 +152,67 @@
}
#endif
}
+ //
+ // Finish off by testing the error handlers:
+ //
+ BOOST_CHECK_THROW(boost::math::iround(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::iround(static_cast<T>(-1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::lround(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::lround(static_cast<T>(-1e20)), boost::math::rounding_error);
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_CHECK_THROW(boost::math::llround(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::llround(static_cast<T>(-1e20)), boost::math::rounding_error);
+#endif
+ if(std::numeric_limits<T>::has_infinity)
+ {
+ BOOST_CHECK_THROW(boost::math::round(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::iround(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::iround(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::lround(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::lround(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ #ifdef BOOST_HAS_LONG_LONG
+ BOOST_CHECK_THROW(boost::math::llround(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::llround(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ #endif
+ }
+ if(std::numeric_limits<T>::has_quiet_NaN)
+ {
+ BOOST_CHECK_THROW(boost::math::round(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::iround(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::lround(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ #ifdef BOOST_HAS_LONG_LONG
+ BOOST_CHECK_THROW(boost::math::llround(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ #endif
+ }
+ BOOST_CHECK_THROW(boost::math::itrunc(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::itrunc(static_cast<T>(-1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::ltrunc(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::ltrunc(static_cast<T>(-1e20)), boost::math::rounding_error);
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_CHECK_THROW(boost::math::lltrunc(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::lltrunc(static_cast<T>(-1e20)), boost::math::rounding_error);
+#endif
+ if(std::numeric_limits<T>::has_infinity)
+ {
+ BOOST_CHECK_THROW(boost::math::trunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::itrunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::itrunc(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::ltrunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::ltrunc(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ #ifdef BOOST_HAS_LONG_LONG
+ BOOST_CHECK_THROW(boost::math::lltrunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::lltrunc(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ #endif
+ }
+ if(std::numeric_limits<T>::has_quiet_NaN)
+ {
+ BOOST_CHECK_THROW(boost::math::trunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::itrunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(boost::math::ltrunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ #ifdef BOOST_HAS_LONG_LONG
+ BOOST_CHECK_THROW(boost::math::lltrunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ #endif
+ }
}
int test_main(int, char* [])
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