Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
1 // boost atanh.hpp header file
3 // (C) Copyright Hubert Holin 2001.
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)
8 // See http://www.boost.org for updates, documentation, and revision history.
10 #ifndef BOOST_ATANH_HPP
11 #define BOOST_ATANH_HPP
20 #include <boost/config.hpp>
23 // This is the inverse of the hyperbolic tangent function.
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:
37 using ::std::numeric_limits;
40 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
41 // This is the main fare
44 inline T atanh(const T x)
50 using ::std::numeric_limits;
52 T const one = static_cast<T>(1);
53 T const two = static_cast<T>(2);
55 static T const taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
56 static T const taylor_n_bound = sqrt(taylor_2_bound);
60 if (numeric_limits<T>::has_quiet_NaN)
62 return(numeric_limits<T>::quiet_NaN());
66 ::std::string error_reporting("Argument to atanh is strictly greater than +1 or strictly smaller than -1!");
67 ::std::domain_error bad_argument(error_reporting);
72 else if (x < -one+numeric_limits<T>::epsilon())
74 if (numeric_limits<T>::has_infinity)
76 return(-numeric_limits<T>::infinity());
80 ::std::string error_reporting("Argument to atanh is -1 (result: -Infinity)!");
81 ::std::out_of_range bad_argument(error_reporting);
86 else if (x > +one-numeric_limits<T>::epsilon())
88 if (numeric_limits<T>::has_infinity)
90 return(+numeric_limits<T>::infinity());
94 ::std::string error_reporting("Argument to atanh is +1 (result: +Infinity)!");
95 ::std::out_of_range bad_argument(error_reporting);
102 if (numeric_limits<T>::has_quiet_NaN)
104 return(numeric_limits<T>::quiet_NaN());
108 ::std::string error_reporting("Argument to atanh is strictly greater than +1 or strictly smaller than -1!");
109 ::std::domain_error bad_argument(error_reporting);
114 else if (abs(x) >= taylor_n_bound)
116 return(log( (one + x) / (one - x) ) / two);
120 // approximation by taylor series in x at 0 up to order 2
123 if (abs(x) >= taylor_2_bound)
127 // approximation by taylor series in x at 0 up to order 4
128 result += x3/static_cast<T>(3);
135 // These are implementation details (for main fare see below)
141 bool InfinitySupported
143 struct atanh_helper1_t
145 static T get_pos_infinity()
147 return(+::std::numeric_limits<T>::infinity());
150 static T get_neg_infinity()
152 return(-::std::numeric_limits<T>::infinity());
154 }; // boost::math::detail::atanh_helper1_t
158 struct atanh_helper1_t<T, false>
160 static T get_pos_infinity()
162 ::std::string error_reporting("Argument to atanh is +1 (result: +Infinity)!");
163 ::std::out_of_range bad_argument(error_reporting);
168 static T get_neg_infinity()
170 ::std::string error_reporting("Argument to atanh is -1 (result: -Infinity)!");
171 ::std::out_of_range bad_argument(error_reporting);
175 }; // boost::math::detail::atanh_helper1_t
180 bool QuietNanSupported
182 struct atanh_helper2_t
186 return(::std::numeric_limits<T>::quiet_NaN());
188 }; // boost::detail::atanh_helper2_t
192 struct atanh_helper2_t<T, false>
196 ::std::string error_reporting("Argument to atanh is strictly greater than +1 or strictly smaller than -1!");
197 ::std::domain_error bad_argument(error_reporting);
201 }; // boost::detail::atanh_helper2_t
205 // This is the main fare
208 inline T atanh(const T x)
214 using ::std::numeric_limits;
216 typedef detail::atanh_helper1_t<T, ::std::numeric_limits<T>::has_infinity> helper1_type;
217 typedef detail::atanh_helper2_t<T, ::std::numeric_limits<T>::has_quiet_NaN> helper2_type;
220 T const one = static_cast<T>(1);
221 T const two = static_cast<T>(2);
223 static T const taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
224 static T const taylor_n_bound = sqrt(taylor_2_bound);
228 return(helper2_type::get_NaN());
230 else if (x < -one+numeric_limits<T>::epsilon())
232 return(helper1_type::get_neg_infinity());
234 else if (x > +one-numeric_limits<T>::epsilon())
236 return(helper1_type::get_pos_infinity());
240 return(helper2_type::get_NaN());
242 else if (abs(x) >= taylor_n_bound)
244 return(log( (one + x) / (one - x) ) / two);
248 // approximation by taylor series in x at 0 up to order 2
251 if (abs(x) >= taylor_2_bound)
255 // approximation by taylor series in x at 0 up to order 4
256 result += x3/static_cast<T>(3);
262 #endif /* defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) */
266 #endif /* BOOST_ATANH_HPP */