Chris@16: // boost asinh.hpp header file Chris@16: Chris@16: // (C) Copyright Eric Ford & 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_ASINH_HPP Chris@16: #define BOOST_ASINH_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: #include Chris@16: Chris@16: // This is the inverse of the hyperbolic sine function. Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace math Chris@16: { Chris@16: namespace detail{ Chris@16: template Chris@16: inline T asinh_imp(const T x, const Policy& pol) Chris@16: { Chris@16: BOOST_MATH_STD_USING Chris@16: Chris@16: if (x >= tools::forth_root_epsilon()) Chris@16: { Chris@16: if (x > 1 / tools::root_epsilon()) Chris@16: { Chris@16: // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/06/01/06/01/0001/ Chris@16: // approximation by laurent series in 1/x at 0+ order from -1 to 1 Chris@16: return constants::ln_two() + log(x) + 1/ (4 * x * x); Chris@16: } Chris@16: else if(x < 0.5f) Chris@16: { Chris@16: // As below, but rearranged to preserve digits: Chris@16: return boost::math::log1p(x + boost::math::sqrt1pm1(x * x, pol), pol); Chris@16: } Chris@16: else Chris@16: { Chris@16: // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/ Chris@16: return( log( x + sqrt(x*x+1) ) ); Chris@16: } Chris@16: } Chris@16: else if (x <= -tools::forth_root_epsilon()) Chris@16: { Chris@16: return(-asinh(-x, pol)); Chris@16: } Chris@16: else Chris@16: { Chris@16: // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/06/01/03/01/0001/ 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(6); 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 asinh(T x) Chris@16: { Chris@16: return boost::math::asinh(x, policies::policy<>()); Chris@16: } Chris@16: template Chris@16: inline typename tools::promote_args::type asinh(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::asinh_imp(static_cast(x), forwarding_policy()), Chris@16: "boost::math::asinh<%1%>(%1%)"); Chris@16: } Chris@16: Chris@16: } Chris@16: } Chris@16: Chris@16: #endif /* BOOST_ASINH_HPP */ Chris@16: