Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / math / special_functions / acosh.hpp
1 //    boost asinh.hpp header file
2
3 //  (C) Copyright Eric Ford 2001 & Hubert Holin.
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 // See http://www.boost.org for updates, documentation, and revision history.
9
10 #ifndef BOOST_ACOSH_HPP
11 #define BOOST_ACOSH_HPP
12
13
14 #include <cmath>
15 #include <limits>
16 #include <string>
17 #include <stdexcept>
18
19
20 #include <boost/config.hpp>
21
22
23 // This is the inverse of the hyperbolic cosine function.
24
25 namespace boost
26 {
27     namespace math
28     {
29 #if defined(__GNUC__) && (__GNUC__ < 3)
30         // gcc 2.x ignores function scope using declarations,
31         // put them in the scope of the enclosing namespace instead:
32         
33         using    ::std::abs;
34         using    ::std::sqrt;
35         using    ::std::log;
36         
37         using    ::std::numeric_limits;
38 #endif
39         
40 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
41         // This is the main fare
42         
43         template<typename T>
44         inline T    acosh(const T x)
45         {
46             using    ::std::abs;
47             using    ::std::sqrt;
48             using    ::std::log;
49             
50             using    ::std::numeric_limits;
51             
52             
53             T const    one = static_cast<T>(1);
54             T const    two = static_cast<T>(2);
55             
56             static T const    taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
57             static T const    taylor_n_bound = sqrt(taylor_2_bound);
58             static T const    upper_taylor_2_bound = one/taylor_2_bound;
59             
60             if        (x < one)
61             {
62                 if    (numeric_limits<T>::has_quiet_NaN)
63                 {
64                     return(numeric_limits<T>::quiet_NaN());
65                 }
66                 else
67                 {
68                     ::std::string        error_reporting("Argument to atanh is strictly greater than +1 or strictly smaller than -1!");
69                     ::std::domain_error  bad_argument(error_reporting);
70                     
71                     throw(bad_argument);
72                 }
73             }
74             else if    (x >= taylor_n_bound)
75             {
76                 if    (x > upper_taylor_2_bound)
77                 {
78                     // approximation by laurent series in 1/x at 0+ order from -1 to 0
79                     return( log( x*two) );
80                 }
81                 else
82                 {
83                     return( log( x + sqrt(x*x-one) ) );
84                 }
85             }
86             else
87             {
88                 T    y = sqrt(x-one);
89                 
90                 // approximation by taylor series in y at 0 up to order 2
91                 T    result = y;
92                 
93                 if    (y >= taylor_2_bound)
94                 {
95                     T    y3 = y*y*y;
96                     
97                     // approximation by taylor series in y at 0 up to order 4
98                     result -= y3/static_cast<T>(12);
99                 }
100                 
101                 return(sqrt(static_cast<T>(2))*result);
102             }
103         }
104 #else
105         // These are implementation details (for main fare see below)
106         
107         namespace detail
108         {
109             template    <
110                             typename T,
111                             bool QuietNanSupported
112                         >
113             struct    acosh_helper2_t
114             {
115                 static T    get_NaN()
116                 {
117                     return(::std::numeric_limits<T>::quiet_NaN());
118                 }
119             };  // boost::detail::acosh_helper2_t
120             
121             
122             template<typename T>
123             struct    acosh_helper2_t<T, false>
124             {
125                 static T    get_NaN()
126                 {
127                     ::std::string        error_reporting("Argument to acosh is greater than or equal to +1!");
128                     ::std::domain_error  bad_argument(error_reporting);
129                     
130                     throw(bad_argument);
131                 }
132             };  // boost::detail::acosh_helper2_t
133         
134         }  // boost::detail
135         
136         
137         // This is the main fare
138         
139         template<typename T>
140         inline T    acosh(const T x)
141         {
142             using    ::std::abs;
143             using    ::std::sqrt;
144             using    ::std::log;
145             
146             using    ::std::numeric_limits;
147             
148             typedef    detail::acosh_helper2_t<T, std::numeric_limits<T>::has_quiet_NaN>    helper2_type;
149             
150             
151             T const    one = static_cast<T>(1);
152             T const    two = static_cast<T>(2);
153             
154             static T const    taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
155             static T const    taylor_n_bound = sqrt(taylor_2_bound);
156             static T const    upper_taylor_2_bound = one/taylor_2_bound;
157             
158             if        (x < one)
159             {
160                 return(helper2_type::get_NaN());
161             }
162             else if    (x >= taylor_n_bound)
163             {
164                 if    (x > upper_taylor_2_bound)
165                 {
166                     // approximation by laurent series in 1/x at 0+ order from -1 to 0
167                     return( log( x*two) );
168                 }
169                 else
170                 {
171                     return( log( x + sqrt(x*x-one) ) );
172                 }
173             }
174             else
175             {
176                 T    y = sqrt(x-one);
177                 
178                 // approximation by taylor series in y at 0 up to order 2
179                 T    result = y;
180                 
181                 if    (y >= taylor_2_bound)
182                 {
183                     T    y3 = y*y*y;
184                     
185                     // approximation by taylor series in y at 0 up to order 4
186                     result -= y3/static_cast<T>(12);
187                 }
188                 
189                 return(sqrt(static_cast<T>(2))*result);
190             }
191         }
192 #endif /* defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) */
193     }
194 }
195
196 #endif /* BOOST_ACOSH_HPP */
197
198