mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
jinc.hpp
Go to the documentation of this file.
1 /** \file jinc.hpp
2  * \brief Declares and defines the Jinc and Jinc2 functions
3  * \ingroup gen_math_files
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2015, 2016, 2017 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef math_func_jinc_hpp
28 #define math_func_jinc_hpp
29 
30 #include <limits>
31 #include <cmath>
32 
33 #include "bessel.hpp"
34 #include "precision.hpp"
35 
36 namespace mx
37 {
38 namespace math
39 {
40 namespace func
41 {
42 
43 /// The Jinc function
44 /** The Jinc function is defined here as
45  * \f[
46  * Ji(x) = \frac{J_1(x)}{x}
47  * \f]
48  * where \f$ J_1 \f$ is the cylindrical bessel function of the first kind of order 1.
49  *
50  * Follows the technique in boost sinc_pi, using the Taylor series for small arguments. If x
51  * is smaller than \f$ \epsilon \f$, then it returns 1/2. If x is larger than \f$ \epsilon \f$ but smaller than \f$ \sqrt{\epsilon} \f$, then
52  * this function returns
53  * \f[
54  * Ji(x) \approx \frac{1}{2} - \frac{x^2}{16}.
55  * \f]
56  *
57  * \returns the value of Ji(x)
58  *
59  * \tparam T is an floating point type
60  *
61  * \ingroup gen_math_bessel
62  */
63 template<typename T>
64 T jinc( const T & x /**< [in] the argument */)
65 {
66  T const taylor_0_bound = std::numeric_limits<T>::epsilon();
67  T const taylor_2_bound = root_epsilon<T>();
68 
69  if( std::fabs(x) > taylor_2_bound)
70  {
71  return bessel_j<int, T>(1,x)/(x);
72  }
73  else
74  {
75  // approximation by taylor series in x at 0
76  T result = static_cast<T>(0.5);
77  if (std::fabs(x) >= taylor_0_bound)
78  {
79  T x2 = x*x;
80 
81  // approximation by taylor series in x at 0 up to order 2
82  result -= x2/static_cast<T>(16);
83  }
84 
85  return result;
86  }
87 
88 }
89 
90 extern template
91 float jinc<float>(const float & x);
92 
93 extern template
94 double jinc<double>(const double & x);
95 
96 extern template
97 long double jinc<long double>(const long double & x);
98 
99 #ifdef HASQUAD
100 extern template
101 __float128 jinc<__float128>(const __float128 & x);
102 #endif
103 
104 /// The JincN function
105 /** The JincN function is defined here as
106  * \f[
107  * Ji_N(x) = \frac{J_N(x)}{x}
108  * \f]
109  * where \f$ J_N \f$ is the cylindrical bessel function of the first kind of order N, \f$ N \ge 1 \f$.
110  *
111  * If \f$ N == 1 \f$ this returns \ref mx::math::func::jinc() "jinc(x)".
112  *
113  * Otherwise, if x is smaller than \f$ \sqrt{\epsilon} \f$, returns 0.
114  *
115  * \returns the value of JiN(x)
116  *
117  * \ingroup gen_math_bessel
118  */
119 template<typename T1, typename T2>
120 T2 jincN( const T1 & v, ///< [in] the Bessel function order
121  const T2 & x ///< [in] the argument
122  )
123 {
124  if(v == 1) return jinc(x);
125 
126  T2 const taylor_2_bound = root_epsilon<T2>();
127 
128  if( std::fabs(x) > taylor_2_bound )
129  {
130  return bessel_j<T1, T2>(v,x)/(x);
131  }
132  else
133  {
134  return static_cast<T2>(0);
135  }
136 }
137 
138 extern template
139 float jincN<float, float>( const float & v,
140  const float & x
141  );
142 
143 extern template
144 float jincN<int, float>( const int & v,
145  const float & x
146  );
147 
148 extern template
149 double jincN<double, double>( const double & v,
150  const double & x
151  );
152 
153 extern template
154 double jincN<int, double>( const int & v,
155  const double & x
156  );
157 
158 
159 extern template
160 long double jincN<long double, long double>( const long double & v,
161  const long double & x
162  );
163 
164 extern template
165 long double jincN<int, long double>( const int & v,
166  const long double & x
167  );
168 
169 #ifdef HASQUAD
170 extern template
171 
172 __float128 jincN<__float128, __float128>( const __float128 & v,
173  const __float128 & x
174  );
175 
176 __float128 jincN<int, __float128>( const int & v,
177  const __float128 & x
178  );
179 #endif
180 
181 } //namespace func
182 } //namespace math
183 } //namespace mx
184 
185 #endif //math_func_jinc_hpp
Declares and defines Bessel functions of the first kind.
T2 jincN(const T1 &v, const T2 &x)
The JincN function.
Definition: jinc.hpp:120
T jinc(const T &x)
The Jinc function.
Definition: jinc.hpp:64
The mxlib c++ namespace.
Definition: mxError.hpp:107