1 //  boost sinhc.hpp header file
2 
3 //  (C) Copyright Hubert Holin 2001.
4 //  Distributed under the Boost Software License, Version 1.0. (See
5 //  accompanying file LICENSE_1_0.txt or copy at
6 //  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_HPP
11 #define BOOST_SINHC_HPP
12 
13 
14 #ifdef _MSC_VER
15 #pragma once
16 #endif
17 
18 #include <boost/math/tools/config.hpp>
19 #include <boost/math/tools/precision.hpp>
20 #include <boost/math/special_functions/math_fwd.hpp>
21 #include <boost/config/no_tr1/cmath.hpp>
22 #include <boost/limits.hpp>
23 #include <string>
24 #include <stdexcept>
25 
26 #include <boost/config.hpp>
27 
28 
29 // These are the the "Hyperbolic Sinus Cardinal" functions.
30 
31 namespace boost
32 {
33     namespace math
34     {
35        namespace detail
36        {
37         // This is the "Hyperbolic Sinus Cardinal" of index Pi.
38 
39         template<typename T>
sinhc_pi_imp(const T x)40         inline T    sinhc_pi_imp(const T x)
41         {
42 #if defined(BOOST_NO_STDC_NAMESPACE) && !defined(__SUNPRO_CC)
43             using    ::abs;
44             using    ::sinh;
45             using    ::sqrt;
46 #else    /* BOOST_NO_STDC_NAMESPACE */
47             using    ::std::abs;
48             using    ::std::sinh;
49             using    ::std::sqrt;
50 #endif    /* BOOST_NO_STDC_NAMESPACE */
51 
52             static T const    taylor_0_bound = tools::epsilon<T>();
53             static T const    taylor_2_bound = sqrt(taylor_0_bound);
54             static T const    taylor_n_bound = sqrt(taylor_2_bound);
55 
56             if    (abs(x) >= taylor_n_bound)
57             {
58                 return(sinh(x)/x);
59             }
60             else
61             {
62                 // approximation by taylor series in x at 0 up to order 0
63                 T    result = static_cast<T>(1);
64 
65                 if    (abs(x) >= taylor_0_bound)
66                 {
67                     T    x2 = x*x;
68 
69                     // approximation by taylor series in x at 0 up to order 2
70                     result += x2/static_cast<T>(6);
71 
72                     if    (abs(x) >= taylor_2_bound)
73                     {
74                         // approximation by taylor series in x at 0 up to order 4
75                         result += (x2*x2)/static_cast<T>(120);
76                     }
77                 }
78 
79                 return(result);
80             }
81         }
82 
83        } // namespace detail
84 
85        template <class T>
sinhc_pi(T x)86        inline typename tools::promote_args<T>::type sinhc_pi(T x)
87        {
88           typedef typename tools::promote_args<T>::type result_type;
89           return detail::sinhc_pi_imp(static_cast<result_type>(x));
90        }
91 
92        template <class T, class Policy>
sinhc_pi(T x,const Policy &)93        inline typename tools::promote_args<T>::type sinhc_pi(T x, const Policy&)
94        {
95           return boost::math::sinhc_pi(x);
96        }
97 
98 #ifdef    BOOST_NO_TEMPLATE_TEMPLATES
99 #else    /* BOOST_NO_TEMPLATE_TEMPLATES */
100         template<typename T, template<typename> class U>
sinhc_pi(const U<T> x)101         inline U<T>    sinhc_pi(const U<T> x)
102         {
103 #if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) || defined(__GNUC__)
104             using namespace std;
105 #elif    defined(BOOST_NO_STDC_NAMESPACE) && !defined(__SUNPRO_CC)
106             using    ::abs;
107             using    ::sinh;
108             using    ::sqrt;
109 #else    /* BOOST_NO_STDC_NAMESPACE */
110             using    ::std::abs;
111             using    ::std::sinh;
112             using    ::std::sqrt;
113 #endif    /* BOOST_NO_STDC_NAMESPACE */
114 
115             using    ::std::numeric_limits;
116 
117             static T const    taylor_0_bound = tools::epsilon<T>();
118             static T const    taylor_2_bound = sqrt(taylor_0_bound);
119             static T const    taylor_n_bound = sqrt(taylor_2_bound);
120 
121             if    (abs(x) >= taylor_n_bound)
122             {
123                 return(sinh(x)/x);
124             }
125             else
126             {
127                 // approximation by taylor series in x at 0 up to order 0
128 #ifdef __MWERKS__
129                 U<T>    result = static_cast<U<T> >(1);
130 #else
131                 U<T>    result = U<T>(1);
132 #endif
133 
134                 if    (abs(x) >= taylor_0_bound)
135                 {
136                     U<T>    x2 = x*x;
137 
138                     // approximation by taylor series in x at 0 up to order 2
139                     result += x2/static_cast<T>(6);
140 
141                     if    (abs(x) >= taylor_2_bound)
142                     {
143                         // approximation by taylor series in x at 0 up to order 4
144                         result += (x2*x2)/static_cast<T>(120);
145                     }
146                 }
147 
148                 return(result);
149             }
150         }
151 #endif    /* BOOST_NO_TEMPLATE_TEMPLATES */
152     }
153 }
154 
155 #endif /* BOOST_SINHC_HPP */
156 
157