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