1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/math/complex/atanh.hpp Wed Mar 31 12:27:01 2010 +0100
1.3 @@ -0,0 +1,267 @@
1.4 +// boost atanh.hpp header file
1.5 +
1.6 +// (C) Copyright Hubert Holin 2001.
1.7 +// Distributed under the Boost Software License, Version 1.0. (See
1.8 +// accompanying file LICENSE_1_0.txt or copy at
1.9 +// http://www.boost.org/LICENSE_1_0.txt)
1.10 +
1.11 +// See http://www.boost.org for updates, documentation, and revision history.
1.12 +
1.13 +#ifndef BOOST_ATANH_HPP
1.14 +#define BOOST_ATANH_HPP
1.15 +
1.16 +
1.17 +#include <cmath>
1.18 +#include <limits>
1.19 +#include <string>
1.20 +#include <stdexcept>
1.21 +
1.22 +
1.23 +#include <boost/config.hpp>
1.24 +
1.25 +
1.26 +// This is the inverse of the hyperbolic tangent function.
1.27 +
1.28 +namespace boost
1.29 +{
1.30 + namespace math
1.31 + {
1.32 +#if defined(__GNUC__) && (__GNUC__ < 3)
1.33 + // gcc 2.x ignores function scope using declarations,
1.34 + // put them in the scope of the enclosing namespace instead:
1.35 +
1.36 + using ::std::abs;
1.37 + using ::std::sqrt;
1.38 + using ::std::log;
1.39 +
1.40 + using ::std::numeric_limits;
1.41 +#endif
1.42 +
1.43 +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
1.44 + // This is the main fare
1.45 +
1.46 + template<typename T>
1.47 + inline T atanh(const T x)
1.48 + {
1.49 + using ::std::abs;
1.50 + using ::std::sqrt;
1.51 + using ::std::log;
1.52 +
1.53 + using ::std::numeric_limits;
1.54 +
1.55 + T const one = static_cast<T>(1);
1.56 + T const two = static_cast<T>(2);
1.57 +
1.58 + static T const taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
1.59 + static T const taylor_n_bound = sqrt(taylor_2_bound);
1.60 +
1.61 + if (x < -one)
1.62 + {
1.63 + if (numeric_limits<T>::has_quiet_NaN)
1.64 + {
1.65 + return(numeric_limits<T>::quiet_NaN());
1.66 + }
1.67 + else
1.68 + {
1.69 + ::std::string error_reporting("Argument to atanh is strictly greater than +1 or strictly smaller than -1!");
1.70 + ::std::domain_error bad_argument(error_reporting);
1.71 +
1.72 + throw(bad_argument);
1.73 + }
1.74 + }
1.75 + else if (x < -one+numeric_limits<T>::epsilon())
1.76 + {
1.77 + if (numeric_limits<T>::has_infinity)
1.78 + {
1.79 + return(-numeric_limits<T>::infinity());
1.80 + }
1.81 + else
1.82 + {
1.83 + ::std::string error_reporting("Argument to atanh is -1 (result: -Infinity)!");
1.84 + ::std::out_of_range bad_argument(error_reporting);
1.85 +
1.86 + throw(bad_argument);
1.87 + }
1.88 + }
1.89 + else if (x > +one-numeric_limits<T>::epsilon())
1.90 + {
1.91 + if (numeric_limits<T>::has_infinity)
1.92 + {
1.93 + return(+numeric_limits<T>::infinity());
1.94 + }
1.95 + else
1.96 + {
1.97 + ::std::string error_reporting("Argument to atanh is +1 (result: +Infinity)!");
1.98 + ::std::out_of_range bad_argument(error_reporting);
1.99 +
1.100 + throw(bad_argument);
1.101 + }
1.102 + }
1.103 + else if (x > +one)
1.104 + {
1.105 + if (numeric_limits<T>::has_quiet_NaN)
1.106 + {
1.107 + return(numeric_limits<T>::quiet_NaN());
1.108 + }
1.109 + else
1.110 + {
1.111 + ::std::string error_reporting("Argument to atanh is strictly greater than +1 or strictly smaller than -1!");
1.112 + ::std::domain_error bad_argument(error_reporting);
1.113 +
1.114 + throw(bad_argument);
1.115 + }
1.116 + }
1.117 + else if (abs(x) >= taylor_n_bound)
1.118 + {
1.119 + return(log( (one + x) / (one - x) ) / two);
1.120 + }
1.121 + else
1.122 + {
1.123 + // approximation by taylor series in x at 0 up to order 2
1.124 + T result = x;
1.125 +
1.126 + if (abs(x) >= taylor_2_bound)
1.127 + {
1.128 + T x3 = x*x*x;
1.129 +
1.130 + // approximation by taylor series in x at 0 up to order 4
1.131 + result += x3/static_cast<T>(3);
1.132 + }
1.133 +
1.134 + return(result);
1.135 + }
1.136 + }
1.137 +#else
1.138 + // These are implementation details (for main fare see below)
1.139 +
1.140 + namespace detail
1.141 + {
1.142 + template <
1.143 + typename T,
1.144 + bool InfinitySupported
1.145 + >
1.146 + struct atanh_helper1_t
1.147 + {
1.148 + static T get_pos_infinity()
1.149 + {
1.150 + return(+::std::numeric_limits<T>::infinity());
1.151 + }
1.152 +
1.153 + static T get_neg_infinity()
1.154 + {
1.155 + return(-::std::numeric_limits<T>::infinity());
1.156 + }
1.157 + }; // boost::math::detail::atanh_helper1_t
1.158 +
1.159 +
1.160 + template<typename T>
1.161 + struct atanh_helper1_t<T, false>
1.162 + {
1.163 + static T get_pos_infinity()
1.164 + {
1.165 + ::std::string error_reporting("Argument to atanh is +1 (result: +Infinity)!");
1.166 + ::std::out_of_range bad_argument(error_reporting);
1.167 +
1.168 + throw(bad_argument);
1.169 + }
1.170 +
1.171 + static T get_neg_infinity()
1.172 + {
1.173 + ::std::string error_reporting("Argument to atanh is -1 (result: -Infinity)!");
1.174 + ::std::out_of_range bad_argument(error_reporting);
1.175 +
1.176 + throw(bad_argument);
1.177 + }
1.178 + }; // boost::math::detail::atanh_helper1_t
1.179 +
1.180 +
1.181 + template <
1.182 + typename T,
1.183 + bool QuietNanSupported
1.184 + >
1.185 + struct atanh_helper2_t
1.186 + {
1.187 + static T get_NaN()
1.188 + {
1.189 + return(::std::numeric_limits<T>::quiet_NaN());
1.190 + }
1.191 + }; // boost::detail::atanh_helper2_t
1.192 +
1.193 +
1.194 + template<typename T>
1.195 + struct atanh_helper2_t<T, false>
1.196 + {
1.197 + static T get_NaN()
1.198 + {
1.199 + ::std::string error_reporting("Argument to atanh is strictly greater than +1 or strictly smaller than -1!");
1.200 + ::std::domain_error bad_argument(error_reporting);
1.201 +
1.202 + throw(bad_argument);
1.203 + }
1.204 + }; // boost::detail::atanh_helper2_t
1.205 + } // boost::detail
1.206 +
1.207 +
1.208 + // This is the main fare
1.209 +
1.210 + template<typename T>
1.211 + inline T atanh(const T x)
1.212 + {
1.213 + using ::std::abs;
1.214 + using ::std::sqrt;
1.215 + using ::std::log;
1.216 +
1.217 + using ::std::numeric_limits;
1.218 +
1.219 + typedef detail::atanh_helper1_t<T, ::std::numeric_limits<T>::has_infinity> helper1_type;
1.220 + typedef detail::atanh_helper2_t<T, ::std::numeric_limits<T>::has_quiet_NaN> helper2_type;
1.221 +
1.222 +
1.223 + T const one = static_cast<T>(1);
1.224 + T const two = static_cast<T>(2);
1.225 +
1.226 + static T const taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
1.227 + static T const taylor_n_bound = sqrt(taylor_2_bound);
1.228 +
1.229 + if (x < -one)
1.230 + {
1.231 + return(helper2_type::get_NaN());
1.232 + }
1.233 + else if (x < -one+numeric_limits<T>::epsilon())
1.234 + {
1.235 + return(helper1_type::get_neg_infinity());
1.236 + }
1.237 + else if (x > +one-numeric_limits<T>::epsilon())
1.238 + {
1.239 + return(helper1_type::get_pos_infinity());
1.240 + }
1.241 + else if (x > +one)
1.242 + {
1.243 + return(helper2_type::get_NaN());
1.244 + }
1.245 + else if (abs(x) >= taylor_n_bound)
1.246 + {
1.247 + return(log( (one + x) / (one - x) ) / two);
1.248 + }
1.249 + else
1.250 + {
1.251 + // approximation by taylor series in x at 0 up to order 2
1.252 + T result = x;
1.253 +
1.254 + if (abs(x) >= taylor_2_bound)
1.255 + {
1.256 + T x3 = x*x*x;
1.257 +
1.258 + // approximation by taylor series in x at 0 up to order 4
1.259 + result += x3/static_cast<T>(3);
1.260 + }
1.261 +
1.262 + return(result);
1.263 + }
1.264 + }
1.265 +#endif /* defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) */
1.266 + }
1.267 +}
1.268 +
1.269 +#endif /* BOOST_ATANH_HPP */
1.270 +