1 // boost asinh.hpp header file 2 3 // (C) Copyright Eric Ford 2001 & Hubert Holin. 4 // (C) Copyright John Maddock 2008. 5 // Distributed under the Boost Software License, Version 1.0. (See 6 // accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 // See http://www.boost.org for updates, documentation, and revision history. 10 11 #ifndef BOOST_ACOSH_HPP 12 #define BOOST_ACOSH_HPP 13 14 #ifdef _MSC_VER 15 #pragma once 16 #endif 17 18 #include <boost/config/no_tr1/cmath.hpp> 19 #include <boost/config.hpp> 20 #include <boost/math/tools/precision.hpp> 21 #include <boost/math/policies/error_handling.hpp> 22 #include <boost/math/special_functions/math_fwd.hpp> 23 #include <boost/math/special_functions/log1p.hpp> 24 #include <boost/math/constants/constants.hpp> 25 26 // This is the inverse of the hyperbolic cosine function. 27 28 namespace boost 29 { 30 namespace math 31 { 32 namespace detail 33 { 34 template<typename T, typename Policy> acosh_imp(const T x,const Policy & pol)35 inline T acosh_imp(const T x, const Policy& pol) 36 { 37 BOOST_MATH_STD_USING 38 39 if((x < 1) || (boost::math::isnan)(x)) 40 { 41 return policies::raise_domain_error<T>( 42 "boost::math::acosh<%1%>(%1%)", 43 "acosh requires x >= 1, but got x = %1%.", x, pol); 44 } 45 else if ((x - 1) >= tools::root_epsilon<T>()) 46 { 47 if (x > 1 / tools::root_epsilon<T>()) 48 { 49 // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/06/01/0001/ 50 // approximation by laurent series in 1/x at 0+ order from -1 to 0 51 return log(x) + constants::ln_two<T>(); 52 } 53 else if(x < 1.5f) 54 { 55 // This is just a rearrangement of the standard form below 56 // devised to minimse loss of precision when x ~ 1: 57 T y = x - 1; 58 return boost::math::log1p(y + sqrt(y * y + 2 * y), pol); 59 } 60 else 61 { 62 // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/ 63 return( log( x + sqrt(x * x - 1) ) ); 64 } 65 } 66 else 67 { 68 // see http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/04/01/0001/ 69 T y = x - 1; 70 71 // approximation by taylor series in y at 0 up to order 2 72 T result = sqrt(2 * y) * (1 - y /12 + 3 * y * y / 160); 73 return result; 74 } 75 } 76 } 77 78 template<typename T, typename Policy> acosh(T x,const Policy &)79 inline typename tools::promote_args<T>::type acosh(T x, const Policy&) 80 { 81 typedef typename tools::promote_args<T>::type result_type; 82 typedef typename policies::evaluation<result_type, Policy>::type value_type; 83 typedef typename policies::normalise< 84 Policy, 85 policies::promote_float<false>, 86 policies::promote_double<false>, 87 policies::discrete_quantile<>, 88 policies::assert_undefined<> >::type forwarding_policy; 89 return policies::checked_narrowing_cast<result_type, forwarding_policy>( 90 detail::acosh_imp(static_cast<value_type>(x), forwarding_policy()), 91 "boost::math::acosh<%1%>(%1%)"); 92 } 93 template<typename T> acosh(T x)94 inline typename tools::promote_args<T>::type acosh(T x) 95 { 96 return boost::math::acosh(x, policies::policy<>()); 97 } 98 99 } 100 } 101 102 #endif /* BOOST_ACOSH_HPP */ 103 104 105