Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-09 08:15:12

0001 //    boost asinh.hpp header file
0002 
0003 //  (C) Copyright Eric Ford 2001 & Hubert Holin.
0004 //  (C) Copyright John Maddock 2008.
0005 //  Distributed under the Boost Software License, Version 1.0. (See
0006 //  accompanying file LICENSE_1_0.txt or copy at
0007 //  http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 // See http://www.boost.org for updates, documentation, and revision history.
0010 
0011 #ifndef BOOST_ACOSH_HPP
0012 #define BOOST_ACOSH_HPP
0013 
0014 #ifdef _MSC_VER
0015 #pragma once
0016 #endif
0017 
0018 #include <cmath>
0019 #include <boost/math/tools/precision.hpp>
0020 #include <boost/math/policies/error_handling.hpp>
0021 #include <boost/math/special_functions/math_fwd.hpp>
0022 #include <boost/math/special_functions/log1p.hpp>
0023 #include <boost/math/constants/constants.hpp>
0024 #include <boost/math/special_functions/fpclassify.hpp>
0025 
0026 // This is the inverse of the hyperbolic cosine function.
0027 
0028 namespace boost
0029 {
0030     namespace math
0031     {
0032        namespace detail
0033        {
0034         template<typename T, typename Policy>
0035         inline T    acosh_imp(const T x, const Policy& pol)
0036         {
0037             BOOST_MATH_STD_USING
0038             
0039             if((x < 1) || (boost::math::isnan)(x))
0040             {
0041                return policies::raise_domain_error<T>("boost::math::acosh<%1%>(%1%)", "acosh requires x >= 1, but got x = %1%.", x, pol);
0042             }
0043             else if    ((x - 1) >= tools::root_epsilon<T>())
0044             {
0045                 if    (x > 1 / tools::root_epsilon<T>())
0046                 {
0047                     // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/06/01/0001/
0048                     // approximation by laurent series in 1/x at 0+ order from -1 to 0
0049                     return log(x) + constants::ln_two<T>();
0050                 }
0051                 else if(x < 1.5f)
0052                 {
0053                    // This is just a rearrangement of the standard form below
0054                    // devised to minimise loss of precision when x ~ 1:
0055                    T y = x - 1;
0056                    return boost::math::log1p(y + sqrt(y * y + 2 * y), pol);
0057                 }
0058                 else
0059                 {
0060                     // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/
0061                     return( log( x + sqrt(x * x - 1) ) );
0062                 }
0063             }
0064             else
0065             {
0066                 // see http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/04/01/0001/
0067                 T y = x - 1;
0068                 
0069                 // approximation by taylor series in y at 0 up to order 2
0070                 T result = sqrt(2 * y) * (1 - y /12 + 3 * y * y / 160);
0071                 return result;
0072             }
0073         }
0074        }
0075 
0076         template<typename T, typename Policy>
0077         inline typename tools::promote_args<T>::type acosh(T x, const Policy&)
0078         {
0079             typedef typename tools::promote_args<T>::type result_type;
0080             typedef typename policies::evaluation<result_type, Policy>::type value_type;
0081             typedef typename policies::normalise<
0082                Policy, 
0083                policies::promote_float<false>, 
0084                policies::promote_double<false>, 
0085                policies::discrete_quantile<>,
0086                policies::assert_undefined<> >::type forwarding_policy;
0087            return policies::checked_narrowing_cast<result_type, forwarding_policy>(
0088               detail::acosh_imp(static_cast<value_type>(x), forwarding_policy()),
0089               "boost::math::acosh<%1%>(%1%)");
0090         }
0091         template<typename T>
0092         inline typename tools::promote_args<T>::type acosh(T x)
0093         {
0094            return boost::math::acosh(x, policies::policy<>());
0095         }
0096 
0097     }
0098 }
0099 
0100 #endif /* BOOST_ACOSH_HPP */
0101 
0102