brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · b8c5f9f Raw
143 lines · plain
1//  boost sinhc.hpp header file2 3//  (C) Copyright Hubert Holin 2001.4//  Distributed under the Boost Software License, Version 1.0. (See5//  accompanying file LICENSE_1_0.txt or copy at6//  http://www.boost.org/LICENSE_1_0.txt)7 8// See http://www.boost.org for updates, documentation, and revision history.9 10#ifndef BOOST_SINHC_HPP11#define BOOST_SINHC_HPP12 13 14#ifdef _MSC_VER15#pragma once16#endif17 18#include <boost/math/tools/precision.hpp>19#include <boost/math/policies/error_handling.hpp>20#include <boost/math/special_functions/math_fwd.hpp>21#include <boost/math/special_functions/fpclassify.hpp>22#include <limits>23#include <string>24#include <stdexcept>25#include <cmath>26 27// These are the the "Hyperbolic Sinus Cardinal" functions.28 29namespace boost30{31    namespace math32    {33       namespace detail34       {35        // This is the "Hyperbolic Sinus Cardinal" of index Pi.36 37        template<typename T, typename Policy>38        inline T    sinhc_pi_imp(const T x, const Policy&)39        {40            using    ::std::abs;41            using    ::std::sinh;42            using    ::std::sqrt;43 44            static T const    taylor_0_bound = tools::epsilon<T>();45            static T const    taylor_2_bound = sqrt(taylor_0_bound);46            static T const    taylor_n_bound = sqrt(taylor_2_bound);47 48            if((boost::math::isinf)(x))49            {50               return policies::raise_overflow_error<T>("sinhc(%1%)", nullptr, Policy());51            }52            if    (abs(x) >= taylor_n_bound)53            {54                return(sinh(x)/x);55            }56            else57            {58                // approximation by taylor series in x at 0 up to order 059                T    result = static_cast<T>(1);60 61                if    (abs(x) >= taylor_0_bound)62                {63                    T    x2 = x*x;64 65                    // approximation by taylor series in x at 0 up to order 266                    result += x2/static_cast<T>(6);67 68                    if    (abs(x) >= taylor_2_bound)69                    {70                        // approximation by taylor series in x at 0 up to order 471                        result += (x2*x2)/static_cast<T>(120);72                    }73                }74 75                return(result);76            }77        }78 79       } // namespace detail80 81       template <class T, class Policy>82       inline typename tools::promote_args<T>::type sinhc_pi(T x, const Policy& pol)83       {84          typedef typename tools::promote_args<T>::type result_type;85          return policies::checked_narrowing_cast<T, Policy>(detail::sinhc_pi_imp(static_cast<result_type>(x), pol), "sinhc(%1%)");86       }87 88       template <class T>89       inline typename tools::promote_args<T>::type sinhc_pi(T x)90       {91          typedef typename tools::promote_args<T>::type result_type;92          return sinhc_pi(static_cast<result_type>(x), policies::policy<>());93       }94 95        template<typename T, template<typename> class U>96        inline U<T>    sinhc_pi(const U<T> x)97        {98            using std::abs;99            using std::sinh;100            using std::sqrt;101 102            using    ::std::numeric_limits;103 104            static T const    taylor_0_bound = tools::epsilon<T>();105            static T const    taylor_2_bound = sqrt(taylor_0_bound);106            static T const    taylor_n_bound = sqrt(taylor_2_bound);107 108            if    (abs(x) >= taylor_n_bound)109            {110                return(sinh(x)/x);111            }112            else113            {114                // approximation by taylor series in x at 0 up to order 0115#ifdef __MWERKS__116                U<T>    result = static_cast<U<T> >(1);117#else118                U<T>    result = U<T>(1);119#endif120 121                if    (abs(x) >= taylor_0_bound)122                {123                    U<T>    x2 = x*x;124 125                    // approximation by taylor series in x at 0 up to order 2126                    result += x2/static_cast<T>(6);127 128                    if    (abs(x) >= taylor_2_bound)129                    {130                        // approximation by taylor series in x at 0 up to order 4131                        result += (x2*x2)/static_cast<T>(120);132                    }133                }134 135                return(result);136            }137        }138    }139}140 141#endif /* BOOST_SINHC_HPP */142 143