Chris@16: // boost asinh.hpp header file Chris@16: Chris@16: // (C) Copyright Eric Ford 2001 & Hubert Holin. 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_ACOSH_HPP Chris@16: #define BOOST_ACOSH_HPP Chris@16: Chris@16: #ifdef _MSC_VER Chris@16: #pragma once Chris@16: #endif 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 cosine function. Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace math Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: inline T acosh_imp(const T x, const Policy& pol) Chris@16: { Chris@16: BOOST_MATH_STD_USING Chris@16: Chris@16: if(x < 1) Chris@16: { Chris@16: return policies::raise_domain_error( Chris@16: "boost::math::acosh<%1%>(%1%)", Chris@16: "acosh requires x >= 1, but got x = %1%.", x, pol); Chris@16: } Chris@16: else if ((x - 1) >= tools::root_epsilon()) Chris@16: { Chris@16: if (x > 1 / tools::root_epsilon()) Chris@16: { Chris@16: // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/06/01/0001/ Chris@16: // approximation by laurent series in 1/x at 0+ order from -1 to 0 Chris@16: return log(x) + constants::ln_two(); Chris@16: } Chris@16: else if(x < 1.5f) Chris@16: { Chris@16: // This is just a rearrangement of the standard form below Chris@16: // devised to minimse loss of precision when x ~ 1: Chris@16: T y = x - 1; Chris@16: return boost::math::log1p(y + sqrt(y * y + 2 * y), pol); Chris@16: } Chris@16: else Chris@16: { Chris@16: // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/ Chris@16: return( log( x + sqrt(x * x - 1) ) ); Chris@16: } Chris@16: } Chris@16: else Chris@16: { Chris@16: // see http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/04/01/0001/ Chris@16: T y = x - 1; Chris@16: Chris@16: // approximation by taylor series in y at 0 up to order 2 Chris@16: T result = sqrt(2 * y) * (1 - y /12 + 3 * y * y / 160); Chris@16: return result; Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename tools::promote_args::type acosh(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::acosh_imp(static_cast(x), forwarding_policy()), Chris@16: "boost::math::acosh<%1%>(%1%)"); Chris@16: } Chris@16: template Chris@16: inline typename tools::promote_args::type acosh(T x) Chris@16: { Chris@16: return boost::math::acosh(x, policies::policy<>()); Chris@16: } Chris@16: Chris@16: } Chris@16: } Chris@16: Chris@16: #endif /* BOOST_ACOSH_HPP */ Chris@16: Chris@16: