Chris@16: // boost atanh.hpp header file Chris@16: Chris@16: // (C) Copyright Hubert Holin 2001. Chris@16: // (C) Copyright John Maddock 2008. Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org for updates, documentation, and revision history. Chris@16: Chris@16: #ifndef BOOST_ATANH_HPP Chris@16: #define BOOST_ATANH_HPP Chris@16: Chris@16: #ifdef _MSC_VER Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // This is the inverse of the hyperbolic tangent function. Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace math Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: // This is the main fare Chris@16: Chris@16: template Chris@16: inline T atanh_imp(const T x, const Policy& pol) Chris@16: { Chris@16: BOOST_MATH_STD_USING Chris@16: static const char* function = "boost::math::atanh<%1%>(%1%)"; Chris@16: Chris@16: if(x < -1) Chris@16: { Chris@16: return policies::raise_domain_error( Chris@16: function, Chris@16: "atanh requires x >= -1, but got x = %1%.", x, pol); Chris@16: } Chris@16: else if(x > 1) Chris@16: { Chris@16: return policies::raise_domain_error( Chris@16: function, Chris@16: "atanh requires x <= 1, but got x = %1%.", x, pol); Chris@16: } Chris@16: else if(x < -1 + tools::epsilon()) Chris@16: { Chris@16: // -Infinity: Chris@16: return -policies::raise_overflow_error(function, 0, pol); Chris@16: } Chris@16: else if(x > 1 - tools::epsilon()) Chris@16: { Chris@16: // Infinity: Chris@16: return policies::raise_overflow_error(function, 0, pol); Chris@16: } Chris@16: else if(abs(x) >= tools::forth_root_epsilon()) Chris@16: { Chris@16: // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/02/ Chris@16: if(abs(x) < 0.5f) Chris@16: return (boost::math::log1p(x, pol) - boost::math::log1p(-x, pol)) / 2; Chris@16: return(log( (1 + x) / (1 - x) ) / 2); Chris@16: } Chris@16: else Chris@16: { Chris@16: // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/06/01/03/01/ Chris@16: // approximation by taylor series in x at 0 up to order 2 Chris@16: T result = x; Chris@16: Chris@16: if (abs(x) >= tools::root_epsilon()) Chris@16: { Chris@16: T x3 = x*x*x; Chris@16: Chris@16: // approximation by taylor series in x at 0 up to order 4 Chris@16: result += x3/static_cast(3); Chris@16: } Chris@16: Chris@16: return(result); Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename tools::promote_args::type atanh(T x, const Policy&) Chris@16: { Chris@16: typedef typename tools::promote_args::type result_type; Chris@16: typedef typename policies::evaluation::type value_type; Chris@16: typedef typename policies::normalise< Chris@16: Policy, Chris@16: policies::promote_float, Chris@16: policies::promote_double, Chris@16: policies::discrete_quantile<>, Chris@16: policies::assert_undefined<> >::type forwarding_policy; Chris@16: return policies::checked_narrowing_cast( Chris@16: detail::atanh_imp(static_cast(x), forwarding_policy()), Chris@16: "boost::math::atanh<%1%>(%1%)"); Chris@16: } Chris@16: template Chris@16: inline typename tools::promote_args::type atanh(T x) Chris@16: { Chris@16: return boost::math::atanh(x, policies::policy<>()); Chris@16: } Chris@16: Chris@16: } Chris@16: } Chris@16: Chris@16: #endif /* BOOST_ATANH_HPP */ Chris@16: Chris@16: Chris@16: