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