1 | // boost sinc.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_SINC_HPP |
11 | #define BOOST_SINC_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/policies/policy.hpp> |
21 | #include <boost/math/special_functions/math_fwd.hpp> |
22 | #include <boost/config/no_tr1/cmath.hpp> |
23 | #include <boost/limits.hpp> |
24 | #include <string> |
25 | #include <stdexcept> |
26 | |
27 | |
28 | #include <boost/config.hpp> |
29 | |
30 | |
31 | // These are the the "Sinus Cardinal" functions. |
32 | |
33 | namespace boost |
34 | { |
35 | namespace math |
36 | { |
37 | namespace detail |
38 | { |
39 | // This is the "Sinus Cardinal" of index Pi. |
40 | |
41 | template<typename T> |
42 | inline T sinc_pi_imp(const T x) |
43 | { |
44 | BOOST_MATH_STD_USING |
45 | |
46 | if (abs(x) >= 3.3 * tools::forth_root_epsilon<T>()) |
47 | { |
48 | return(sin(x)/x); |
49 | } |
50 | else |
51 | { |
52 | // |x| < (eps*120)^(1/4) |
53 | return 1 - x * x / 6; |
54 | } |
55 | } |
56 | |
57 | } // namespace detail |
58 | |
59 | template <class T> |
60 | inline typename tools::promote_args<T>::type sinc_pi(T x) |
61 | { |
62 | typedef typename tools::promote_args<T>::type result_type; |
63 | return detail::sinc_pi_imp(static_cast<result_type>(x)); |
64 | } |
65 | |
66 | template <class T, class Policy> |
67 | inline typename tools::promote_args<T>::type sinc_pi(T x, const Policy&) |
68 | { |
69 | typedef typename tools::promote_args<T>::type result_type; |
70 | return detail::sinc_pi_imp(static_cast<result_type>(x)); |
71 | } |
72 | |
73 | #ifndef BOOST_NO_TEMPLATE_TEMPLATES |
74 | template<typename T, template<typename> class U> |
75 | inline U<T> sinc_pi(const U<T> x) |
76 | { |
77 | BOOST_MATH_STD_USING |
78 | using ::std::numeric_limits; |
79 | |
80 | T const taylor_0_bound = tools::epsilon<T>(); |
81 | T const taylor_2_bound = tools::root_epsilon<T>(); |
82 | T const taylor_n_bound = tools::forth_root_epsilon<T>(); |
83 | |
84 | if (abs(x) >= taylor_n_bound) |
85 | { |
86 | return(sin(x)/x); |
87 | } |
88 | else |
89 | { |
90 | // approximation by taylor series in x at 0 up to order 0 |
91 | #ifdef __MWERKS__ |
92 | U<T> result = static_cast<U<T> >(1); |
93 | #else |
94 | U<T> result = U<T>(1); |
95 | #endif |
96 | |
97 | if (abs(x) >= taylor_0_bound) |
98 | { |
99 | U<T> x2 = x*x; |
100 | |
101 | // approximation by taylor series in x at 0 up to order 2 |
102 | result -= x2/static_cast<T>(6); |
103 | |
104 | if (abs(x) >= taylor_2_bound) |
105 | { |
106 | // approximation by taylor series in x at 0 up to order 4 |
107 | result += (x2*x2)/static_cast<T>(120); |
108 | } |
109 | } |
110 | |
111 | return(result); |
112 | } |
113 | } |
114 | |
115 | template<typename T, template<typename> class U, class Policy> |
116 | inline U<T> sinc_pi(const U<T> x, const Policy&) |
117 | { |
118 | return sinc_pi(x); |
119 | } |
120 | #endif /* BOOST_NO_TEMPLATE_TEMPLATES */ |
121 | } |
122 | } |
123 | |
124 | #endif /* BOOST_SINC_HPP */ |
125 | |
126 | |