Chris@16
|
1 // Copyright (c) 2007, 2013 John Maddock
|
Chris@16
|
2 // Copyright Christopher Kormanyos 2013.
|
Chris@16
|
3 // Use, modification and distribution are subject to the
|
Chris@16
|
4 // Boost Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 // This header just defines the function entry points, and adds dispatch
|
Chris@16
|
8 // to the right implementation method. Most of the implementation details
|
Chris@16
|
9 // are in separate headers and copyright Xiaogang Zhang.
|
Chris@16
|
10 //
|
Chris@16
|
11 #ifndef BOOST_MATH_BESSEL_HPP
|
Chris@16
|
12 #define BOOST_MATH_BESSEL_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #ifdef _MSC_VER
|
Chris@16
|
15 # pragma once
|
Chris@16
|
16 #endif
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/math/special_functions/detail/bessel_jy.hpp>
|
Chris@16
|
19 #include <boost/math/special_functions/detail/bessel_jn.hpp>
|
Chris@16
|
20 #include <boost/math/special_functions/detail/bessel_yn.hpp>
|
Chris@16
|
21 #include <boost/math/special_functions/detail/bessel_jy_zero.hpp>
|
Chris@16
|
22 #include <boost/math/special_functions/detail/bessel_ik.hpp>
|
Chris@16
|
23 #include <boost/math/special_functions/detail/bessel_i0.hpp>
|
Chris@16
|
24 #include <boost/math/special_functions/detail/bessel_i1.hpp>
|
Chris@16
|
25 #include <boost/math/special_functions/detail/bessel_kn.hpp>
|
Chris@16
|
26 #include <boost/math/special_functions/detail/iconv.hpp>
|
Chris@16
|
27 #include <boost/math/special_functions/sin_pi.hpp>
|
Chris@16
|
28 #include <boost/math/special_functions/cos_pi.hpp>
|
Chris@16
|
29 #include <boost/math/special_functions/sinc.hpp>
|
Chris@16
|
30 #include <boost/math/special_functions/trunc.hpp>
|
Chris@16
|
31 #include <boost/math/special_functions/round.hpp>
|
Chris@16
|
32 #include <boost/math/tools/rational.hpp>
|
Chris@16
|
33 #include <boost/math/tools/promotion.hpp>
|
Chris@16
|
34 #include <boost/math/tools/series.hpp>
|
Chris@16
|
35 #include <boost/math/tools/roots.hpp>
|
Chris@16
|
36
|
Chris@16
|
37 namespace boost{ namespace math{
|
Chris@16
|
38
|
Chris@16
|
39 namespace detail{
|
Chris@16
|
40
|
Chris@16
|
41 template <class T, class Policy>
|
Chris@16
|
42 struct sph_bessel_j_small_z_series_term
|
Chris@16
|
43 {
|
Chris@16
|
44 typedef T result_type;
|
Chris@16
|
45
|
Chris@16
|
46 sph_bessel_j_small_z_series_term(unsigned v_, T x)
|
Chris@16
|
47 : N(0), v(v_)
|
Chris@16
|
48 {
|
Chris@16
|
49 BOOST_MATH_STD_USING
|
Chris@16
|
50 mult = x / 2;
|
Chris@16
|
51 if(v + 3 > max_factorial<T>::value)
|
Chris@16
|
52 {
|
Chris@16
|
53 term = v * log(mult) - boost::math::lgamma(v+1+T(0.5f), Policy());
|
Chris@16
|
54 term = exp(term);
|
Chris@16
|
55 }
|
Chris@16
|
56 else
|
Chris@16
|
57 term = pow(mult, T(v)) / boost::math::tgamma(v+1+T(0.5f), Policy());
|
Chris@16
|
58 mult *= -mult;
|
Chris@16
|
59 }
|
Chris@16
|
60 T operator()()
|
Chris@16
|
61 {
|
Chris@16
|
62 T r = term;
|
Chris@16
|
63 ++N;
|
Chris@16
|
64 term *= mult / (N * T(N + v + 0.5f));
|
Chris@16
|
65 return r;
|
Chris@16
|
66 }
|
Chris@16
|
67 private:
|
Chris@16
|
68 unsigned N;
|
Chris@16
|
69 unsigned v;
|
Chris@16
|
70 T mult;
|
Chris@16
|
71 T term;
|
Chris@16
|
72 };
|
Chris@16
|
73
|
Chris@16
|
74 template <class T, class Policy>
|
Chris@16
|
75 inline T sph_bessel_j_small_z_series(unsigned v, T x, const Policy& pol)
|
Chris@16
|
76 {
|
Chris@16
|
77 BOOST_MATH_STD_USING // ADL of std names
|
Chris@16
|
78 sph_bessel_j_small_z_series_term<T, Policy> s(v, x);
|
Chris@16
|
79 boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
|
Chris@16
|
80 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
Chris@16
|
81 T zero = 0;
|
Chris@16
|
82 T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, zero);
|
Chris@16
|
83 #else
|
Chris@16
|
84 T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
|
Chris@16
|
85 #endif
|
Chris@16
|
86 policies::check_series_iterations<T>("boost::math::sph_bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol);
|
Chris@16
|
87 return result * sqrt(constants::pi<T>() / 4);
|
Chris@16
|
88 }
|
Chris@16
|
89
|
Chris@16
|
90 template <class T, class Policy>
|
Chris@16
|
91 T cyl_bessel_j_imp(T v, T x, const bessel_no_int_tag& t, const Policy& pol)
|
Chris@16
|
92 {
|
Chris@16
|
93 BOOST_MATH_STD_USING
|
Chris@16
|
94 static const char* function = "boost::math::bessel_j<%1%>(%1%,%1%)";
|
Chris@16
|
95 if(x < 0)
|
Chris@16
|
96 {
|
Chris@16
|
97 // better have integer v:
|
Chris@16
|
98 if(floor(v) == v)
|
Chris@16
|
99 {
|
Chris@16
|
100 T r = cyl_bessel_j_imp(v, T(-x), t, pol);
|
Chris@16
|
101 if(iround(v, pol) & 1)
|
Chris@16
|
102 r = -r;
|
Chris@16
|
103 return r;
|
Chris@16
|
104 }
|
Chris@16
|
105 else
|
Chris@16
|
106 return policies::raise_domain_error<T>(
|
Chris@16
|
107 function,
|
Chris@16
|
108 "Got x = %1%, but we need x >= 0", x, pol);
|
Chris@16
|
109 }
|
Chris@16
|
110
|
Chris@16
|
111 T j, y;
|
Chris@16
|
112 bessel_jy(v, x, &j, &y, need_j, pol);
|
Chris@16
|
113 return j;
|
Chris@16
|
114 }
|
Chris@16
|
115
|
Chris@16
|
116 template <class T, class Policy>
|
Chris@16
|
117 inline T cyl_bessel_j_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol)
|
Chris@16
|
118 {
|
Chris@16
|
119 BOOST_MATH_STD_USING // ADL of std names.
|
Chris@16
|
120 int ival = detail::iconv(v, pol);
|
Chris@16
|
121 // If v is an integer, use the integer recursion
|
Chris@16
|
122 // method, both that and Steeds method are O(v):
|
Chris@16
|
123 if((0 == v - ival))
|
Chris@16
|
124 {
|
Chris@16
|
125 return bessel_jn(ival, x, pol);
|
Chris@16
|
126 }
|
Chris@16
|
127 return cyl_bessel_j_imp(v, x, bessel_no_int_tag(), pol);
|
Chris@16
|
128 }
|
Chris@16
|
129
|
Chris@16
|
130 template <class T, class Policy>
|
Chris@16
|
131 inline T cyl_bessel_j_imp(int v, T x, const bessel_int_tag&, const Policy& pol)
|
Chris@16
|
132 {
|
Chris@16
|
133 BOOST_MATH_STD_USING
|
Chris@16
|
134 return bessel_jn(v, x, pol);
|
Chris@16
|
135 }
|
Chris@16
|
136
|
Chris@16
|
137 template <class T, class Policy>
|
Chris@16
|
138 inline T sph_bessel_j_imp(unsigned n, T x, const Policy& pol)
|
Chris@16
|
139 {
|
Chris@16
|
140 BOOST_MATH_STD_USING // ADL of std names
|
Chris@16
|
141 if(x < 0)
|
Chris@16
|
142 return policies::raise_domain_error<T>(
|
Chris@16
|
143 "boost::math::sph_bessel_j<%1%>(%1%,%1%)",
|
Chris@16
|
144 "Got x = %1%, but function requires x > 0.", x, pol);
|
Chris@16
|
145 //
|
Chris@16
|
146 // Special case, n == 0 resolves down to the sinus cardinal of x:
|
Chris@16
|
147 //
|
Chris@16
|
148 if(n == 0)
|
Chris@16
|
149 return boost::math::sinc_pi(x, pol);
|
Chris@16
|
150 //
|
Chris@16
|
151 // Special case for x == 0:
|
Chris@16
|
152 //
|
Chris@16
|
153 if(x == 0)
|
Chris@16
|
154 return 0;
|
Chris@16
|
155 //
|
Chris@16
|
156 // When x is small we may end up with 0/0, use series evaluation
|
Chris@16
|
157 // instead, especially as it converges rapidly:
|
Chris@16
|
158 //
|
Chris@16
|
159 if(x < 1)
|
Chris@16
|
160 return sph_bessel_j_small_z_series(n, x, pol);
|
Chris@16
|
161 //
|
Chris@16
|
162 // Default case is just a naive evaluation of the definition:
|
Chris@16
|
163 //
|
Chris@16
|
164 return sqrt(constants::pi<T>() / (2 * x))
|
Chris@16
|
165 * cyl_bessel_j_imp(T(T(n)+T(0.5f)), x, bessel_no_int_tag(), pol);
|
Chris@16
|
166 }
|
Chris@16
|
167
|
Chris@16
|
168 template <class T, class Policy>
|
Chris@16
|
169 T cyl_bessel_i_imp(T v, T x, const Policy& pol)
|
Chris@16
|
170 {
|
Chris@16
|
171 //
|
Chris@16
|
172 // This handles all the bessel I functions, note that we don't optimise
|
Chris@16
|
173 // for integer v, other than the v = 0 or 1 special cases, as Millers
|
Chris@16
|
174 // algorithm is at least as inefficient as the general case (the general
|
Chris@16
|
175 // case has better error handling too).
|
Chris@16
|
176 //
|
Chris@16
|
177 BOOST_MATH_STD_USING
|
Chris@16
|
178 if(x < 0)
|
Chris@16
|
179 {
|
Chris@16
|
180 // better have integer v:
|
Chris@16
|
181 if(floor(v) == v)
|
Chris@16
|
182 {
|
Chris@16
|
183 T r = cyl_bessel_i_imp(v, T(-x), pol);
|
Chris@16
|
184 if(iround(v, pol) & 1)
|
Chris@16
|
185 r = -r;
|
Chris@16
|
186 return r;
|
Chris@16
|
187 }
|
Chris@16
|
188 else
|
Chris@16
|
189 return policies::raise_domain_error<T>(
|
Chris@16
|
190 "boost::math::cyl_bessel_i<%1%>(%1%,%1%)",
|
Chris@16
|
191 "Got x = %1%, but we need x >= 0", x, pol);
|
Chris@16
|
192 }
|
Chris@16
|
193 if(x == 0)
|
Chris@16
|
194 {
|
Chris@16
|
195 return (v == 0) ? 1 : 0;
|
Chris@16
|
196 }
|
Chris@16
|
197 if(v == 0.5f)
|
Chris@16
|
198 {
|
Chris@16
|
199 // common special case, note try and avoid overflow in exp(x):
|
Chris@16
|
200 if(x >= tools::log_max_value<T>())
|
Chris@16
|
201 {
|
Chris@16
|
202 T e = exp(x / 2);
|
Chris@16
|
203 return e * (e / sqrt(2 * x * constants::pi<T>()));
|
Chris@16
|
204 }
|
Chris@16
|
205 return sqrt(2 / (x * constants::pi<T>())) * sinh(x);
|
Chris@16
|
206 }
|
Chris@16
|
207 if(policies::digits<T, Policy>() <= 64)
|
Chris@16
|
208 {
|
Chris@16
|
209 if(v == 0)
|
Chris@16
|
210 {
|
Chris@16
|
211 return bessel_i0(x);
|
Chris@16
|
212 }
|
Chris@16
|
213 if(v == 1)
|
Chris@16
|
214 {
|
Chris@16
|
215 return bessel_i1(x);
|
Chris@16
|
216 }
|
Chris@16
|
217 }
|
Chris@16
|
218 if((v > 0) && (x / v < 0.25))
|
Chris@16
|
219 return bessel_i_small_z_series(v, x, pol);
|
Chris@16
|
220 T I, K;
|
Chris@16
|
221 bessel_ik(v, x, &I, &K, need_i, pol);
|
Chris@16
|
222 return I;
|
Chris@16
|
223 }
|
Chris@16
|
224
|
Chris@16
|
225 template <class T, class Policy>
|
Chris@16
|
226 inline T cyl_bessel_k_imp(T v, T x, const bessel_no_int_tag& /* t */, const Policy& pol)
|
Chris@16
|
227 {
|
Chris@16
|
228 static const char* function = "boost::math::cyl_bessel_k<%1%>(%1%,%1%)";
|
Chris@16
|
229 BOOST_MATH_STD_USING
|
Chris@16
|
230 if(x < 0)
|
Chris@16
|
231 {
|
Chris@16
|
232 return policies::raise_domain_error<T>(
|
Chris@16
|
233 function,
|
Chris@16
|
234 "Got x = %1%, but we need x > 0", x, pol);
|
Chris@16
|
235 }
|
Chris@16
|
236 if(x == 0)
|
Chris@16
|
237 {
|
Chris@16
|
238 return (v == 0) ? policies::raise_overflow_error<T>(function, 0, pol)
|
Chris@16
|
239 : policies::raise_domain_error<T>(
|
Chris@16
|
240 function,
|
Chris@16
|
241 "Got x = %1%, but we need x > 0", x, pol);
|
Chris@16
|
242 }
|
Chris@16
|
243 T I, K;
|
Chris@16
|
244 bessel_ik(v, x, &I, &K, need_k, pol);
|
Chris@16
|
245 return K;
|
Chris@16
|
246 }
|
Chris@16
|
247
|
Chris@16
|
248 template <class T, class Policy>
|
Chris@16
|
249 inline T cyl_bessel_k_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol)
|
Chris@16
|
250 {
|
Chris@16
|
251 BOOST_MATH_STD_USING
|
Chris@16
|
252 if((floor(v) == v))
|
Chris@16
|
253 {
|
Chris@16
|
254 return bessel_kn(itrunc(v), x, pol);
|
Chris@16
|
255 }
|
Chris@16
|
256 return cyl_bessel_k_imp(v, x, bessel_no_int_tag(), pol);
|
Chris@16
|
257 }
|
Chris@16
|
258
|
Chris@16
|
259 template <class T, class Policy>
|
Chris@16
|
260 inline T cyl_bessel_k_imp(int v, T x, const bessel_int_tag&, const Policy& pol)
|
Chris@16
|
261 {
|
Chris@16
|
262 return bessel_kn(v, x, pol);
|
Chris@16
|
263 }
|
Chris@16
|
264
|
Chris@16
|
265 template <class T, class Policy>
|
Chris@16
|
266 inline T cyl_neumann_imp(T v, T x, const bessel_no_int_tag&, const Policy& pol)
|
Chris@16
|
267 {
|
Chris@16
|
268 static const char* function = "boost::math::cyl_neumann<%1%>(%1%,%1%)";
|
Chris@16
|
269
|
Chris@16
|
270 BOOST_MATH_INSTRUMENT_VARIABLE(v);
|
Chris@16
|
271 BOOST_MATH_INSTRUMENT_VARIABLE(x);
|
Chris@16
|
272
|
Chris@16
|
273 if(x <= 0)
|
Chris@16
|
274 {
|
Chris@16
|
275 return (v == 0) && (x == 0) ?
|
Chris@16
|
276 policies::raise_overflow_error<T>(function, 0, pol)
|
Chris@16
|
277 : policies::raise_domain_error<T>(
|
Chris@16
|
278 function,
|
Chris@16
|
279 "Got x = %1%, but result is complex for x <= 0", x, pol);
|
Chris@16
|
280 }
|
Chris@16
|
281 T j, y;
|
Chris@16
|
282 bessel_jy(v, x, &j, &y, need_y, pol);
|
Chris@16
|
283 //
|
Chris@16
|
284 // Post evaluation check for internal overflow during evaluation,
|
Chris@16
|
285 // can occur when x is small and v is large, in which case the result
|
Chris@16
|
286 // is -INF:
|
Chris@16
|
287 //
|
Chris@16
|
288 if(!(boost::math::isfinite)(y))
|
Chris@16
|
289 return -policies::raise_overflow_error<T>(function, 0, pol);
|
Chris@16
|
290 return y;
|
Chris@16
|
291 }
|
Chris@16
|
292
|
Chris@16
|
293 template <class T, class Policy>
|
Chris@16
|
294 inline T cyl_neumann_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol)
|
Chris@16
|
295 {
|
Chris@16
|
296 BOOST_MATH_STD_USING
|
Chris@16
|
297
|
Chris@16
|
298 BOOST_MATH_INSTRUMENT_VARIABLE(v);
|
Chris@16
|
299 BOOST_MATH_INSTRUMENT_VARIABLE(x);
|
Chris@16
|
300
|
Chris@16
|
301 if(floor(v) == v)
|
Chris@16
|
302 {
|
Chris@16
|
303 if(asymptotic_bessel_large_x_limit(v, x))
|
Chris@16
|
304 {
|
Chris@16
|
305 T r = asymptotic_bessel_y_large_x_2(static_cast<T>(abs(v)), x);
|
Chris@16
|
306 if((v < 0) && (itrunc(v, pol) & 1))
|
Chris@16
|
307 r = -r;
|
Chris@16
|
308 BOOST_MATH_INSTRUMENT_VARIABLE(r);
|
Chris@16
|
309 return r;
|
Chris@16
|
310 }
|
Chris@16
|
311 else
|
Chris@16
|
312 {
|
Chris@16
|
313 T r = bessel_yn(itrunc(v, pol), x, pol);
|
Chris@16
|
314 BOOST_MATH_INSTRUMENT_VARIABLE(r);
|
Chris@16
|
315 return r;
|
Chris@16
|
316 }
|
Chris@16
|
317 }
|
Chris@16
|
318 T r = cyl_neumann_imp<T>(v, x, bessel_no_int_tag(), pol);
|
Chris@16
|
319 BOOST_MATH_INSTRUMENT_VARIABLE(r);
|
Chris@16
|
320 return r;
|
Chris@16
|
321 }
|
Chris@16
|
322
|
Chris@16
|
323 template <class T, class Policy>
|
Chris@16
|
324 inline T cyl_neumann_imp(int v, T x, const bessel_int_tag&, const Policy& pol)
|
Chris@16
|
325 {
|
Chris@16
|
326 BOOST_MATH_STD_USING
|
Chris@16
|
327
|
Chris@16
|
328 BOOST_MATH_INSTRUMENT_VARIABLE(v);
|
Chris@16
|
329 BOOST_MATH_INSTRUMENT_VARIABLE(x);
|
Chris@16
|
330
|
Chris@16
|
331 if(asymptotic_bessel_large_x_limit(T(v), x))
|
Chris@16
|
332 {
|
Chris@16
|
333 T r = asymptotic_bessel_y_large_x_2(static_cast<T>(abs(v)), x);
|
Chris@16
|
334 if((v < 0) && (v & 1))
|
Chris@16
|
335 r = -r;
|
Chris@16
|
336 return r;
|
Chris@16
|
337 }
|
Chris@16
|
338 else
|
Chris@16
|
339 return bessel_yn(v, x, pol);
|
Chris@16
|
340 }
|
Chris@16
|
341
|
Chris@16
|
342 template <class T, class Policy>
|
Chris@16
|
343 inline T sph_neumann_imp(unsigned v, T x, const Policy& pol)
|
Chris@16
|
344 {
|
Chris@16
|
345 BOOST_MATH_STD_USING // ADL of std names
|
Chris@16
|
346 static const char* function = "boost::math::sph_neumann<%1%>(%1%,%1%)";
|
Chris@16
|
347 //
|
Chris@16
|
348 // Nothing much to do here but check for errors, and
|
Chris@16
|
349 // evaluate the function's definition directly:
|
Chris@16
|
350 //
|
Chris@16
|
351 if(x < 0)
|
Chris@16
|
352 return policies::raise_domain_error<T>(
|
Chris@16
|
353 function,
|
Chris@16
|
354 "Got x = %1%, but function requires x > 0.", x, pol);
|
Chris@16
|
355
|
Chris@16
|
356 if(x < 2 * tools::min_value<T>())
|
Chris@16
|
357 return -policies::raise_overflow_error<T>(function, 0, pol);
|
Chris@16
|
358
|
Chris@16
|
359 T result = cyl_neumann_imp(T(T(v)+0.5f), x, bessel_no_int_tag(), pol);
|
Chris@16
|
360 T tx = sqrt(constants::pi<T>() / (2 * x));
|
Chris@16
|
361
|
Chris@16
|
362 if((tx > 1) && (tools::max_value<T>() / tx < result))
|
Chris@16
|
363 return -policies::raise_overflow_error<T>(function, 0, pol);
|
Chris@16
|
364
|
Chris@16
|
365 return result * tx;
|
Chris@16
|
366 }
|
Chris@16
|
367
|
Chris@16
|
368 template <class T, class Policy>
|
Chris@16
|
369 inline T cyl_bessel_j_zero_imp(T v, int m, const Policy& pol)
|
Chris@16
|
370 {
|
Chris@16
|
371 BOOST_MATH_STD_USING // ADL of std names, needed for floor.
|
Chris@16
|
372
|
Chris@16
|
373 static const char* function = "boost::math::cyl_bessel_j_zero<%1%>(%1%, int)";
|
Chris@16
|
374
|
Chris@16
|
375 const T half_epsilon(boost::math::tools::epsilon<T>() / 2U);
|
Chris@16
|
376
|
Chris@16
|
377 // Handle non-finite order.
|
Chris@16
|
378 if (!(boost::math::isfinite)(v) )
|
Chris@16
|
379 {
|
Chris@16
|
380 return policies::raise_domain_error<T>(function, "Order argument is %1%, but must be finite >= 0 !", v, pol);
|
Chris@16
|
381 }
|
Chris@16
|
382
|
Chris@16
|
383 // Handle negative rank.
|
Chris@16
|
384 if(m < 0)
|
Chris@16
|
385 {
|
Chris@16
|
386 // Zeros of Jv(x) with negative rank are not defined and requesting one raises a domain error.
|
Chris@16
|
387 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero, but the rank must be positive !", m, pol);
|
Chris@16
|
388 }
|
Chris@16
|
389
|
Chris@16
|
390 // Get the absolute value of the order.
|
Chris@16
|
391 const bool order_is_negative = (v < 0);
|
Chris@16
|
392 const T vv((!order_is_negative) ? v : T(-v));
|
Chris@16
|
393
|
Chris@16
|
394 // Check if the order is very close to zero or very close to an integer.
|
Chris@16
|
395 const bool order_is_zero = (vv < half_epsilon);
|
Chris@16
|
396 const bool order_is_integer = ((vv - floor(vv)) < half_epsilon);
|
Chris@16
|
397
|
Chris@16
|
398 if(m == 0)
|
Chris@16
|
399 {
|
Chris@16
|
400 if(order_is_zero)
|
Chris@16
|
401 {
|
Chris@16
|
402 // The zero'th zero of J0(x) is not defined and requesting it raises a domain error.
|
Chris@16
|
403 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero of J0, but the rank must be > 0 !", m, pol);
|
Chris@16
|
404 }
|
Chris@16
|
405
|
Chris@16
|
406 // The zero'th zero of Jv(x) for v < 0 is not defined
|
Chris@16
|
407 // unless the order is a negative integer.
|
Chris@16
|
408 if(order_is_negative && (!order_is_integer))
|
Chris@16
|
409 {
|
Chris@16
|
410 // For non-integer, negative order, requesting the zero'th zero raises a domain error.
|
Chris@16
|
411 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero of Jv for negative, non-integer order, but the rank must be > 0 !", m, pol);
|
Chris@16
|
412 }
|
Chris@16
|
413
|
Chris@16
|
414 // The zero'th zero does exist and its value is zero.
|
Chris@16
|
415 return T(0);
|
Chris@16
|
416 }
|
Chris@16
|
417
|
Chris@16
|
418 // Set up the initial guess for the upcoming root-finding.
|
Chris@16
|
419 // If the order is a negative integer, then use the corresponding
|
Chris@16
|
420 // positive integer for the order.
|
Chris@16
|
421 const T guess_root = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess<T, Policy>((order_is_integer ? vv : v), m, pol);
|
Chris@16
|
422
|
Chris@16
|
423 // Select the maximum allowed iterations from the policy.
|
Chris@16
|
424 boost::uintmax_t number_of_iterations = policies::get_max_root_iterations<Policy>();
|
Chris@16
|
425
|
Chris@16
|
426 // Select the desired number of binary digits of precision.
|
Chris@16
|
427 // Account for the radix of number representations having non-two radix!
|
Chris@16
|
428 const int my_digits2 = policies::digits<T, Policy>();
|
Chris@16
|
429
|
Chris@16
|
430 const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U));
|
Chris@16
|
431
|
Chris@16
|
432 // Perform the root-finding using Newton-Raphson iteration from Boost.Math.
|
Chris@16
|
433 const T jvm =
|
Chris@16
|
434 boost::math::tools::newton_raphson_iterate(
|
Chris@16
|
435 boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::function_object_jv_and_jv_prime<T, Policy>((order_is_integer ? vv : v), order_is_zero, pol),
|
Chris@16
|
436 guess_root,
|
Chris@16
|
437 T(guess_root - delta_lo),
|
Chris@16
|
438 T(guess_root + 0.2F),
|
Chris@16
|
439 my_digits2,
|
Chris@16
|
440 number_of_iterations);
|
Chris@16
|
441
|
Chris@16
|
442 if(number_of_iterations >= policies::get_max_root_iterations<Policy>())
|
Chris@16
|
443 {
|
Chris@16
|
444 policies::raise_evaluation_error<T>(function, "Unable to locate root in a reasonable time:"
|
Chris@16
|
445 " Current best guess is %1%", jvm, Policy());
|
Chris@16
|
446 }
|
Chris@16
|
447
|
Chris@16
|
448 return jvm;
|
Chris@16
|
449 }
|
Chris@16
|
450
|
Chris@16
|
451 template <class T, class Policy>
|
Chris@16
|
452 inline T cyl_neumann_zero_imp(T v, int m, const Policy& pol)
|
Chris@16
|
453 {
|
Chris@16
|
454 BOOST_MATH_STD_USING // ADL of std names, needed for floor.
|
Chris@16
|
455
|
Chris@16
|
456 static const char* function = "boost::math::cyl_neumann_zero<%1%>(%1%, int)";
|
Chris@16
|
457
|
Chris@16
|
458 // Handle non-finite order.
|
Chris@16
|
459 if (!(boost::math::isfinite)(v) )
|
Chris@16
|
460 {
|
Chris@16
|
461 return policies::raise_domain_error<T>(function, "Order argument is %1%, but must be finite >= 0 !", v, pol);
|
Chris@16
|
462 }
|
Chris@16
|
463
|
Chris@16
|
464 // Handle negative rank.
|
Chris@16
|
465 if(m < 0)
|
Chris@16
|
466 {
|
Chris@16
|
467 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero, but the rank must be positive !", m, pol);
|
Chris@16
|
468 }
|
Chris@16
|
469
|
Chris@16
|
470 const T half_epsilon(boost::math::tools::epsilon<T>() / 2U);
|
Chris@16
|
471
|
Chris@16
|
472 // Get the absolute value of the order.
|
Chris@16
|
473 const bool order_is_negative = (v < 0);
|
Chris@16
|
474 const T vv((!order_is_negative) ? v : T(-v));
|
Chris@16
|
475
|
Chris@16
|
476 const bool order_is_integer = ((vv - floor(vv)) < half_epsilon);
|
Chris@16
|
477
|
Chris@16
|
478 // For negative integers, use reflection to positive integer order.
|
Chris@16
|
479 if(order_is_negative && order_is_integer)
|
Chris@16
|
480 return boost::math::detail::cyl_neumann_zero_imp(vv, m, pol);
|
Chris@16
|
481
|
Chris@16
|
482 // Check if the order is very close to a negative half-integer.
|
Chris@16
|
483 const T delta_half_integer(vv - (floor(vv) + 0.5F));
|
Chris@16
|
484
|
Chris@16
|
485 const bool order_is_negative_half_integer =
|
Chris@16
|
486 (order_is_negative && ((delta_half_integer > -half_epsilon) && (delta_half_integer < +half_epsilon)));
|
Chris@16
|
487
|
Chris@16
|
488 // The zero'th zero of Yv(x) for v < 0 is not defined
|
Chris@16
|
489 // unless the order is a negative integer.
|
Chris@16
|
490 if((m == 0) && (!order_is_negative_half_integer))
|
Chris@16
|
491 {
|
Chris@16
|
492 // For non-integer, negative order, requesting the zero'th zero raises a domain error.
|
Chris@16
|
493 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero of Yv for negative, non-half-integer order, but the rank must be > 0 !", m, pol);
|
Chris@16
|
494 }
|
Chris@16
|
495
|
Chris@16
|
496 // For negative half-integers, use the corresponding
|
Chris@16
|
497 // spherical Bessel function of positive half-integer order.
|
Chris@16
|
498 if(order_is_negative_half_integer)
|
Chris@16
|
499 return boost::math::detail::cyl_bessel_j_zero_imp(vv, m, pol);
|
Chris@16
|
500
|
Chris@16
|
501 // Set up the initial guess for the upcoming root-finding.
|
Chris@16
|
502 // If the order is a negative integer, then use the corresponding
|
Chris@16
|
503 // positive integer for the order.
|
Chris@16
|
504 const T guess_root = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess<T, Policy>(v, m, pol);
|
Chris@16
|
505
|
Chris@16
|
506 // Select the maximum allowed iterations from the policy.
|
Chris@16
|
507 boost::uintmax_t number_of_iterations = policies::get_max_root_iterations<Policy>();
|
Chris@16
|
508
|
Chris@16
|
509 // Select the desired number of binary digits of precision.
|
Chris@16
|
510 // Account for the radix of number representations having non-two radix!
|
Chris@16
|
511 const int my_digits2 = policies::digits<T, Policy>();
|
Chris@16
|
512
|
Chris@16
|
513 const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U));
|
Chris@16
|
514
|
Chris@16
|
515 // Perform the root-finding using Newton-Raphson iteration from Boost.Math.
|
Chris@16
|
516 const T yvm =
|
Chris@16
|
517 boost::math::tools::newton_raphson_iterate(
|
Chris@16
|
518 boost::math::detail::bessel_zero::cyl_neumann_zero_detail::function_object_yv_and_yv_prime<T, Policy>(v, pol),
|
Chris@16
|
519 guess_root,
|
Chris@16
|
520 T(guess_root - delta_lo),
|
Chris@16
|
521 T(guess_root + 0.2F),
|
Chris@16
|
522 my_digits2,
|
Chris@16
|
523 number_of_iterations);
|
Chris@16
|
524
|
Chris@16
|
525 if(number_of_iterations >= policies::get_max_root_iterations<Policy>())
|
Chris@16
|
526 {
|
Chris@16
|
527 policies::raise_evaluation_error<T>(function, "Unable to locate root in a reasonable time:"
|
Chris@16
|
528 " Current best guess is %1%", yvm, Policy());
|
Chris@16
|
529 }
|
Chris@16
|
530
|
Chris@16
|
531 return yvm;
|
Chris@16
|
532 }
|
Chris@16
|
533
|
Chris@16
|
534 } // namespace detail
|
Chris@16
|
535
|
Chris@16
|
536 template <class T1, class T2, class Policy>
|
Chris@16
|
537 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_j(T1 v, T2 x, const Policy& /* pol */)
|
Chris@16
|
538 {
|
Chris@16
|
539 BOOST_FPU_EXCEPTION_GUARD
|
Chris@16
|
540 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
|
Chris@16
|
541 typedef typename detail::bessel_traits<T1, T2, Policy>::optimisation_tag tag_type;
|
Chris@16
|
542 typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
Chris@16
|
543 typedef typename policies::normalise<
|
Chris@16
|
544 Policy,
|
Chris@16
|
545 policies::promote_float<false>,
|
Chris@16
|
546 policies::promote_double<false>,
|
Chris@16
|
547 policies::discrete_quantile<>,
|
Chris@16
|
548 policies::assert_undefined<> >::type forwarding_policy;
|
Chris@16
|
549 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_bessel_j_imp<value_type>(v, static_cast<value_type>(x), tag_type(), forwarding_policy()), "boost::math::cyl_bessel_j<%1%>(%1%,%1%)");
|
Chris@16
|
550 }
|
Chris@16
|
551
|
Chris@16
|
552 template <class T1, class T2>
|
Chris@16
|
553 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_j(T1 v, T2 x)
|
Chris@16
|
554 {
|
Chris@16
|
555 return cyl_bessel_j(v, x, policies::policy<>());
|
Chris@16
|
556 }
|
Chris@16
|
557
|
Chris@16
|
558 template <class T, class Policy>
|
Chris@16
|
559 inline typename detail::bessel_traits<T, T, Policy>::result_type sph_bessel(unsigned v, T x, const Policy& /* pol */)
|
Chris@16
|
560 {
|
Chris@16
|
561 BOOST_FPU_EXCEPTION_GUARD
|
Chris@16
|
562 typedef typename detail::bessel_traits<T, T, Policy>::result_type result_type;
|
Chris@16
|
563 typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
Chris@16
|
564 typedef typename policies::normalise<
|
Chris@16
|
565 Policy,
|
Chris@16
|
566 policies::promote_float<false>,
|
Chris@16
|
567 policies::promote_double<false>,
|
Chris@16
|
568 policies::discrete_quantile<>,
|
Chris@16
|
569 policies::assert_undefined<> >::type forwarding_policy;
|
Chris@16
|
570 return policies::checked_narrowing_cast<result_type, Policy>(detail::sph_bessel_j_imp<value_type>(v, static_cast<value_type>(x), forwarding_policy()), "boost::math::sph_bessel<%1%>(%1%,%1%)");
|
Chris@16
|
571 }
|
Chris@16
|
572
|
Chris@16
|
573 template <class T>
|
Chris@16
|
574 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_bessel(unsigned v, T x)
|
Chris@16
|
575 {
|
Chris@16
|
576 return sph_bessel(v, x, policies::policy<>());
|
Chris@16
|
577 }
|
Chris@16
|
578
|
Chris@16
|
579 template <class T1, class T2, class Policy>
|
Chris@16
|
580 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_i(T1 v, T2 x, const Policy& /* pol */)
|
Chris@16
|
581 {
|
Chris@16
|
582 BOOST_FPU_EXCEPTION_GUARD
|
Chris@16
|
583 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
|
Chris@16
|
584 typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
Chris@16
|
585 typedef typename policies::normalise<
|
Chris@16
|
586 Policy,
|
Chris@16
|
587 policies::promote_float<false>,
|
Chris@16
|
588 policies::promote_double<false>,
|
Chris@16
|
589 policies::discrete_quantile<>,
|
Chris@16
|
590 policies::assert_undefined<> >::type forwarding_policy;
|
Chris@16
|
591 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_bessel_i_imp<value_type>(v, static_cast<value_type>(x), forwarding_policy()), "boost::math::cyl_bessel_i<%1%>(%1%,%1%)");
|
Chris@16
|
592 }
|
Chris@16
|
593
|
Chris@16
|
594 template <class T1, class T2>
|
Chris@16
|
595 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_i(T1 v, T2 x)
|
Chris@16
|
596 {
|
Chris@16
|
597 return cyl_bessel_i(v, x, policies::policy<>());
|
Chris@16
|
598 }
|
Chris@16
|
599
|
Chris@16
|
600 template <class T1, class T2, class Policy>
|
Chris@16
|
601 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_k(T1 v, T2 x, const Policy& /* pol */)
|
Chris@16
|
602 {
|
Chris@16
|
603 BOOST_FPU_EXCEPTION_GUARD
|
Chris@16
|
604 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
|
Chris@16
|
605 typedef typename detail::bessel_traits<T1, T2, Policy>::optimisation_tag tag_type;
|
Chris@16
|
606 typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
Chris@16
|
607 typedef typename policies::normalise<
|
Chris@16
|
608 Policy,
|
Chris@16
|
609 policies::promote_float<false>,
|
Chris@16
|
610 policies::promote_double<false>,
|
Chris@16
|
611 policies::discrete_quantile<>,
|
Chris@16
|
612 policies::assert_undefined<> >::type forwarding_policy;
|
Chris@16
|
613 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_bessel_k_imp<value_type>(v, static_cast<value_type>(x), tag_type(), forwarding_policy()), "boost::math::cyl_bessel_k<%1%>(%1%,%1%)");
|
Chris@16
|
614 }
|
Chris@16
|
615
|
Chris@16
|
616 template <class T1, class T2>
|
Chris@16
|
617 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_k(T1 v, T2 x)
|
Chris@16
|
618 {
|
Chris@16
|
619 return cyl_bessel_k(v, x, policies::policy<>());
|
Chris@16
|
620 }
|
Chris@16
|
621
|
Chris@16
|
622 template <class T1, class T2, class Policy>
|
Chris@16
|
623 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_neumann(T1 v, T2 x, const Policy& /* pol */)
|
Chris@16
|
624 {
|
Chris@16
|
625 BOOST_FPU_EXCEPTION_GUARD
|
Chris@16
|
626 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
|
Chris@16
|
627 typedef typename detail::bessel_traits<T1, T2, Policy>::optimisation_tag tag_type;
|
Chris@16
|
628 typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
Chris@16
|
629 typedef typename policies::normalise<
|
Chris@16
|
630 Policy,
|
Chris@16
|
631 policies::promote_float<false>,
|
Chris@16
|
632 policies::promote_double<false>,
|
Chris@16
|
633 policies::discrete_quantile<>,
|
Chris@16
|
634 policies::assert_undefined<> >::type forwarding_policy;
|
Chris@16
|
635 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_neumann_imp<value_type>(v, static_cast<value_type>(x), tag_type(), forwarding_policy()), "boost::math::cyl_neumann<%1%>(%1%,%1%)");
|
Chris@16
|
636 }
|
Chris@16
|
637
|
Chris@16
|
638 template <class T1, class T2>
|
Chris@16
|
639 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_neumann(T1 v, T2 x)
|
Chris@16
|
640 {
|
Chris@16
|
641 return cyl_neumann(v, x, policies::policy<>());
|
Chris@16
|
642 }
|
Chris@16
|
643
|
Chris@16
|
644 template <class T, class Policy>
|
Chris@16
|
645 inline typename detail::bessel_traits<T, T, Policy>::result_type sph_neumann(unsigned v, T x, const Policy& /* pol */)
|
Chris@16
|
646 {
|
Chris@16
|
647 BOOST_FPU_EXCEPTION_GUARD
|
Chris@16
|
648 typedef typename detail::bessel_traits<T, T, Policy>::result_type result_type;
|
Chris@16
|
649 typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
Chris@16
|
650 typedef typename policies::normalise<
|
Chris@16
|
651 Policy,
|
Chris@16
|
652 policies::promote_float<false>,
|
Chris@16
|
653 policies::promote_double<false>,
|
Chris@16
|
654 policies::discrete_quantile<>,
|
Chris@16
|
655 policies::assert_undefined<> >::type forwarding_policy;
|
Chris@16
|
656 return policies::checked_narrowing_cast<result_type, Policy>(detail::sph_neumann_imp<value_type>(v, static_cast<value_type>(x), forwarding_policy()), "boost::math::sph_neumann<%1%>(%1%,%1%)");
|
Chris@16
|
657 }
|
Chris@16
|
658
|
Chris@16
|
659 template <class T>
|
Chris@16
|
660 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_neumann(unsigned v, T x)
|
Chris@16
|
661 {
|
Chris@16
|
662 return sph_neumann(v, x, policies::policy<>());
|
Chris@16
|
663 }
|
Chris@16
|
664
|
Chris@16
|
665 template <class T, class Policy>
|
Chris@16
|
666 inline typename detail::bessel_traits<T, T, Policy>::result_type cyl_bessel_j_zero(T v, int m, const Policy& /* pol */)
|
Chris@16
|
667 {
|
Chris@16
|
668 BOOST_FPU_EXCEPTION_GUARD
|
Chris@16
|
669 typedef typename detail::bessel_traits<T, T, Policy>::result_type result_type;
|
Chris@16
|
670 typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
Chris@16
|
671 typedef typename policies::normalise<
|
Chris@16
|
672 Policy,
|
Chris@16
|
673 policies::promote_float<false>,
|
Chris@16
|
674 policies::promote_double<false>,
|
Chris@16
|
675 policies::discrete_quantile<>,
|
Chris@16
|
676 policies::assert_undefined<> >::type forwarding_policy;
|
Chris@16
|
677 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<value_type>::is_integer, "Order must be a floating-point type.");
|
Chris@16
|
678 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_bessel_j_zero_imp<value_type>(v, m, forwarding_policy()), "boost::math::cyl_bessel_j_zero<%1%>(%1%,%1%)");
|
Chris@16
|
679 }
|
Chris@16
|
680
|
Chris@16
|
681 template <class T>
|
Chris@16
|
682 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type cyl_bessel_j_zero(T v, int m)
|
Chris@16
|
683 {
|
Chris@16
|
684 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Order must be a floating-point type.");
|
Chris@16
|
685 return cyl_bessel_j_zero<T, policies::policy<> >(v, m, policies::policy<>());
|
Chris@16
|
686 }
|
Chris@16
|
687
|
Chris@16
|
688 template <class T, class OutputIterator, class Policy>
|
Chris@16
|
689 inline OutputIterator cyl_bessel_j_zero(T v,
|
Chris@16
|
690 int start_index,
|
Chris@16
|
691 unsigned number_of_zeros,
|
Chris@16
|
692 OutputIterator out_it,
|
Chris@16
|
693 const Policy& pol)
|
Chris@16
|
694 {
|
Chris@16
|
695 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Order must be a floating-point type.");
|
Chris@16
|
696 for(unsigned i = 0; i < number_of_zeros; ++i)
|
Chris@16
|
697 {
|
Chris@16
|
698 *out_it = boost::math::cyl_bessel_j_zero(v, start_index + i, pol);
|
Chris@16
|
699 ++out_it;
|
Chris@16
|
700 }
|
Chris@16
|
701 return out_it;
|
Chris@16
|
702 }
|
Chris@16
|
703
|
Chris@16
|
704 template <class T, class OutputIterator>
|
Chris@16
|
705 inline OutputIterator cyl_bessel_j_zero(T v,
|
Chris@16
|
706 int start_index,
|
Chris@16
|
707 unsigned number_of_zeros,
|
Chris@16
|
708 OutputIterator out_it)
|
Chris@16
|
709 {
|
Chris@16
|
710 return cyl_bessel_j_zero(v, start_index, number_of_zeros, out_it, policies::policy<>());
|
Chris@16
|
711 }
|
Chris@16
|
712
|
Chris@16
|
713 template <class T, class Policy>
|
Chris@16
|
714 inline typename detail::bessel_traits<T, T, Policy>::result_type cyl_neumann_zero(T v, int m, const Policy& /* pol */)
|
Chris@16
|
715 {
|
Chris@16
|
716 BOOST_FPU_EXCEPTION_GUARD
|
Chris@16
|
717 typedef typename detail::bessel_traits<T, T, Policy>::result_type result_type;
|
Chris@16
|
718 typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
Chris@16
|
719 typedef typename policies::normalise<
|
Chris@16
|
720 Policy,
|
Chris@16
|
721 policies::promote_float<false>,
|
Chris@16
|
722 policies::promote_double<false>,
|
Chris@16
|
723 policies::discrete_quantile<>,
|
Chris@16
|
724 policies::assert_undefined<> >::type forwarding_policy;
|
Chris@16
|
725 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<value_type>::is_integer, "Order must be a floating-point type.");
|
Chris@16
|
726 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_neumann_zero_imp<value_type>(v, m, forwarding_policy()), "boost::math::cyl_neumann_zero<%1%>(%1%,%1%)");
|
Chris@16
|
727 }
|
Chris@16
|
728
|
Chris@16
|
729 template <class T>
|
Chris@16
|
730 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type cyl_neumann_zero(T v, int m)
|
Chris@16
|
731 {
|
Chris@16
|
732 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Order must be a floating-point type.");
|
Chris@16
|
733 return cyl_neumann_zero<T, policies::policy<> >(v, m, policies::policy<>());
|
Chris@16
|
734 }
|
Chris@16
|
735
|
Chris@16
|
736 template <class T, class OutputIterator, class Policy>
|
Chris@16
|
737 inline OutputIterator cyl_neumann_zero(T v,
|
Chris@16
|
738 int start_index,
|
Chris@16
|
739 unsigned number_of_zeros,
|
Chris@16
|
740 OutputIterator out_it,
|
Chris@16
|
741 const Policy& pol)
|
Chris@16
|
742 {
|
Chris@16
|
743 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Order must be a floating-point type.");
|
Chris@16
|
744 for(unsigned i = 0; i < number_of_zeros; ++i)
|
Chris@16
|
745 {
|
Chris@16
|
746 *out_it = boost::math::cyl_neumann_zero(v, start_index + i, pol);
|
Chris@16
|
747 ++out_it;
|
Chris@16
|
748 }
|
Chris@16
|
749 return out_it;
|
Chris@16
|
750 }
|
Chris@16
|
751
|
Chris@16
|
752 template <class T, class OutputIterator>
|
Chris@16
|
753 inline OutputIterator cyl_neumann_zero(T v,
|
Chris@16
|
754 int start_index,
|
Chris@16
|
755 unsigned number_of_zeros,
|
Chris@16
|
756 OutputIterator out_it)
|
Chris@16
|
757 {
|
Chris@16
|
758 return cyl_neumann_zero(v, start_index, number_of_zeros, out_it, policies::policy<>());
|
Chris@16
|
759 }
|
Chris@16
|
760
|
Chris@16
|
761 } // namespace math
|
Chris@16
|
762 } // namespace boost
|
Chris@16
|
763
|
Chris@16
|
764 #endif // BOOST_MATH_BESSEL_HPP
|
Chris@16
|
765
|
Chris@16
|
766
|