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