// 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 <functional>
#include <iomanip>
//#include <iostream>


#include <boost/math/special_functions/atanh.hpp>


#include <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>

template<typename T>
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<float>::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_MESSAGE("Testing atanh in the real domain for "
        << string_type_name<T>::_() << ".");
    
    BOOST_CHECK_PREDICATE(::std::less_equal<T>(),
        (abs(atanh<T>(static_cast<T>(0))))
        (numeric_limits<T>::epsilon()));
    
    BOOST_CHECK_PREDICATE(::std::less_equal<T>(),
        (abs(atanh<T>(static_cast<T>(3)/5) - log(static_cast<T>(2))))
        (numeric_limits<T>::epsilon()));
    
    BOOST_CHECK_PREDICATE(::std::less_equal<T>(),
        (abs(atanh<T>(static_cast<T>(-3)/5) + log(static_cast<T>(2))))
        (numeric_limits<T>::epsilon()));
    
    for    (int i = 0; i <= 100; i++)
    {
        T    x = static_cast<T>(i-50)/static_cast<T>(5);
        T    y = tanh(x);
        
        if    (
                (abs(y-static_cast<T>(1)) >= numeric_limits<T>::epsilon())&&
                (abs(y+static_cast<T>(1)) >= numeric_limits<T>::epsilon())
            )
        {
            BOOST_CHECK_PREDICATE(::std::less_equal<T>(),
                (atanh_error_evaluator(x))
                (static_cast<T>(4)));
        }
    }
}


void    atanh_manual_check()
{
    using    ::std::abs;
    using    ::std::tanh;
        
    using    ::std::numeric_limits;
    
    
    BOOST_MESSAGE(" ");
    BOOST_MESSAGE("atanh");
    
    for    (int i = 0; i <= 100; i++)
    {
        float        xf = static_cast<float>(i-50)/static_cast<float>(5);
        double       xd = static_cast<double>(i-50)/static_cast<double>(5);
        long double  xl =
                static_cast<long double>(i-50)/static_cast<long double>(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<float>::has_infinity &&
                std::numeric_limits<double>::has_infinity &&
                std::numeric_limits<long double>::has_infinity
            )
        {
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
            BOOST_MESSAGE( ::std::setw(15)
                        << atanh_error_evaluator(xf)
                        << ::std::setw(15)
                        << atanh_error_evaluator(xd)
                        << ::std::setw(15)
                        << atanh_error_evaluator(xl));
#else
            BOOST_MESSAGE( ::std::setw(15)
                        << atanh_error_evaluator(xf)
                        << ::std::setw(15)
                        << atanh_error_evaluator(xd));
#endif
        }
        else
        {
            if    (
                    (abs(yf-static_cast<float>(1)) <
                        numeric_limits<float>::epsilon())||
                    (abs(yf+static_cast<float>(1)) <
                        numeric_limits<float>::epsilon())||
                    (abs(yf-static_cast<double>(1)) <
                        numeric_limits<double>::epsilon())||
                    (abs(yf+static_cast<double>(1)) <
                        numeric_limits<double>::epsilon())||
                    (abs(yf-static_cast<long double>(1)) <
                        numeric_limits<long double>::epsilon())||
                    (abs(yf+static_cast<long double>(1)) <
                        numeric_limits<long double>::epsilon())
                )
            {
                BOOST_MESSAGE("Platform's numerics may lack precision.");
            }
            else
            {
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
                BOOST_MESSAGE( ::std::setw(15)
                            << atanh_error_evaluator(xf)
                            << ::std::setw(15)
                            << atanh_error_evaluator(xd)
                            << ::std::setw(15)
                            << atanh_error_evaluator(xl));
#else
                BOOST_MESSAGE( ::std::setw(15)
                            << atanh_error_evaluator(xf)
                            << ::std::setw(15)
                            << atanh_error_evaluator(xd));
#endif
            }
        }
    }
    
    BOOST_MESSAGE(" ");
}

