1 // boost asinh.hpp header file |
1 // (C) Copyright John Maddock 2005. |
|
2 // Use, modification and distribution are subject to the |
|
3 // Boost Software License, Version 1.0. (See accompanying file |
|
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
2 |
5 |
3 // (C) Copyright Eric Ford & Hubert Holin 2001. |
6 #ifndef BOOST_MATH_COMPLEX_ASINH_INCLUDED |
4 // Distributed under the Boost Software License, Version 1.0. (See |
7 #define BOOST_MATH_COMPLEX_ASINH_INCLUDED |
5 // accompanying file LICENSE_1_0.txt or copy at |
|
6 // http://www.boost.org/LICENSE_1_0.txt) |
|
7 |
8 |
8 // See http://www.boost.org for updates, documentation, and revision history. |
9 #ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED |
|
10 # include <boost/math/complex/details.hpp> |
|
11 #endif |
|
12 #ifndef BOOST_MATH_COMPLEX_ASINH_INCLUDED |
|
13 # include <boost/math/complex/asinh.hpp> |
|
14 #endif |
9 |
15 |
10 #ifndef BOOST_ASINH_HPP |
16 namespace boost{ namespace math{ |
11 #define BOOST_ASINH_HPP |
|
12 |
17 |
13 |
18 template<class T> |
14 #include <cmath> |
19 inline std::complex<T> asinh(const std::complex<T>& x) |
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 sine function. |
|
24 |
|
25 namespace boost |
|
26 { |
20 { |
27 namespace math |
21 // |
28 { |
22 // We use asinh(z) = i asin(-i z); |
29 #if defined(__GNUC__) && (__GNUC__ < 3) |
23 // Note that C99 defines this the other way around (which is |
30 // gcc 2.x ignores function scope using declarations, |
24 // to say asin is specified in terms of asinh), this is consistent |
31 // put them in the scope of the enclosing namespace instead: |
25 // with C99 though: |
32 |
26 // |
33 using ::std::abs; |
27 return ::boost::math::detail::mult_i(::boost::math::asin(::boost::math::detail::mult_minus_i(x))); |
34 using ::std::sqrt; |
|
35 using ::std::log; |
|
36 |
|
37 using ::std::numeric_limits; |
|
38 #endif |
|
39 |
|
40 template<typename T> |
|
41 inline T asinh(const T x) |
|
42 { |
|
43 using ::std::abs; |
|
44 using ::std::sqrt; |
|
45 using ::std::log; |
|
46 |
|
47 using ::std::numeric_limits; |
|
48 |
|
49 |
|
50 T const one = static_cast<T>(1); |
|
51 T const two = static_cast<T>(2); |
|
52 |
|
53 static T const taylor_2_bound = sqrt(numeric_limits<T>::epsilon()); |
|
54 static T const taylor_n_bound = sqrt(taylor_2_bound); |
|
55 static T const upper_taylor_2_bound = one/taylor_2_bound; |
|
56 static T const upper_taylor_n_bound = one/taylor_n_bound; |
|
57 |
|
58 if (x >= +taylor_n_bound) |
|
59 { |
|
60 if (x > upper_taylor_n_bound) |
|
61 { |
|
62 if (x > upper_taylor_2_bound) |
|
63 { |
|
64 // approximation by laurent series in 1/x at 0+ order from -1 to 0 |
|
65 return( log( x * two) ); |
|
66 } |
|
67 else |
|
68 { |
|
69 // approximation by laurent series in 1/x at 0+ order from -1 to 1 |
|
70 return( log( x*two + (one/(x*two)) ) ); |
|
71 } |
|
72 } |
|
73 else |
|
74 { |
|
75 return( log( x + sqrt(x*x+one) ) ); |
|
76 } |
|
77 } |
|
78 else if (x <= -taylor_n_bound) |
|
79 { |
|
80 return(-asinh(-x)); |
|
81 } |
|
82 else |
|
83 { |
|
84 // approximation by taylor series in x at 0 up to order 2 |
|
85 T result = x; |
|
86 |
|
87 if (abs(x) >= taylor_2_bound) |
|
88 { |
|
89 T x3 = x*x*x; |
|
90 |
|
91 // approximation by taylor series in x at 0 up to order 4 |
|
92 result -= x3/static_cast<T>(6); |
|
93 } |
|
94 |
|
95 return(result); |
|
96 } |
|
97 } |
|
98 } |
|
99 } |
28 } |
100 |
29 |
101 #endif /* BOOST_ASINH_HPP */ |
30 } } // namespaces |
|
31 |
|
32 #endif // BOOST_MATH_COMPLEX_ASINH_INCLUDED |