File indexing completed on 2025-01-18 09:40:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_MATH_BESSEL_HPP
0012 #define BOOST_MATH_BESSEL_HPP
0013
0014 #ifdef _MSC_VER
0015 # pragma once
0016 #endif
0017
0018 #include <limits>
0019 #include <boost/math/special_functions/math_fwd.hpp>
0020 #include <boost/math/special_functions/detail/bessel_jy.hpp>
0021 #include <boost/math/special_functions/detail/bessel_jn.hpp>
0022 #include <boost/math/special_functions/detail/bessel_yn.hpp>
0023 #include <boost/math/special_functions/detail/bessel_jy_zero.hpp>
0024 #include <boost/math/special_functions/detail/bessel_ik.hpp>
0025 #include <boost/math/special_functions/detail/bessel_i0.hpp>
0026 #include <boost/math/special_functions/detail/bessel_i1.hpp>
0027 #include <boost/math/special_functions/detail/bessel_kn.hpp>
0028 #include <boost/math/special_functions/detail/iconv.hpp>
0029 #include <boost/math/special_functions/sin_pi.hpp>
0030 #include <boost/math/special_functions/cos_pi.hpp>
0031 #include <boost/math/special_functions/sinc.hpp>
0032 #include <boost/math/special_functions/trunc.hpp>
0033 #include <boost/math/special_functions/round.hpp>
0034 #include <boost/math/tools/rational.hpp>
0035 #include <boost/math/tools/promotion.hpp>
0036 #include <boost/math/tools/series.hpp>
0037 #include <boost/math/tools/roots.hpp>
0038
0039 #ifdef _MSC_VER
0040 # pragma warning(push)
0041 # pragma warning(disable: 6326)
0042 #endif
0043
0044 namespace boost{ namespace math{
0045
0046 namespace detail{
0047
0048 template <class T, class Policy>
0049 struct sph_bessel_j_small_z_series_term
0050 {
0051 typedef T result_type;
0052
0053 sph_bessel_j_small_z_series_term(unsigned v_, T x)
0054 : N(0), v(v_)
0055 {
0056 BOOST_MATH_STD_USING
0057 mult = x / 2;
0058 if(v + 3 > max_factorial<T>::value)
0059 {
0060 term = v * log(mult) - boost::math::lgamma(v+1+T(0.5f), Policy());
0061 term = exp(term);
0062 }
0063 else
0064 term = pow(mult, T(v)) / boost::math::tgamma(v+1+T(0.5f), Policy());
0065 mult *= -mult;
0066 }
0067 T operator()()
0068 {
0069 T r = term;
0070 ++N;
0071 term *= mult / (N * T(N + v + 0.5f));
0072 return r;
0073 }
0074 private:
0075 unsigned N;
0076 unsigned v;
0077 T mult;
0078 T term;
0079 };
0080
0081 template <class T, class Policy>
0082 inline T sph_bessel_j_small_z_series(unsigned v, T x, const Policy& pol)
0083 {
0084 BOOST_MATH_STD_USING
0085 sph_bessel_j_small_z_series_term<T, Policy> s(v, x);
0086 std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
0087
0088 T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
0089
0090 policies::check_series_iterations<T>("boost::math::sph_bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol);
0091 return result * sqrt(constants::pi<T>() / 4);
0092 }
0093
0094 template <class T, class Policy>
0095 T cyl_bessel_j_imp(T v, T x, const bessel_no_int_tag& t, const Policy& pol)
0096 {
0097 BOOST_MATH_STD_USING
0098 static const char* function = "boost::math::bessel_j<%1%>(%1%,%1%)";
0099 if(x < 0)
0100 {
0101
0102 if(floor(v) == v)
0103 {
0104 T r = cyl_bessel_j_imp(v, T(-x), t, pol);
0105 if(iround(v, pol) & 1)
0106 r = -r;
0107 return r;
0108 }
0109 else
0110 return policies::raise_domain_error<T>(
0111 function,
0112 "Got x = %1%, but we need x >= 0", x, pol);
0113 }
0114
0115 T j, y;
0116 bessel_jy(v, x, &j, &y, need_j, pol);
0117 return j;
0118 }
0119
0120 template <class T, class Policy>
0121 inline T cyl_bessel_j_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol)
0122 {
0123 BOOST_MATH_STD_USING
0124 int ival = detail::iconv(v, pol);
0125
0126
0127 if((0 == v - ival))
0128 {
0129 return bessel_jn(ival, x, pol);
0130 }
0131 return cyl_bessel_j_imp(v, x, bessel_no_int_tag(), pol);
0132 }
0133
0134 template <class T, class Policy>
0135 inline T cyl_bessel_j_imp(int v, T x, const bessel_int_tag&, const Policy& pol)
0136 {
0137 BOOST_MATH_STD_USING
0138 return bessel_jn(v, x, pol);
0139 }
0140
0141 template <class T, class Policy>
0142 inline T sph_bessel_j_imp(unsigned n, T x, const Policy& pol)
0143 {
0144 BOOST_MATH_STD_USING
0145 if(x < 0)
0146 return policies::raise_domain_error<T>(
0147 "boost::math::sph_bessel_j<%1%>(%1%,%1%)",
0148 "Got x = %1%, but function requires x > 0.", x, pol);
0149
0150
0151
0152 if(n == 0)
0153 return boost::math::sinc_pi(x, pol);
0154
0155
0156
0157 if(x == 0)
0158 return 0;
0159
0160
0161
0162
0163 if(x < 1)
0164 return sph_bessel_j_small_z_series(n, x, pol);
0165
0166
0167
0168 return sqrt(constants::pi<T>() / (2 * x))
0169 * cyl_bessel_j_imp(T(T(n)+T(0.5f)), x, bessel_no_int_tag(), pol);
0170 }
0171
0172 template <class T, class Policy>
0173 T cyl_bessel_i_imp(T v, T x, const Policy& pol)
0174 {
0175
0176
0177
0178
0179
0180
0181 BOOST_MATH_STD_USING
0182 if(x < 0)
0183 {
0184
0185 if(floor(v) == v)
0186 {
0187 T r = cyl_bessel_i_imp(v, T(-x), pol);
0188 if(iround(v, pol) & 1)
0189 r = -r;
0190 return r;
0191 }
0192 else
0193 return policies::raise_domain_error<T>(
0194 "boost::math::cyl_bessel_i<%1%>(%1%,%1%)",
0195 "Got x = %1%, but we need x >= 0", x, pol);
0196 }
0197 if(x == 0)
0198 {
0199 return (v == 0) ? static_cast<T>(1) : static_cast<T>(0);
0200 }
0201 if(v == 0.5f)
0202 {
0203
0204 if(x >= tools::log_max_value<T>())
0205 {
0206 T e = exp(x / 2);
0207 return e * (e / sqrt(2 * x * constants::pi<T>()));
0208 }
0209 return sqrt(2 / (x * constants::pi<T>())) * sinh(x);
0210 }
0211 if((policies::digits<T, Policy>() <= 113) && (std::numeric_limits<T>::digits <= 113) && (std::numeric_limits<T>::radix == 2))
0212 {
0213 if(v == 0)
0214 {
0215 return bessel_i0(x);
0216 }
0217 if(v == 1)
0218 {
0219 return bessel_i1(x);
0220 }
0221 }
0222 if((v > 0) && (x / v < 0.25))
0223 return bessel_i_small_z_series(v, x, pol);
0224 T I, K;
0225 bessel_ik(v, x, &I, &K, need_i, pol);
0226 return I;
0227 }
0228
0229 template <class T, class Policy>
0230 inline T cyl_bessel_k_imp(T v, T x, const bessel_no_int_tag& , const Policy& pol)
0231 {
0232 static const char* function = "boost::math::cyl_bessel_k<%1%>(%1%,%1%)";
0233 BOOST_MATH_STD_USING
0234 if(x < 0)
0235 {
0236 return policies::raise_domain_error<T>(
0237 function,
0238 "Got x = %1%, but we need x > 0", x, pol);
0239 }
0240 if(x == 0)
0241 {
0242 return (v == 0) ? policies::raise_overflow_error<T>(function, nullptr, pol)
0243 : policies::raise_domain_error<T>(
0244 function,
0245 "Got x = %1%, but we need x > 0", x, pol);
0246 }
0247 T I, K;
0248 bessel_ik(v, x, &I, &K, need_k, pol);
0249 return K;
0250 }
0251
0252 template <class T, class Policy>
0253 inline T cyl_bessel_k_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol)
0254 {
0255 BOOST_MATH_STD_USING
0256 if((floor(v) == v))
0257 {
0258 return bessel_kn(itrunc(v), x, pol);
0259 }
0260 return cyl_bessel_k_imp(v, x, bessel_no_int_tag(), pol);
0261 }
0262
0263 template <class T, class Policy>
0264 inline T cyl_bessel_k_imp(int v, T x, const bessel_int_tag&, const Policy& pol)
0265 {
0266 return bessel_kn(v, x, pol);
0267 }
0268
0269 template <class T, class Policy>
0270 inline T cyl_neumann_imp(T v, T x, const bessel_no_int_tag&, const Policy& pol)
0271 {
0272 static const char* function = "boost::math::cyl_neumann<%1%>(%1%,%1%)";
0273
0274 BOOST_MATH_INSTRUMENT_VARIABLE(v);
0275 BOOST_MATH_INSTRUMENT_VARIABLE(x);
0276
0277 if(x <= 0)
0278 {
0279 return (v == 0) && (x == 0) ?
0280 policies::raise_overflow_error<T>(function, nullptr, pol)
0281 : policies::raise_domain_error<T>(
0282 function,
0283 "Got x = %1%, but result is complex for x <= 0", x, pol);
0284 }
0285 T j, y;
0286 bessel_jy(v, x, &j, &y, need_y, pol);
0287
0288
0289
0290
0291
0292 if(!(boost::math::isfinite)(y))
0293 return -policies::raise_overflow_error<T>(function, nullptr, pol);
0294 return y;
0295 }
0296
0297 template <class T, class Policy>
0298 inline T cyl_neumann_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol)
0299 {
0300 BOOST_MATH_STD_USING
0301
0302 BOOST_MATH_INSTRUMENT_VARIABLE(v);
0303 BOOST_MATH_INSTRUMENT_VARIABLE(x);
0304
0305 if(floor(v) == v)
0306 {
0307 T r = bessel_yn(itrunc(v, pol), x, pol);
0308 BOOST_MATH_INSTRUMENT_VARIABLE(r);
0309 return r;
0310 }
0311 T r = cyl_neumann_imp<T>(v, x, bessel_no_int_tag(), pol);
0312 BOOST_MATH_INSTRUMENT_VARIABLE(r);
0313 return r;
0314 }
0315
0316 template <class T, class Policy>
0317 inline T cyl_neumann_imp(int v, T x, const bessel_int_tag&, const Policy& pol)
0318 {
0319 return bessel_yn(v, x, pol);
0320 }
0321
0322 template <class T, class Policy>
0323 inline T sph_neumann_imp(unsigned v, T x, const Policy& pol)
0324 {
0325 BOOST_MATH_STD_USING
0326 static const char* function = "boost::math::sph_neumann<%1%>(%1%,%1%)";
0327
0328
0329
0330
0331 if(x < 0)
0332 return policies::raise_domain_error<T>(
0333 function,
0334 "Got x = %1%, but function requires x > 0.", x, pol);
0335
0336 if(x < 2 * tools::min_value<T>())
0337 return -policies::raise_overflow_error<T>(function, nullptr, pol);
0338
0339 T result = cyl_neumann_imp(T(T(v)+0.5f), x, bessel_no_int_tag(), pol);
0340 T tx = sqrt(constants::pi<T>() / (2 * x));
0341
0342 if((tx > 1) && (tools::max_value<T>() / tx < result))
0343 return -policies::raise_overflow_error<T>(function, nullptr, pol);
0344
0345 return result * tx;
0346 }
0347
0348 template <class T, class Policy>
0349 inline T cyl_bessel_j_zero_imp(T v, int m, const Policy& pol)
0350 {
0351 BOOST_MATH_STD_USING
0352
0353 static const char* function = "boost::math::cyl_bessel_j_zero<%1%>(%1%, int)";
0354
0355 const T half_epsilon(boost::math::tools::epsilon<T>() / 2U);
0356
0357
0358 if (!(boost::math::isfinite)(v) )
0359 {
0360 return policies::raise_domain_error<T>(function, "Order argument is %1%, but must be finite >= 0 !", v, pol);
0361 }
0362
0363
0364 if(m < 0)
0365 {
0366
0367 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero, but the rank must be positive !", static_cast<T>(m), pol);
0368 }
0369
0370
0371 const bool order_is_negative = (v < 0);
0372 const T vv((!order_is_negative) ? v : T(-v));
0373
0374
0375 const bool order_is_zero = (vv < half_epsilon);
0376 const bool order_is_integer = ((vv - floor(vv)) < half_epsilon);
0377
0378 if(m == 0)
0379 {
0380 if(order_is_zero)
0381 {
0382
0383 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);
0384 }
0385
0386
0387
0388 if(order_is_negative && (!order_is_integer))
0389 {
0390
0391 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);
0392 }
0393
0394
0395 return T(0);
0396 }
0397
0398
0399
0400
0401 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);
0402
0403
0404 std::uintmax_t number_of_iterations = policies::get_max_root_iterations<Policy>();
0405
0406 const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U));
0407
0408
0409 const T jvm =
0410 boost::math::tools::newton_raphson_iterate(
0411 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),
0412 guess_root,
0413 T(guess_root - delta_lo),
0414 T(guess_root + 0.2F),
0415 policies::digits<T, Policy>(),
0416 number_of_iterations);
0417
0418 if(number_of_iterations >= policies::get_max_root_iterations<Policy>())
0419 {
0420 return policies::raise_evaluation_error<T>(function, "Unable to locate root in a reasonable time:"
0421 " Current best guess is %1%", jvm, Policy());
0422 }
0423
0424 return jvm;
0425 }
0426
0427 template <class T, class Policy>
0428 inline T cyl_neumann_zero_imp(T v, int m, const Policy& pol)
0429 {
0430 BOOST_MATH_STD_USING
0431
0432 static const char* function = "boost::math::cyl_neumann_zero<%1%>(%1%, int)";
0433
0434
0435 if (!(boost::math::isfinite)(v) )
0436 {
0437 return policies::raise_domain_error<T>(function, "Order argument is %1%, but must be finite >= 0 !", v, pol);
0438 }
0439
0440
0441 if(m < 0)
0442 {
0443 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero, but the rank must be positive !", static_cast<T>(m), pol);
0444 }
0445
0446 const T half_epsilon(boost::math::tools::epsilon<T>() / 2U);
0447
0448
0449 const bool order_is_negative = (v < 0);
0450 const T vv((!order_is_negative) ? v : T(-v));
0451
0452 const bool order_is_integer = ((vv - floor(vv)) < half_epsilon);
0453
0454
0455 if(order_is_negative && order_is_integer)
0456 return boost::math::detail::cyl_neumann_zero_imp(vv, m, pol);
0457
0458
0459 const T delta_half_integer(vv - (floor(vv) + 0.5F));
0460
0461 const bool order_is_negative_half_integer =
0462 (order_is_negative && ((delta_half_integer > -half_epsilon) && (delta_half_integer < +half_epsilon)));
0463
0464
0465
0466 if((m == 0) && (!order_is_negative_half_integer))
0467 {
0468
0469 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);
0470 }
0471
0472
0473
0474 if(order_is_negative_half_integer)
0475 return boost::math::detail::cyl_bessel_j_zero_imp(vv, m, pol);
0476
0477
0478
0479
0480 const T guess_root = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess<T, Policy>(v, m, pol);
0481
0482
0483 std::uintmax_t number_of_iterations = policies::get_max_root_iterations<Policy>();
0484
0485 const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U));
0486
0487
0488 const T yvm =
0489 boost::math::tools::newton_raphson_iterate(
0490 boost::math::detail::bessel_zero::cyl_neumann_zero_detail::function_object_yv_and_yv_prime<T, Policy>(v, pol),
0491 guess_root,
0492 T(guess_root - delta_lo),
0493 T(guess_root + 0.2F),
0494 policies::digits<T, Policy>(),
0495 number_of_iterations);
0496
0497 if(number_of_iterations >= policies::get_max_root_iterations<Policy>())
0498 {
0499 return policies::raise_evaluation_error<T>(function, "Unable to locate root in a reasonable time:"
0500 " Current best guess is %1%", yvm, Policy());
0501 }
0502
0503 return yvm;
0504 }
0505
0506 }
0507
0508 template <class T1, class T2, class Policy>
0509 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_j(T1 v, T2 x, const Policy& )
0510 {
0511 BOOST_FPU_EXCEPTION_GUARD
0512 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
0513 typedef typename detail::bessel_traits<T1, T2, Policy>::optimisation_tag tag_type;
0514 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0515 typedef typename policies::normalise<
0516 Policy,
0517 policies::promote_float<false>,
0518 policies::promote_double<false>,
0519 policies::discrete_quantile<>,
0520 policies::assert_undefined<> >::type forwarding_policy;
0521 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%)");
0522 }
0523
0524 template <class T1, class T2>
0525 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_j(T1 v, T2 x)
0526 {
0527 return cyl_bessel_j(v, x, policies::policy<>());
0528 }
0529
0530 template <class T, class Policy>
0531 inline typename detail::bessel_traits<T, T, Policy>::result_type sph_bessel(unsigned v, T x, const Policy& )
0532 {
0533 BOOST_FPU_EXCEPTION_GUARD
0534 typedef typename detail::bessel_traits<T, T, Policy>::result_type result_type;
0535 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0536 typedef typename policies::normalise<
0537 Policy,
0538 policies::promote_float<false>,
0539 policies::promote_double<false>,
0540 policies::discrete_quantile<>,
0541 policies::assert_undefined<> >::type forwarding_policy;
0542 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%)");
0543 }
0544
0545 template <class T>
0546 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_bessel(unsigned v, T x)
0547 {
0548 return sph_bessel(v, x, policies::policy<>());
0549 }
0550
0551 template <class T1, class T2, class Policy>
0552 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_i(T1 v, T2 x, const Policy& )
0553 {
0554 BOOST_FPU_EXCEPTION_GUARD
0555 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
0556 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0557 typedef typename policies::normalise<
0558 Policy,
0559 policies::promote_float<false>,
0560 policies::promote_double<false>,
0561 policies::discrete_quantile<>,
0562 policies::assert_undefined<> >::type forwarding_policy;
0563 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_bessel_i_imp<value_type>(static_cast<value_type>(v), static_cast<value_type>(x), forwarding_policy()), "boost::math::cyl_bessel_i<%1%>(%1%,%1%)");
0564 }
0565
0566 template <class T1, class T2>
0567 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_i(T1 v, T2 x)
0568 {
0569 return cyl_bessel_i(v, x, policies::policy<>());
0570 }
0571
0572 template <class T1, class T2, class Policy>
0573 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_k(T1 v, T2 x, const Policy& )
0574 {
0575 BOOST_FPU_EXCEPTION_GUARD
0576 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
0577 typedef typename detail::bessel_traits<T1, T2, Policy>::optimisation_tag128 tag_type;
0578 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0579 typedef typename policies::normalise<
0580 Policy,
0581 policies::promote_float<false>,
0582 policies::promote_double<false>,
0583 policies::discrete_quantile<>,
0584 policies::assert_undefined<> >::type forwarding_policy;
0585 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%)");
0586 }
0587
0588 template <class T1, class T2>
0589 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_k(T1 v, T2 x)
0590 {
0591 return cyl_bessel_k(v, x, policies::policy<>());
0592 }
0593
0594 template <class T1, class T2, class Policy>
0595 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_neumann(T1 v, T2 x, const Policy& )
0596 {
0597 BOOST_FPU_EXCEPTION_GUARD
0598 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
0599 typedef typename detail::bessel_traits<T1, T2, Policy>::optimisation_tag tag_type;
0600 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0601 typedef typename policies::normalise<
0602 Policy,
0603 policies::promote_float<false>,
0604 policies::promote_double<false>,
0605 policies::discrete_quantile<>,
0606 policies::assert_undefined<> >::type forwarding_policy;
0607 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%)");
0608 }
0609
0610 template <class T1, class T2>
0611 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_neumann(T1 v, T2 x)
0612 {
0613 return cyl_neumann(v, x, policies::policy<>());
0614 }
0615
0616 template <class T, class Policy>
0617 inline typename detail::bessel_traits<T, T, Policy>::result_type sph_neumann(unsigned v, T x, const Policy& )
0618 {
0619 BOOST_FPU_EXCEPTION_GUARD
0620 typedef typename detail::bessel_traits<T, T, Policy>::result_type result_type;
0621 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0622 typedef typename policies::normalise<
0623 Policy,
0624 policies::promote_float<false>,
0625 policies::promote_double<false>,
0626 policies::discrete_quantile<>,
0627 policies::assert_undefined<> >::type forwarding_policy;
0628 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%)");
0629 }
0630
0631 template <class T>
0632 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_neumann(unsigned v, T x)
0633 {
0634 return sph_neumann(v, x, policies::policy<>());
0635 }
0636
0637 template <class T, class Policy>
0638 inline typename detail::bessel_traits<T, T, Policy>::result_type cyl_bessel_j_zero(T v, int m, const Policy& )
0639 {
0640 BOOST_FPU_EXCEPTION_GUARD
0641 typedef typename detail::bessel_traits<T, T, Policy>::result_type result_type;
0642 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0643 typedef typename policies::normalise<
0644 Policy,
0645 policies::promote_float<false>,
0646 policies::promote_double<false>,
0647 policies::discrete_quantile<>,
0648 policies::assert_undefined<> >::type forwarding_policy;
0649
0650 static_assert( false == std::numeric_limits<T>::is_specialized
0651 || ( true == std::numeric_limits<T>::is_specialized
0652 && false == std::numeric_limits<T>::is_integer),
0653 "Order must be a floating-point type.");
0654
0655 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%)");
0656 }
0657
0658 template <class T>
0659 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type cyl_bessel_j_zero(T v, int m)
0660 {
0661 static_assert( false == std::numeric_limits<T>::is_specialized
0662 || ( true == std::numeric_limits<T>::is_specialized
0663 && false == std::numeric_limits<T>::is_integer),
0664 "Order must be a floating-point type.");
0665
0666 return cyl_bessel_j_zero<T, policies::policy<> >(v, m, policies::policy<>());
0667 }
0668
0669 template <class T, class OutputIterator, class Policy>
0670 inline OutputIterator cyl_bessel_j_zero(T v,
0671 int start_index,
0672 unsigned number_of_zeros,
0673 OutputIterator out_it,
0674 const Policy& pol)
0675 {
0676 static_assert( false == std::numeric_limits<T>::is_specialized
0677 || ( true == std::numeric_limits<T>::is_specialized
0678 && false == std::numeric_limits<T>::is_integer),
0679 "Order must be a floating-point type.");
0680
0681 for(int i = 0; i < static_cast<int>(number_of_zeros); ++i)
0682 {
0683 *out_it = boost::math::cyl_bessel_j_zero(v, start_index + i, pol);
0684 ++out_it;
0685 }
0686 return out_it;
0687 }
0688
0689 template <class T, class OutputIterator>
0690 inline OutputIterator cyl_bessel_j_zero(T v,
0691 int start_index,
0692 unsigned number_of_zeros,
0693 OutputIterator out_it)
0694 {
0695 return cyl_bessel_j_zero(v, start_index, number_of_zeros, out_it, policies::policy<>());
0696 }
0697
0698 template <class T, class Policy>
0699 inline typename detail::bessel_traits<T, T, Policy>::result_type cyl_neumann_zero(T v, int m, const Policy& )
0700 {
0701 BOOST_FPU_EXCEPTION_GUARD
0702 typedef typename detail::bessel_traits<T, T, Policy>::result_type result_type;
0703 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0704 typedef typename policies::normalise<
0705 Policy,
0706 policies::promote_float<false>,
0707 policies::promote_double<false>,
0708 policies::discrete_quantile<>,
0709 policies::assert_undefined<> >::type forwarding_policy;
0710
0711 static_assert( false == std::numeric_limits<T>::is_specialized
0712 || ( true == std::numeric_limits<T>::is_specialized
0713 && false == std::numeric_limits<T>::is_integer),
0714 "Order must be a floating-point type.");
0715
0716 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%)");
0717 }
0718
0719 template <class T>
0720 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type cyl_neumann_zero(T v, int m)
0721 {
0722 static_assert( false == std::numeric_limits<T>::is_specialized
0723 || ( true == std::numeric_limits<T>::is_specialized
0724 && false == std::numeric_limits<T>::is_integer),
0725 "Order must be a floating-point type.");
0726
0727 return cyl_neumann_zero<T, policies::policy<> >(v, m, policies::policy<>());
0728 }
0729
0730 template <class T, class OutputIterator, class Policy>
0731 inline OutputIterator cyl_neumann_zero(T v,
0732 int start_index,
0733 unsigned number_of_zeros,
0734 OutputIterator out_it,
0735 const Policy& pol)
0736 {
0737 static_assert( false == std::numeric_limits<T>::is_specialized
0738 || ( true == std::numeric_limits<T>::is_specialized
0739 && false == std::numeric_limits<T>::is_integer),
0740 "Order must be a floating-point type.");
0741
0742 for(int i = 0; i < static_cast<int>(number_of_zeros); ++i)
0743 {
0744 *out_it = boost::math::cyl_neumann_zero(v, start_index + i, pol);
0745 ++out_it;
0746 }
0747 return out_it;
0748 }
0749
0750 template <class T, class OutputIterator>
0751 inline OutputIterator cyl_neumann_zero(T v,
0752 int start_index,
0753 unsigned number_of_zeros,
0754 OutputIterator out_it)
0755 {
0756 return cyl_neumann_zero(v, start_index, number_of_zeros, out_it, policies::policy<>());
0757 }
0758
0759 }
0760 }
0761
0762 #ifdef _MSC_VER
0763 # pragma warning(pop)
0764 #endif
0765
0766 #endif
0767
0768