Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / math / test / atanh_test.hpp
1 // unit test file atanh.hpp for the special functions test suite
2
3 //  (C) Copyright Hubert Holin 2003.
4 //  Distributed under the Boost Software License, Version 1.0. (See
5 //  accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7
8
9 #include <functional>
10 #include <iomanip>
11 //#include <iostream>
12
13 #define BOOST_TEST_MAiN
14 #include <boost/math/special_functions/atanh.hpp>
15
16
17 #include <boost/test/unit_test.hpp>
18
19 template<typename T>
20 T    atanh_error_evaluator(T x)
21 {
22     using    ::std::abs;
23     using    ::std::tanh;
24     using    ::std::cosh;
25         
26     using    ::std::numeric_limits;
27     
28     using    ::boost::math::atanh;
29     
30     
31     static T const   epsilon = numeric_limits<float>::epsilon();
32     
33     T                y = tanh(x);
34     T                z = atanh(y);
35     
36     T                absolute_error = abs(z-x);
37     T                relative_error = absolute_error/(cosh(x)*cosh(x));
38     T                scaled_error = relative_error/epsilon;
39     
40     return(scaled_error);
41 }
42
43
44 BOOST_TEST_CASE_TEMPLATE_FUNCTION(atanh_test, T)
45 {
46     using    ::std::abs;
47     using    ::std::tanh;
48     using    ::std::log;
49         
50     using    ::std::numeric_limits;
51     
52     using    ::boost::math::atanh;
53     
54     
55     BOOST_TEST_MESSAGE("Testing atanh in the real domain for "
56         << string_type_name<T>::_() << ".");
57     
58     BOOST_CHECK_PREDICATE(::std::less_equal<T>(),
59         (abs(atanh<T>(static_cast<T>(0))))
60         (numeric_limits<T>::epsilon()));
61     
62     BOOST_CHECK_PREDICATE(::std::less_equal<T>(),
63         (abs(atanh<T>(static_cast<T>(3)/5) - log(static_cast<T>(2))))
64         (numeric_limits<T>::epsilon()));
65     
66     BOOST_CHECK_PREDICATE(::std::less_equal<T>(),
67         (abs(atanh<T>(static_cast<T>(-3)/5) + log(static_cast<T>(2))))
68         (numeric_limits<T>::epsilon()));
69     
70     for    (int i = 0; i <= 100; i++)
71     {
72         T    x = static_cast<T>(i-50)/static_cast<T>(5);
73         T    y = tanh(x);
74         
75         if    (
76                 (abs(y-static_cast<T>(1)) >= numeric_limits<T>::epsilon())&&
77                 (abs(y+static_cast<T>(1)) >= numeric_limits<T>::epsilon())
78             )
79         {
80             BOOST_CHECK_PREDICATE(::std::less_equal<T>(),
81                 (atanh_error_evaluator(x))
82                 (static_cast<T>(4)));
83         }
84     }
85     //
86     // Error handling checks:
87     //
88     BOOST_CHECK_THROW(atanh(T(-1)), std::overflow_error);
89     BOOST_CHECK_THROW(atanh(T(1)), std::overflow_error);
90     BOOST_CHECK_THROW(atanh(T(-2)), std::domain_error);
91     BOOST_CHECK_THROW(atanh(T(2)), std::domain_error);
92 }
93
94
95 void    atanh_manual_check()
96 {
97     using    ::std::abs;
98     using    ::std::tanh;
99         
100     using    ::std::numeric_limits;
101     
102     
103     BOOST_TEST_MESSAGE(" ");
104     BOOST_TEST_MESSAGE("atanh");
105     
106     for    (int i = 0; i <= 100; i++)
107     {
108         float        xf = static_cast<float>(i-50)/static_cast<float>(5);
109         double       xd = static_cast<double>(i-50)/static_cast<double>(5);
110         long double  xl =
111                 static_cast<long double>(i-50)/static_cast<long double>(5);
112         
113         float        yf = tanh(xf);
114         double       yd = tanh(xd);
115         (void) &yd;        // avoid "unused variable" warning
116         long double  yl = tanh(xl);
117         (void) &yl;        // avoid "unused variable" warning
118         
119         if    (
120                 std::numeric_limits<float>::has_infinity &&
121                 std::numeric_limits<double>::has_infinity &&
122                 std::numeric_limits<long double>::has_infinity
123             )
124         {
125 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
126             BOOST_TEST_MESSAGE( ::std::setw(15)
127                         << atanh_error_evaluator(xf)
128                         << ::std::setw(15)
129                         << atanh_error_evaluator(xd)
130                         << ::std::setw(15)
131                         << atanh_error_evaluator(xl));
132 #else
133             BOOST_TEST_MESSAGE( ::std::setw(15)
134                         << atanh_error_evaluator(xf)
135                         << ::std::setw(15)
136                         << atanh_error_evaluator(xd));
137 #endif
138         }
139         else
140         {
141             if    (
142                     (abs(yf-static_cast<float>(1)) <
143                         numeric_limits<float>::epsilon())||
144                     (abs(yf+static_cast<float>(1)) <
145                         numeric_limits<float>::epsilon())||
146                     (abs(yf-static_cast<double>(1)) <
147                         numeric_limits<double>::epsilon())||
148                     (abs(yf+static_cast<double>(1)) <
149                         numeric_limits<double>::epsilon())||
150                     (abs(yf-static_cast<long double>(1)) <
151                         numeric_limits<long double>::epsilon())||
152                     (abs(yf+static_cast<long double>(1)) <
153                         numeric_limits<long double>::epsilon())
154                 )
155             {
156                 BOOST_TEST_MESSAGE("Platform's numerics may lack precision.");
157             }
158             else
159             {
160 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
161                 BOOST_TEST_MESSAGE( ::std::setw(15)
162                             << atanh_error_evaluator(xf)
163                             << ::std::setw(15)
164                             << atanh_error_evaluator(xd)
165                             << ::std::setw(15)
166                             << atanh_error_evaluator(xl));
167 #else
168                 BOOST_TEST_MESSAGE( ::std::setw(15)
169                             << atanh_error_evaluator(xf)
170                             << ::std::setw(15)
171                             << atanh_error_evaluator(xd));
172 #endif
173             }
174         }
175     }
176     
177     BOOST_TEST_MESSAGE(" ");
178 }
179