2
0
mirror of https://github.com/boostorg/math.git synced 2026-02-18 02:02:15 +00:00

Get the tests hooked up and working with a variety of compilers.

This commit is contained in:
jzmaddock
2017-06-24 09:48:32 +01:00
parent b55167446f
commit 040feb0240
10 changed files with 221 additions and 136 deletions

View File

@@ -769,23 +769,33 @@ run test_uniform.cpp pch ../../test/build//boost_unit_test_framework ;
run test_weibull.cpp ../../test/build//boost_unit_test_framework ;
run test_zeta.cpp ../../test/build//boost_unit_test_framework test_instances//test_instances pch_light ;
run tanh_sinh_quadrature_test.cpp ../../test/build//boost_unit_test_framework
: : : <define>TEST1 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] :
: : : <define>TEST1 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] :
tanh_sinh_quadrature_test_1 ;
run tanh_sinh_quadrature_test.cpp ../../test/build//boost_unit_test_framework
: : : <define>TEST2 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] :
: : : <define>TEST2 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] :
tanh_sinh_quadrature_test_2 ;
run tanh_sinh_quadrature_test.cpp ../../test/build//boost_unit_test_framework
: : : <define>TEST3 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] :
: : : <define>TEST3 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] :
tanh_sinh_quadrature_test_3 ;
run tanh_sinh_quadrature_test.cpp ../../test/build//boost_unit_test_framework
: : : release <define>TEST4 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] :
: : : release <define>TEST4 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] :
tanh_sinh_quadrature_test_4 ;
run tanh_sinh_quadrature_test.cpp ../../test/build//boost_unit_test_framework
: : : release <define>TEST5 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] :
: : : release <define>TEST5 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] :
tanh_sinh_quadrature_test_5 ;
run tanh_sinh_quadrature_test.cpp ../../test/build//boost_unit_test_framework
: : : <define>TEST6 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] :
: : : <define>TEST6 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] :
tanh_sinh_quadrature_test_6 ;
run sinh_sinh_quadrature_test.cpp ../../test/build//boost_unit_test_framework
: : : [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] ;
run exp_sinh_quadrature_test.cpp ../../test/build//boost_unit_test_framework
: : : <define>TEST1 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] : exp_sinh_quadrature_test_1 ;
run exp_sinh_quadrature_test.cpp ../../test/build//boost_unit_test_framework
: : : release <define>TEST2 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] : exp_sinh_quadrature_test_2 ;
run exp_sinh_quadrature_test.cpp ../../test/build//boost_unit_test_framework
: : : <define>TEST3 [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] : exp_sinh_quadrature_test_3 ;
run test_policy.cpp ../../test/build//boost_unit_test_framework ;
run test_policy_2.cpp ../../test/build//boost_unit_test_framework ;
@@ -886,9 +896,9 @@ run compile_test/dist_triangular_incl_test.cpp compile_test_main ;
run compile_test/dist_uniform_incl_test.cpp compile_test_main ;
run compile_test/dist_weibull_incl_test.cpp compile_test_main ;
run compile_test/distribution_concept_check.cpp ;
run compile_test/exp_sinh_incl_test.cpp compile_test_main ;
run compile_test/sinh_sinh_incl_test.cpp compile_test_main ;
run compile_test/tanh_sinh_incl_test.cpp compile_test_main ;
run compile_test/exp_sinh_incl_test.cpp compile_test_main : : : [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] ;
run compile_test/sinh_sinh_incl_test.cpp compile_test_main : : : [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] ;
run compile_test/tanh_sinh_incl_test.cpp compile_test_main : : : [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] ;
run compile_test/sf_beta_incl_test.cpp compile_test_main ;
run compile_test/sf_bernoulli_incl_test.cpp compile_test_main ;
run compile_test/sf_bessel_incl_test.cpp compile_test_main ;
@@ -969,11 +979,11 @@ compile compile_test/tools_test_inc_test.cpp ;
compile compile_test/tools_toms748_inc_test.cpp ;
compile compile_test/cubic_spline_concept_test.cpp : [ requires cxx11_smart_ptr cxx11_defaulted_functions ] ;
compile compile_test/barycentric_rational_concept_test.cpp : [ requires cxx11_smart_ptr cxx11_defaulted_functions ] ;
compile compile_test/sf_legendre_stieltjes_concept_test.cpp : [ requires cxx11_auto_declarations cxx11_defaulted_functions cxx11_lambdas ] ;
compile compile_test/sf_legendre_stieltjes_concept_test.cpp : [ requires cxx11_auto_declarations cxx11_defaulted_functions cxx11_lambdas cxx11_auto_declarations ] ;
compile compile_test/trapezoidal_concept_test.cpp ;
compile compile_test/cubic_spline_concept_test.cpp : [ requires cxx11_smart_ptr ] ;
compile compile_test/barycentric_rational_concept_test.cpp : [ requires cxx11_smart_ptr ] ;
compile compile_test/sf_legendre_stieltjes_concept_test.cpp : [ requires cxx11_auto_declarations ] ;
compile compile_test/exp_sinh_concept_test.cpp : [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] ;
compile compile_test/sinh_sinh_concept_test.cpp : [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] ;
compile compile_test/tanh_sinh_concept_test.cpp : [ requires cxx11_auto_declarations cxx11_lambdas cxx11_smart_ptr ] ;
run octonion_test.cpp
../../test/build//boost_unit_test_framework ;

View File

@@ -10,6 +10,7 @@
#include <limits>
#include <functional>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/math/concepts/real_concept.hpp>
#include <boost/type_index.hpp>
#include <boost/test/included/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
@@ -47,11 +48,17 @@ using boost::math::constants::root_two_pi;
using boost::math::constants::root_pi;
using boost::math::quadrature::exp_sinh;
#if !defined(TEST1) && !defined(TEST2) && !defined(TEST3)
# define TEST1
# define TEST2
# define TEST3
#endif
template<class Real>
void test_right_limit_infinite()
{
std::cout << "Testing right limit infinite for tanh_sinh in 'A Comparison of Three High Precision Quadrature Schemes' on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
Real Q;
Real Q_expected;
Real error;
@@ -60,19 +67,19 @@ void test_right_limit_infinite()
// Example 12
const auto f2 = [](Real t) { return exp(-t)/sqrt(t); };
Q = integrator.integrate(f2, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f2, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = root_pi<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
// The integrand is strictly positive, so it coincides with the value of the integral:
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol);
auto f3 = [](Real t) { Real z = exp(-t); if (z == 0) { return z; } return z*cos(t); };
Q = integrator.integrate(f3, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f3, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = half<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
auto f4 = [](Real t) { return 1/(1+t*t); };
Q = integrator.integrate(f4, 1, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f4, 1, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = pi<Real>()/4;
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol);
@@ -82,7 +89,7 @@ template<class Real>
void test_left_limit_infinite()
{
std::cout << "Testing left limit infinite for 1/(1+t^2) on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
Real Q;
Real Q_expected;
Real error;
@@ -91,7 +98,7 @@ void test_left_limit_infinite()
// Example 11:
auto f1 = [](Real t) { return 1/(1+t*t);};
Q = integrator.integrate(f1, -std::numeric_limits<Real>::infinity(), 0, &error, &L1);
Q = integrator.integrate(f1, std::numeric_limits<Real>::has_infinity ? -std::numeric_limits<Real>::infinity() : -boost::math::tools::max_value<Real>(), 0, &error, &L1);
Q_expected = half_pi<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol);
@@ -107,7 +114,7 @@ void test_nr_examples()
using std::exp;
using std::sqrt;
std::cout << "Testing type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
std::cout << std::setprecision(std::numeric_limits<Real>::digits10);
Real Q;
Real Q_expected;
@@ -116,13 +123,13 @@ void test_nr_examples()
exp_sinh<Real> integrator(tol, 12);
auto f0 = [](Real) { return (Real) 0; };
Q = integrator.integrate(f0, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f0, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = 0;
BOOST_CHECK_CLOSE_FRACTION(Q, 0.0f, tol);
BOOST_CHECK_CLOSE_FRACTION(L1, 0.0f, tol);
auto f = [](Real x) { return 1/(1+x*x); };
Q = integrator.integrate(f, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = half_pi<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol);
@@ -141,33 +148,33 @@ void test_nr_examples()
return sin(x*half<Real>())*z2;
};
Q = integrator.integrate(f1, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f1, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = sqrt(pi<Real>()*(sqrt((Real) 5) - 2));
// The integrand is oscillatory; the accuracy is low.
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
auto f2 = [](Real x) { return pow(x, -(Real) 2/(Real) 7)*exp(-x*x); };
Q = integrator.integrate(f2, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f2, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = half<Real>()*boost::math::tgamma((Real) 5/ (Real) 14);
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol);
auto f3 = [](Real x) { return (Real) 1/ (sqrt(x)*(1+x)); };
Q = integrator.integrate(f3, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f3, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = pi<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, 10*std::numeric_limits<float>::epsilon());
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, 10*std::numeric_limits<float>::epsilon());
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, 10*boost::math::tools::epsilon<Real>());
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, 10*boost::math::tools::epsilon<Real>());
auto f4 = [](Real t) { return exp(-t*t*half<Real>()); };
Q = integrator.integrate(f4, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f4, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = root_two_pi<Real>()/2;
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol);
auto f5 = [](Real t) { return 1/cosh(t);};
Q = integrator.integrate(f5, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f5, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = half_pi<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol);
@@ -183,7 +190,7 @@ void test_crc()
using std::sqrt;
using std::log;
std::cout << "Testing integral from CRC handbook on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
std::cout << std::setprecision(std::numeric_limits<Real>::digits10);
Real Q;
Real Q_expected;
@@ -192,7 +199,7 @@ void test_crc()
exp_sinh<Real> integrator(tol, 14);
auto f0 = [](Real x) { return log(x)*exp(-x); };
Q = integrator.integrate(f0, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f0, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = -boost::math::constants::euler<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
@@ -205,7 +212,7 @@ void test_crc()
return pow(t, (Real) 12 - 1)*x;
};
Q = integrator.integrate(f1, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f1, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = boost::math::tgamma(12.0f);
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
@@ -219,7 +226,7 @@ void test_crc()
}
return x*cosh(5*t);
};
Q = integrator.integrate(f2, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f2, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = boost::math::cyl_bessel_k<int, Real>(5, 12);
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
// Laplace transform of cos(at)
@@ -235,7 +242,7 @@ void test_crc()
};
// For high oscillation frequency, the quadrature sum is ill-conditioned.
Q = integrator.integrate(f3, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f3, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = s/(a*a+s*s);
// Since the integrand is oscillatory, we increase the tolerance:
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, 100*tol);
@@ -250,12 +257,12 @@ void test_crc()
return boost::math::cyl_bessel_j(0, t)*x;
};
Q = integrator.integrate(f4, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f4, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = 1/sqrt(1+s*s);
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
auto f6 = [](Real t) { return exp(-t*t)*log(t);};
Q = integrator.integrate(f6, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f6, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = -boost::math::constants::root_pi<Real>()*(boost::math::constants::euler<Real>() + 2*ln_two<Real>())/4;
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
}
@@ -263,23 +270,34 @@ void test_crc()
BOOST_AUTO_TEST_CASE(exp_sinh_quadrature_test)
{
test_left_limit_infinite<float>();
#ifdef TEST1
test_left_limit_infinite<float>();
test_left_limit_infinite<double>();
test_left_limit_infinite<long double>();
test_left_limit_infinite<cpp_bin_float_quad>();
test_right_limit_infinite<float>();
test_right_limit_infinite<double>();
test_right_limit_infinite<long double>();
test_right_limit_infinite<cpp_bin_float_quad>();
test_nr_examples<float>();
test_nr_examples<double>();
test_nr_examples<long double>();
//test_nr_examples<cpp_bin_float_quad>();
test_crc<float>();
test_crc<double>();
test_crc<long double>();
//test_crc<cpp_bin_float_quad>();
#endif
#ifdef TEST2
test_left_limit_infinite<cpp_bin_float_quad>();
test_right_limit_infinite<cpp_bin_float_quad>();
test_nr_examples<cpp_bin_float_quad>();
test_crc<cpp_bin_float_quad>();
#endif
#ifdef TEST3
test_left_limit_infinite<boost::math::concepts::real_concept>();
test_right_limit_infinite<boost::math::concepts::real_concept>();
test_nr_examples<boost::math::concepts::real_concept>();
test_crc<boost::math::concepts::real_concept>();
#endif
}

View File

@@ -10,6 +10,7 @@
#include <limits>
#include <functional>
#include <boost/type_index.hpp>
#include <boost/math/concepts/real_concept.hpp>
#include <boost/test/included/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/math/quadrature/sinh_sinh.hpp>
@@ -56,7 +57,7 @@ template<class Real>
void test_nr_examples()
{
std::cout << "Testing type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
std::cout << std::setprecision(std::numeric_limits<Real>::digits10);
Real Q;
Real Q_expected;
@@ -102,7 +103,7 @@ template<class Real>
void test_crc()
{
std::cout << "Testing CRC formulas on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
std::cout << std::setprecision(std::numeric_limits<Real>::digits10);
Real Q;
Real Q_expected;
@@ -141,10 +142,12 @@ BOOST_AUTO_TEST_CASE(sinh_sinh_quadrature_test)
test_nr_examples<float>();
test_nr_examples<double>();
test_nr_examples<long double>();
//test_nr_examples<cpp_bin_float_quad>();
test_nr_examples<cpp_bin_float_quad>();
test_nr_examples<boost::math::concepts::real_concept>();
test_crc<float>();
test_crc<double>();
test_crc<long double>();
//test_crc<cpp_bin_float_quad>();
test_crc<cpp_bin_float_quad>();
test_crc<boost::math::concepts::real_concept>();
}

View File

@@ -10,6 +10,7 @@
#include <limits>
#include <functional>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/math/concepts/real_concept.hpp>
#include <boost/type_index.hpp>
#include <boost/test/included/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
@@ -24,6 +25,10 @@
#include <boost/math/special_functions/ellint_rc.hpp>
#include <boost/math/special_functions/ellint_rj.hpp>
#ifdef _MSC_VER
#pragma warning(disable:4127) // Conditional expression is constant
#endif
#if !defined(TEST1) && !defined(TEST2) && !defined(TEST3) && !defined(TEST4) && !defined(TEST5) && !defined(TEST6)
# define TEST1
# define TEST2
@@ -157,7 +162,7 @@ template<class Real>
void test_detail()
{
std::cout << "Testing tanh_sinh_detail on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
tanh_sinh_detail<Real, boost::math::policies::policy<> > integrator(tol, 20);
auto f = [](Real x) { return x*x; };
Real err;
@@ -172,7 +177,7 @@ template<class Real>
void test_linear()
{
std::cout << "Testing linear functions are integrated properly by tanh_sinh on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = 100*std::numeric_limits<Real>::epsilon();
Real tol = 100*boost::math::tools::epsilon<Real>();
tanh_sinh<Real> integrator(tol, 20);
auto f = [](Real x) { return 5*x + 7; };
Real error;
@@ -187,7 +192,7 @@ template<class Real>
void test_quadratic()
{
std::cout << "Testing quadratic functions are integrated properly by tanh_sinh on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = 100*std::numeric_limits<Real>::epsilon();
Real tol = 100*boost::math::tools::epsilon<Real>();
tanh_sinh<Real> integrator(tol, 20);
auto f = [](Real x) { return 5*x*x + 7*x + 12; };
Real error;
@@ -202,7 +207,7 @@ template<class Real>
void test_singular()
{
std::cout << "Testing integration of endpoint singularities on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = 100*std::numeric_limits<Real>::epsilon();
Real tol = 100*boost::math::tools::epsilon<Real>();
Real error;
Real L1;
tanh_sinh<Real> integrator(tol, 20);
@@ -221,7 +226,7 @@ template<class Real>
void test_ca()
{
std::cout << "Testing integration of C(a) on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
Real error;
Real L1;
@@ -272,13 +277,13 @@ template<class Real>
void test_three_quadrature_schemes_examples()
{
std::cout << "Testing integral in 'A Comparison of Three High Precision Quadrature Schemes' on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
Real Q;
Real Q_expected;
tanh_sinh<Real> integrator(tol, 20);
// Example 1:
auto f1 = [](Real t) { return t*log1p(t); };
auto f1 = [](Real t) { return t*boost::math::log1p(t); };
Q = integrator.integrate(f1, (Real) 0 , (Real) 1);
Q_expected = half<Real>()*half<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
@@ -293,7 +298,7 @@ void test_three_quadrature_schemes_examples()
// Example 3:
auto f3 = [](Real t) { return exp(t)*cos(t); };
Q = integrator.integrate(f3, (Real) 0, half_pi<Real>());
Q_expected = expm1(half_pi<Real>())*half<Real>();
Q_expected = boost::math::expm1(half_pi<Real>())*half<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
// Example 4:
@@ -320,7 +325,7 @@ template<class Real>
void test_integration_over_real_line()
{
std::cout << "Testing integrals over entire real line in 'A Comparison of Three High Precision Quadrature Schemes' on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
Real Q;
Real Q_expected;
Real error;
@@ -328,13 +333,13 @@ void test_integration_over_real_line()
tanh_sinh<Real> integrator(tol, 20);
auto f1 = [](Real t) { return 1/(1+t*t);};
Q = integrator.integrate(f1, -std::numeric_limits<Real>::infinity(), std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f1, std::numeric_limits<Real>::has_infinity ? -std::numeric_limits<Real>::infinity() : -boost::math::tools::max_value<Real>(), std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = pi<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol);
auto f2 = [](Real t) { return exp(-t*t*half<Real>()); };
Q = integrator.integrate(f2, -std::numeric_limits<Real>::infinity(), std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f2, std::numeric_limits<Real>::has_infinity ? -std::numeric_limits<Real>::infinity() : -boost::math::tools::max_value<Real>(), std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = root_two_pi<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol);
@@ -348,7 +353,7 @@ void test_integration_over_real_line()
//BOOST_CHECK_CLOSE(Q, Q_expected, 100*tol);
auto f4 = [](Real t) { return 1/cosh(t);};
Q = integrator.integrate(f4, -std::numeric_limits<Real>::infinity(), std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f4, std::numeric_limits<Real>::has_infinity ? -std::numeric_limits<Real>::infinity() : -boost::math::tools::max_value<Real>(), std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = pi<Real>();
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
BOOST_CHECK_CLOSE_FRACTION(L1, Q_expected, tol);
@@ -359,7 +364,7 @@ template<class Real>
void test_right_limit_infinite()
{
std::cout << "Testing right limit infinite for tanh_sinh in 'A Comparison of Three High Precision Quadrature Schemes' on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
Real Q;
Real Q_expected;
Real error;
@@ -368,23 +373,23 @@ void test_right_limit_infinite()
// Example 11:
auto f1 = [](Real t) { return 1/(1+t*t);};
Q = integrator.integrate(f1, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f1, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = half_pi<Real>();
BOOST_CHECK_CLOSE(Q, Q_expected, 100*tol);
// Example 12
auto f2 = [](Real t) { return exp(-t)/sqrt(t); };
Q = integrator.integrate(f2, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f2, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = root_pi<Real>();
BOOST_CHECK_CLOSE(Q, Q_expected, 1000*tol);
auto f3 = [](Real t) { return exp(-t)*cos(t); };
Q = integrator.integrate(f3, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f3, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = half<Real>();
BOOST_CHECK_CLOSE(Q, Q_expected, 100*tol);
auto f4 = [](Real t) { return 1/(1+t*t); };
Q = integrator.integrate(f4, 1, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f4, 1, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = pi<Real>()/4;
BOOST_CHECK_CLOSE(Q, Q_expected, 100*tol);
}
@@ -393,14 +398,14 @@ template<class Real>
void test_left_limit_infinite()
{
std::cout << "Testing left limit infinite for tanh_sinh in 'A Comparison of Three High Precision Quadrature Schemes' on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
Real Q;
Real Q_expected;
tanh_sinh<Real> integrator;
// Example 11:
auto f1 = [](Real t) { return 1/(1+t*t);};
Q = integrator.integrate(f1, -std::numeric_limits<Real>::infinity(), 0);
Q = integrator.integrate(f1, std::numeric_limits<Real>::has_infinity ? -std::numeric_limits<Real>::infinity() : -boost::math::tools::max_value<Real>(), 0);
Q_expected = half_pi<Real>();
BOOST_CHECK_CLOSE(Q, Q_expected, 100*tol);
}
@@ -432,7 +437,7 @@ template<class Real>
void test_nr_examples()
{
std::cout << "Testing singular integrals from NR 4.5.4 on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
Real Q;
Real Q_expected;
Real error;
@@ -440,12 +445,12 @@ void test_nr_examples()
tanh_sinh<Real> integrator(tol, 15);
auto f1 = [](Real x) { return sin(x*half<Real>())*pow(x, -3*half<Real>())*exp(-x); };
Q = integrator.integrate(f1, 0, std::numeric_limits<Real>::infinity(), &error, &L1);
Q = integrator.integrate(f1, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>(), &error, &L1);
Q_expected = sqrt(pi<Real>()*(sqrt((Real) 5) - 2));
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, 10*tol);
auto f2 = [](Real x) { return pow(x, -(Real) 2/(Real) 7)*exp(-x*x); };
Q = integrator.integrate(f2, 0, std::numeric_limits<Real>::infinity());
Q = integrator.integrate(f2, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>());
Q_expected = half<Real>()*boost::math::tgamma((Real) 5/ (Real) 14);
BOOST_CHECK_CLOSE_FRACTION(Q, Q_expected, tol);
@@ -456,7 +461,7 @@ template<class Real>
void test_early_termination()
{
std::cout << "Testing Clenshaw & Curtis's example of integrand which fools termination schemes on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
Real Q;
Real Q_expected;
Real error;
@@ -475,7 +480,7 @@ template<class Real>
void test_crc()
{
std::cout << "Testing CRC formulas on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
Real Q;
Real Q_expected;
Real error;
@@ -501,7 +506,7 @@ void test_sf()
using std::sqrt;
// Test some special functions that we already know how to evaluate:
std::cout << "Testing special functions on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
Real tol = sqrt(std::numeric_limits<Real>::epsilon());
Real tol = sqrt(boost::math::tools::epsilon<Real>());
tanh_sinh<Real> integrator;
// incomplete beta:
if (std::numeric_limits<Real>::digits < 120) // Otherwise too slow
@@ -510,15 +515,15 @@ void test_sf()
}
Real x = 2, y = 3, z = 0.5, p = 0.25;
// This one has much larger (10^-9) error than exp_sinh quadrature:
//BOOST_CHECK_CLOSE_FRACTION(integrator.integrate([&](Real t) { return 1 / (sqrt(t + x) * (t + y)); }, 0, std::numeric_limits<Real>::infinity()) / 2, boost::math::ellint_rc(x, y), tol);
// This one has a higher than expected error rate, even though exp_sinh quadrature is just fine:
//BOOST_CHECK_CLOSE_FRACTION(integrator.integrate([&](Real t) { return 1 / (sqrt(t + x) * (t + y)); }, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>()) / 2, boost::math::ellint_rc(x, y), tol);
BOOST_CHECK_CLOSE_FRACTION((Real(3) / 2) * integrator.integrate([&](Real t) { return 1 / (sqrt((t + x) * (t + y) * (t + z)) * (t + p)); }, 0, std::numeric_limits<Real>::infinity()), boost::math::ellint_rj(x, y, z, p), tol);
BOOST_CHECK_CLOSE_FRACTION((Real(3) / 2) * integrator.integrate([&](Real t) { return 1 / (sqrt((t + x) * (t + y) * (t + z)) * (t + p)); }, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>()), boost::math::ellint_rj(x, y, z, p), tol);
z = 5.5;
BOOST_CHECK_CLOSE_FRACTION(integrator.integrate([&](Real t) { using std::pow; using std::exp; return t > 10000 ? 0 : pow(t, z - 1) * exp(-t); }, 0, std::numeric_limits<Real>::infinity()),
BOOST_CHECK_CLOSE_FRACTION(integrator.integrate([&](Real t) { using std::pow; using std::exp; return t > 10000 ? 0 : pow(t, z - 1) * exp(-t); }, 0, std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>()),
boost::math::tgamma(z), tol);
BOOST_CHECK_CLOSE_FRACTION(integrator.integrate([](Real t) { using std::exp; return exp(-t*t); }, -std::numeric_limits<Real>::infinity(), std::numeric_limits<Real>::infinity()),
BOOST_CHECK_CLOSE_FRACTION(integrator.integrate([](Real t) { using std::exp; return exp(-t*t); }, std::numeric_limits<Real>::has_infinity ? -std::numeric_limits<Real>::infinity() : -boost::math::tools::max_value<Real>(), std::numeric_limits<Real>::has_infinity ? std::numeric_limits<Real>::infinity() : boost::math::tools::max_value<Real>()),
boost::math::constants::root_pi<Real>(), tol);
}
@@ -603,8 +608,20 @@ BOOST_AUTO_TEST_CASE(tanh_sinh_quadrature_test)
#endif
#ifdef TEST6
//test_linear<cpp_dec_float_100>();
//test_quadratic<cpp_dec_float_100>();
test_detail<boost::math::concepts::real_concept>();
test_right_limit_infinite<boost::math::concepts::real_concept>();
test_left_limit_infinite<boost::math::concepts::real_concept>();
test_linear<boost::math::concepts::real_concept>();
test_quadratic<boost::math::concepts::real_concept>();
test_singular<boost::math::concepts::real_concept>();
test_ca<boost::math::concepts::real_concept>();
test_three_quadrature_schemes_examples<boost::math::concepts::real_concept>();
test_horrible<boost::math::concepts::real_concept>();
test_integration_over_real_line<boost::math::concepts::real_concept>();
test_nr_examples<boost::math::concepts::real_concept>();
test_early_termination<boost::math::concepts::real_concept>();
test_crc<boost::math::concepts::real_concept>();
test_sf<boost::math::concepts::real_concept>();
#endif
}