// unit test file atanh.hpp for the special functions test suite // (C) Copyright Hubert Holin 2003. // Distributed under 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 #include //#include #define BOOST_TEST_MAiN #include #include template T atanh_error_evaluator(T x) { using ::std::abs; using ::std::tanh; using ::std::cosh; using ::std::numeric_limits; using ::boost::math::atanh; static T const epsilon = numeric_limits::epsilon(); T y = tanh(x); T z = atanh(y); T absolute_error = abs(z-x); T relative_error = absolute_error/(cosh(x)*cosh(x)); T scaled_error = relative_error/epsilon; return(scaled_error); } BOOST_TEST_CASE_TEMPLATE_FUNCTION(atanh_test, T) { using ::std::abs; using ::std::tanh; using ::std::log; using ::std::numeric_limits; using ::boost::math::atanh; BOOST_TEST_MESSAGE("Testing atanh in the real domain for " << string_type_name::_() << "."); BOOST_CHECK_PREDICATE(::std::less_equal(), (abs(atanh(static_cast(0)))) (numeric_limits::epsilon())); BOOST_CHECK_PREDICATE(::std::less_equal(), (abs(atanh(static_cast(3)/5) - log(static_cast(2)))) (numeric_limits::epsilon())); BOOST_CHECK_PREDICATE(::std::less_equal(), (abs(atanh(static_cast(-3)/5) + log(static_cast(2)))) (numeric_limits::epsilon())); for (int i = 0; i <= 100; i++) { T x = static_cast(i-50)/static_cast(5); T y = tanh(x); if ( (abs(y-static_cast(1)) >= numeric_limits::epsilon())&& (abs(y+static_cast(1)) >= numeric_limits::epsilon()) ) { BOOST_CHECK_PREDICATE(::std::less_equal(), (atanh_error_evaluator(x)) (static_cast(4))); } } // // Error handling checks: // BOOST_MATH_CHECK_THROW(atanh(T(-1)), std::overflow_error); BOOST_MATH_CHECK_THROW(atanh(T(1)), std::overflow_error); BOOST_MATH_CHECK_THROW(atanh(T(-2)), std::domain_error); BOOST_MATH_CHECK_THROW(atanh(T(2)), std::domain_error); } void atanh_manual_check() { using ::std::abs; using ::std::tanh; using ::std::numeric_limits; BOOST_TEST_MESSAGE(" "); BOOST_TEST_MESSAGE("atanh"); for (int i = 0; i <= 100; i++) { float xf = static_cast(i-50)/static_cast(5); double xd = static_cast(i-50)/static_cast(5); long double xl = static_cast(i-50)/static_cast(5); float yf = tanh(xf); double yd = tanh(xd); (void) &yd; // avoid "unused variable" warning long double yl = tanh(xl); (void) &yl; // avoid "unused variable" warning if ( std::numeric_limits::has_infinity && std::numeric_limits::has_infinity && std::numeric_limits::has_infinity ) { #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS BOOST_TEST_MESSAGE( ::std::setw(15) << atanh_error_evaluator(xf) << ::std::setw(15) << atanh_error_evaluator(xd) << ::std::setw(15) << atanh_error_evaluator(xl)); #else BOOST_TEST_MESSAGE( ::std::setw(15) << atanh_error_evaluator(xf) << ::std::setw(15) << atanh_error_evaluator(xd)); #endif } else { if ( (abs(yf-static_cast(1)) < numeric_limits::epsilon())|| (abs(yf+static_cast(1)) < numeric_limits::epsilon())|| (abs(yf-static_cast(1)) < numeric_limits::epsilon())|| (abs(yf+static_cast(1)) < numeric_limits::epsilon())|| (abs(yf-static_cast(1)) < numeric_limits::epsilon())|| (abs(yf+static_cast(1)) < numeric_limits::epsilon()) ) { BOOST_TEST_MESSAGE("Platform's numerics may lack precision."); } else { #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS BOOST_TEST_MESSAGE( ::std::setw(15) << atanh_error_evaluator(xf) << ::std::setw(15) << atanh_error_evaluator(xd) << ::std::setw(15) << atanh_error_evaluator(xl)); #else BOOST_TEST_MESSAGE( ::std::setw(15) << atanh_error_evaluator(xf) << ::std::setw(15) << atanh_error_evaluator(xd)); #endif } } } BOOST_TEST_MESSAGE(" "); }