Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/math/special_functions/airy.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
line wrap: on
line diff
--- a/DEPENDENCIES/generic/include/boost/math/special_functions/airy.hpp Fri Sep 04 12:01:02 2015 +0100 +++ b/DEPENDENCIES/generic/include/boost/math/special_functions/airy.hpp Mon Sep 07 11:12:49 2015 +0100 @@ -7,6 +7,8 @@ #ifndef BOOST_MATH_AIRY_HPP #define BOOST_MATH_AIRY_HPP +#include <limits> +#include <boost/math/special_functions/math_fwd.hpp> #include <boost/math/special_functions/bessel.hpp> #include <boost/math/special_functions/cbrt.hpp> #include <boost/math/special_functions/detail/airy_ai_bi_zero.hpp> @@ -154,10 +156,17 @@ } template <class T, class Policy> -T airy_ai_zero_imp(unsigned m, const Policy& pol) +T airy_ai_zero_imp(int m, const Policy& pol) { BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. + // Handle cases when a negative zero (negative rank) is requested. + if(m < 0) + { + return policies::raise_domain_error<T>("boost::math::airy_ai_zero<%1%>(%1%, int)", + "Requested the %1%'th zero, but the rank must be 1 or more !", static_cast<T>(m), pol); + } + // Handle case when the zero'th zero is requested. if(m == 0U) { @@ -168,22 +177,21 @@ // Set up the initial guess for the upcoming root-finding. const T guess_root = boost::math::detail::airy_zero::airy_ai_zero_detail::initial_guess<T>(m); - // Select the maximum allowed iterations, being at least 24. - boost::uintmax_t number_of_iterations = (std::max)(24, int(std::numeric_limits<T>::digits10)); + // Select the maximum allowed iterations based on the number + // of decimal digits in the numeric type T, being at least 12. + const int my_digits10 = static_cast<int>(static_cast<float>(policies::digits<T, Policy>() * 0.301F)); - // Select the desired number of binary digits of precision. - // Account for the radix of number representations having non-two radix! - const int my_digits2 = int(float(std::numeric_limits<T>::digits) - * ( log(float(std::numeric_limits<T>::radix)) - / log(2.0F))); + const boost::uintmax_t iterations_allowed = static_cast<boost::uintmax_t>((std::max)(12, my_digits10 * 2)); + + boost::uintmax_t iterations_used = iterations_allowed; // Use a dynamic tolerance because the roots get closer the higher m gets. T tolerance; - if (m <= 10U) { tolerance = T(0.3F); } - else if(m <= 100U) { tolerance = T(0.1F); } - else if(m <= 1000U) { tolerance = T(0.05F); } - else { tolerance = T(1) / sqrt(T(m)); } + if (m <= 10) { tolerance = T(0.3F); } + else if(m <= 100) { tolerance = T(0.1F); } + else if(m <= 1000) { tolerance = T(0.05F); } + else { tolerance = T(1) / sqrt(T(m)); } // Perform the root-finding using Newton-Raphson iteration from Boost.Math. const T am = @@ -192,19 +200,26 @@ guess_root, T(guess_root - tolerance), T(guess_root + tolerance), - my_digits2, - number_of_iterations); + policies::digits<T, Policy>(), + iterations_used); - static_cast<void>(number_of_iterations); + static_cast<void>(iterations_used); return am; } template <class T, class Policy> -T airy_bi_zero_imp(unsigned m, const Policy& pol) +T airy_bi_zero_imp(int m, const Policy& pol) { BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. + // Handle cases when a negative zero (negative rank) is requested. + if(m < 0) + { + return policies::raise_domain_error<T>("boost::math::airy_bi_zero<%1%>(%1%, int)", + "Requested the %1%'th zero, but the rank must 1 or more !", static_cast<T>(m), pol); + } + // Handle case when the zero'th zero is requested. if(m == 0U) { @@ -214,22 +229,21 @@ // Set up the initial guess for the upcoming root-finding. const T guess_root = boost::math::detail::airy_zero::airy_bi_zero_detail::initial_guess<T>(m); - // Select the maximum allowed iterations, being at least 24. - boost::uintmax_t number_of_iterations = (std::max)(24, int(std::numeric_limits<T>::digits10)); + // Select the maximum allowed iterations based on the number + // of decimal digits in the numeric type T, being at least 12. + const int my_digits10 = static_cast<int>(static_cast<float>(policies::digits<T, Policy>() * 0.301F)); - // Select the desired number of binary digits of precision. - // Account for the radix of number representations having non-two radix! - const int my_digits2 = int(float(std::numeric_limits<T>::digits) - * ( log(float(std::numeric_limits<T>::radix)) - / log(2.0F))); + const boost::uintmax_t iterations_allowed = static_cast<boost::uintmax_t>((std::max)(12, my_digits10 * 2)); + + boost::uintmax_t iterations_used = iterations_allowed; // Use a dynamic tolerance because the roots get closer the higher m gets. T tolerance; - if (m <= 10U) { tolerance = T(0.3F); } - else if(m <= 100U) { tolerance = T(0.1F); } - else if(m <= 1000U) { tolerance = T(0.05F); } - else { tolerance = T(1) / sqrt(T(m)); } + if (m <= 10) { tolerance = T(0.3F); } + else if(m <= 100) { tolerance = T(0.1F); } + else if(m <= 1000) { tolerance = T(0.05F); } + else { tolerance = T(1) / sqrt(T(m)); } // Perform the root-finding using Newton-Raphson iteration from Boost.Math. const T bm = @@ -238,10 +252,10 @@ guess_root, T(guess_root - tolerance), T(guess_root + tolerance), - my_digits2, - number_of_iterations); + policies::digits<T, Policy>(), + iterations_used); - static_cast<void>(number_of_iterations); + static_cast<void>(iterations_used); return bm; } @@ -337,7 +351,7 @@ } template <class T, class Policy> -inline T airy_ai_zero(unsigned m, const Policy& /*pol*/) +inline T airy_ai_zero(int m, const Policy& /*pol*/) { BOOST_FPU_EXCEPTION_GUARD typedef typename policies::evaluation<T, Policy>::type value_type; @@ -347,25 +361,34 @@ policies::promote_double<false>, policies::discrete_quantile<>, policies::assert_undefined<> >::type forwarding_policy; - BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Airy return type must be a floating-point type."); + + BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized + || ( true == std::numeric_limits<T>::is_specialized + && false == std::numeric_limits<T>::is_integer), + "Airy value type must be a floating-point type."); + return policies::checked_narrowing_cast<T, Policy>(detail::airy_ai_zero_imp<value_type>(m, forwarding_policy()), "boost::math::airy_ai_zero<%1%>(unsigned)"); } template <class T> -inline T airy_ai_zero(unsigned m) +inline T airy_ai_zero(int m) { return airy_ai_zero<T>(m, policies::policy<>()); } template <class T, class OutputIterator, class Policy> inline OutputIterator airy_ai_zero( - unsigned start_index, + int start_index, unsigned number_of_zeros, OutputIterator out_it, const Policy& pol) { typedef T result_type; - BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<result_type>::is_integer, "Airy return type must be a floating-point type."); + + BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized + || ( true == std::numeric_limits<T>::is_specialized + && false == std::numeric_limits<T>::is_integer), + "Airy value type must be a floating-point type."); for(unsigned i = 0; i < number_of_zeros; ++i) { @@ -377,7 +400,7 @@ template <class T, class OutputIterator> inline OutputIterator airy_ai_zero( - unsigned start_index, + int start_index, unsigned number_of_zeros, OutputIterator out_it) { @@ -385,7 +408,7 @@ } template <class T, class Policy> -inline T airy_bi_zero(unsigned m, const Policy& /*pol*/) +inline T airy_bi_zero(int m, const Policy& /*pol*/) { BOOST_FPU_EXCEPTION_GUARD typedef typename policies::evaluation<T, Policy>::type value_type; @@ -395,25 +418,34 @@ policies::promote_double<false>, policies::discrete_quantile<>, policies::assert_undefined<> >::type forwarding_policy; - BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Airy return type must be a floating-point type."); + + BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized + || ( true == std::numeric_limits<T>::is_specialized + && false == std::numeric_limits<T>::is_integer), + "Airy value type must be a floating-point type."); + return policies::checked_narrowing_cast<T, Policy>(detail::airy_bi_zero_imp<value_type>(m, forwarding_policy()), "boost::math::airy_bi_zero<%1%>(unsigned)"); } template <typename T> -inline T airy_bi_zero(unsigned m) +inline T airy_bi_zero(int m) { return airy_bi_zero<T>(m, policies::policy<>()); } template <class T, class OutputIterator, class Policy> inline OutputIterator airy_bi_zero( - unsigned start_index, + int start_index, unsigned number_of_zeros, OutputIterator out_it, const Policy& pol) { typedef T result_type; - BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<result_type>::is_integer, "Airy return type must be a floating-point type."); + + BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized + || ( true == std::numeric_limits<T>::is_specialized + && false == std::numeric_limits<T>::is_integer), + "Airy value type must be a floating-point type."); for(unsigned i = 0; i < number_of_zeros; ++i) { @@ -425,7 +457,7 @@ template <class T, class OutputIterator> inline OutputIterator airy_bi_zero( - unsigned start_index, + int start_index, unsigned number_of_zeros, OutputIterator out_it) {