Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:08

0001 //    boost asinh.hpp header file
0002 
0003 //  (C) Copyright Eric Ford & Hubert Holin 2001.
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_ASINH_HPP
0012 #define BOOST_ASINH_HPP
0013 
0014 #ifdef _MSC_VER
0015 #pragma once
0016 #endif
0017 
0018 
0019 #include <cmath>
0020 #include <boost/math/tools/precision.hpp>
0021 #include <boost/math/special_functions/math_fwd.hpp>
0022 #include <boost/math/special_functions/sqrt1pm1.hpp>
0023 #include <boost/math/special_functions/log1p.hpp>
0024 #include <boost/math/constants/constants.hpp>
0025 #include <boost/math/special_functions/fpclassify.hpp>
0026 
0027 // This is the inverse of the hyperbolic sine function.
0028 
0029 namespace boost
0030 {
0031     namespace math
0032     {
0033        namespace detail{
0034         template<typename T, class Policy>
0035         inline T    asinh_imp(const T x, const Policy& pol)
0036         {
0037             BOOST_MATH_STD_USING
0038             
0039             if((boost::math::isnan)(x))
0040             {
0041                return policies::raise_domain_error<T>(
0042                   "boost::math::asinh<%1%>(%1%)",
0043                   "asinh requires a finite argument, but got x = %1%.", x, pol);
0044             }
0045             if        (x >= tools::forth_root_epsilon<T>())
0046             {
0047                if        (x > 1 / tools::root_epsilon<T>())
0048                 {
0049                     // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/06/01/06/01/0001/
0050                     // approximation by laurent series in 1/x at 0+ order from -1 to 1
0051                     return constants::ln_two<T>() + log(x) + 1/ (4 * x * x);
0052                 }
0053                 else if(x < 0.5f)
0054                 {
0055                    // As below, but rearranged to preserve digits:
0056                    return boost::math::log1p(x + boost::math::sqrt1pm1(x * x, pol), pol);
0057                 }
0058                 else
0059                 {
0060                     // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/
0061                     return( log( x + sqrt(x*x+1) ) );
0062                 }
0063             }
0064             else if    (x <= -tools::forth_root_epsilon<T>())
0065             {
0066                 return(-asinh(-x, pol));
0067             }
0068             else
0069             {
0070                 // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/06/01/03/01/0001/
0071                 // approximation by taylor series in x at 0 up to order 2
0072                 T    result = x;
0073                 
0074                 if    (abs(x) >= tools::root_epsilon<T>())
0075                 {
0076                     T    x3 = x*x*x;
0077                     
0078                     // approximation by taylor series in x at 0 up to order 4
0079                     result -= x3/static_cast<T>(6);
0080                 }
0081                 
0082                 return(result);
0083             }
0084         }
0085        }
0086 
0087         template<typename T>
0088         inline typename tools::promote_args<T>::type asinh(T x)
0089         {
0090            return boost::math::asinh(x, policies::policy<>());
0091         }
0092         template<typename T, typename Policy>
0093         inline typename tools::promote_args<T>::type asinh(T x, const Policy&)
0094         {
0095             typedef typename tools::promote_args<T>::type result_type;
0096             typedef typename policies::evaluation<result_type, Policy>::type value_type;
0097             typedef typename policies::normalise<
0098                Policy, 
0099                policies::promote_float<false>, 
0100                policies::promote_double<false>, 
0101                policies::discrete_quantile<>,
0102                policies::assert_undefined<> >::type forwarding_policy;
0103            return policies::checked_narrowing_cast<result_type, forwarding_policy>(
0104               detail::asinh_imp(static_cast<value_type>(x), forwarding_policy()),
0105               "boost::math::asinh<%1%>(%1%)");
0106         }
0107 
0108     }
0109 }
0110 
0111 #endif /* BOOST_ASINH_HPP */
0112