| // Copyright John Maddock 2009 |
| |
| // 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) |
| |
| #include <cmath> |
| #include <math.h> |
| #include <limits.h> |
| |
| #include <boost/test/test_exec_monitor.hpp> // Boost.Test |
| #include <boost/test/results_collector.hpp> |
| #include <boost/test/unit_test.hpp> |
| #include <boost/test/floating_point_comparison.hpp> |
| |
| #include <iostream> |
| #include <iomanip> |
| using std::cout; |
| using std::endl; |
| using std::setprecision; |
| |
| #include <boost/array.hpp> |
| #include "functor.hpp" |
| #include "handle_test_result.hpp" |
| |
| #include <boost/math/tools/config.hpp> |
| |
| void expected_results() |
| { |
| // |
| // Define the max and mean errors expected for |
| // various compilers and platforms. |
| // |
| const char* largest_type; |
| largest_type = "(long\\s+)?double"; |
| |
| add_expected_result( |
| ".*", // compiler |
| ".*", // stdlib |
| ".*", // platform |
| largest_type, // test type(s) |
| ".*", // test data group |
| ".*", 50, 20); // test function |
| } |
| |
| template <class A> |
| void do_test_std_function(const A& data, const char* type_name, const char* function_name, const char* test_name, long double (*proc)(long double), const char* inv_function_name = 0, long double (*inv_proc)(long double) = 0) |
| { |
| // warning suppression: |
| (void)data; |
| (void)type_name; |
| (void)test_name; |
| typedef typename A::value_type row_type; |
| typedef typename row_type::value_type value_type; |
| |
| boost::math::tools::test_result<value_type> result; |
| |
| // |
| // test against data: |
| // |
| result = boost::math::tools::test( |
| data, |
| bind_func(proc, 0), |
| extract_result(1)); |
| handle_test_result(result, data[result.worst()], result.worst(), type_name, function_name, test_name); |
| if(inv_proc) |
| { |
| result = boost::math::tools::test( |
| data, |
| bind_func(inv_proc, 1), |
| extract_result(0)); |
| handle_test_result(result, data[result.worst()], result.worst(), type_name, inv_function_name, test_name); |
| } |
| } |
| |
| |
| void test_spots() |
| { |
| // Basic sanity checks. |
| // Test data taken from functions.wolfram.com |
| long double (*unary_proc)(long double); |
| long double (*inv_unary_proc)(long double); |
| // |
| // COS: |
| // |
| boost::array<boost::array<long double, 2>, 4> cos_test_data = { |
| 0, 1, |
| 0.125L, 0.992197667229329053149096907788250869543327304736601263468910L, |
| 1.125L, 0.431176516798666176551969042921689826840697850225767471037314L, |
| 1.75L, -0.178246055649492090382676943942631358969920851291548272886063L, |
| }; |
| unary_proc = std::cos; |
| inv_unary_proc = std::acos; |
| do_test_std_function(cos_test_data, "long double", "std::cos", "Mathematica data", unary_proc, "std::acos", inv_unary_proc); |
| unary_proc = ::cosl; |
| inv_unary_proc = ::acosl; |
| do_test_std_function(cos_test_data, "long double", "::cosl", "Mathematica data", unary_proc, "::acosl", inv_unary_proc); |
| // |
| // SIN: |
| // |
| boost::array<boost::array<long double, 2>, 6> sin_test_data = { |
| 0, 0, |
| 0.125L, 0.124674733385227689957442708712108467587834905641679257885515L, |
| -0.125L, -0.124674733385227689957442708712108467587834905641679257885515L, |
| 1.125L, 0.902267594099095162918416128654829100758989018716070814389152L, |
| 1e-500L, 1e-500L, |
| 1e-1500L, 1e-1500L, |
| }; |
| unary_proc = std::sin; |
| inv_unary_proc = std::asin; |
| do_test_std_function(sin_test_data, "long double", "std::sin", "Mathematica data", unary_proc, "std::asin", inv_unary_proc); |
| unary_proc = ::sinl; |
| inv_unary_proc = ::asinl; |
| do_test_std_function(sin_test_data, "long double", "::sinl", "Mathematica data", unary_proc, "::asinl", inv_unary_proc); |
| // |
| // TAN: |
| // |
| boost::array<boost::array<long double, 2>, 7> tan_test_data = { |
| 0, 0, |
| 0.125L, 0.125655136575130967792678218629774000758665763892225542668867L, |
| -0.125L, -0.125655136575130967792678218629774000758665763892225542668867L, |
| 1.125L, 2.09257127637217900442373398123488678225994171614872057291399L, |
| 1e-500L, 1e-500L, |
| 1e-1500L, 1e-1500L, |
| #if LDBL_MAX_EXP > DBL_MAX_EXP |
| 1.57079632679489661923132169163975144209858469968755291048747L, 1e500L, |
| #else |
| 0, 0, |
| #endif |
| }; |
| unary_proc = std::tan; |
| inv_unary_proc = std::atan; |
| do_test_std_function(tan_test_data, "long double", "std::tan", "Mathematica data", unary_proc, "std::atan", inv_unary_proc); |
| unary_proc = ::tanl; |
| inv_unary_proc = ::atanl; |
| do_test_std_function(tan_test_data, "long double", "::tanl", "Mathematica data", unary_proc, "::atanl", inv_unary_proc); |
| // |
| // EXP: |
| // |
| boost::array<boost::array<long double, 2>, 16> exp_test_data = { |
| 0, 1, |
| 0.125L, 1.13314845306682631682900722781179387256550313174518162591282L, |
| -0.125L, 0.882496902584595402864892143229050736222004824990650741770309L, |
| 1.125L, 3.08021684891803124500466787877703957705899375982613074033239L, |
| 4.60517018598809136803598290936872841520220297725754595206666L, 100L, |
| 23.0258509299404568401799145468436420760110148862877297603333L, 1e10L, |
| 230.258509299404568401799145468436420760110148862877297603333L, 1e100L, |
| -230.258509299404568401799145468436420760110148862877297603333L, 1e-100L, |
| -23.0258509299404568401799145468436420760110148862877297603333L, 1e-10L, |
| -4.60517018598809136803598290936872841520220297725754595206666L, 0.01L, |
| #if LDBL_MAX_EXP > DBL_MAX_EXP |
| 1151.29254649702284200899572734218210380055074431438648801666L, 1e500L, |
| 2302.58509299404568401799145468436420760110148862877297603333L, 1e1000L, |
| 11351.7445084606452222086978715939155434734303389398507718443L, 1e4930L, |
| -11351.7445084606452222086978715939155434734303389398507718443L, 1e-4930L, |
| -2302.58509299404568401799145468436420760110148862877297603333L, 1e-1000L, |
| -1151.29254649702284200899572734218210380055074431438648801666L, 1e-500L, |
| #else |
| 0, 1, |
| 0, 1, |
| 0, 1, |
| 0, 1, |
| 0, 1, |
| 0, 1, |
| #endif |
| }; |
| unary_proc = std::exp; |
| inv_unary_proc = std::log; |
| do_test_std_function(exp_test_data, "long double", "std::exp", "Mathematica data", unary_proc, "std::log", inv_unary_proc); |
| unary_proc = ::expl; |
| inv_unary_proc = ::logl; |
| do_test_std_function(exp_test_data, "long double", "::expl", "Mathematica data", unary_proc, "::logl", inv_unary_proc); |
| // |
| // SQRT: |
| // |
| boost::array<boost::array<long double, 2>, 8> sqrt_test_data = { |
| 1, 1, |
| 0.125L, 0.353553390593273762200422181052424519642417968844237018294170L, |
| 1.125L, 1.06066017177982128660126654315727355892725390653271105488251L, |
| 1e10L, 1e5L, |
| 1e100L, 1e50L, |
| #if LDBL_MAX_EXP > DBL_MAX_EXP |
| 1e500L, 1e250L, |
| 1e1000L, 1e500L, |
| 1e4930L, 1e2465L |
| #else |
| 1, 1, |
| 1, 1, |
| 1, 1, |
| #endif |
| }; |
| unary_proc = std::sqrt; |
| inv_unary_proc = 0; |
| do_test_std_function(sqrt_test_data, "long double", "std::sqrt", "Mathematica data", unary_proc, "", inv_unary_proc); |
| unary_proc = ::sqrtl; |
| do_test_std_function(sqrt_test_data, "long double", "::sqrtl", "Mathematica data", unary_proc, "", inv_unary_proc); |
| } |
| |
| |
| int test_main(int, char* []) |
| { |
| expected_results(); |
| std::cout << "Running tests with BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS " |
| #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS |
| "defined." |
| #else |
| "not defined." |
| #endif |
| << std::endl; |
| // Basic sanity-check spot values. |
| // (Parameter value, arbitrarily zero, only communicates the floating point type). |
| test_spots(); // Test long double. |
| |
| return 0; |
| } // int test_main(int, char* []) |
| |