File indexing completed on 2025-01-18 09:40:09
0001
0002
0003
0004
0005
0006 #ifndef BOOST_MATH_BESSEL_DERIVATIVES_HPP
0007 #define BOOST_MATH_BESSEL_DERIVATIVES_HPP
0008
0009 #ifdef _MSC_VER
0010 # pragma once
0011 #endif
0012
0013 #include <boost/math/special_functions/math_fwd.hpp>
0014 #include <boost/math/special_functions/bessel.hpp>
0015 #include <boost/math/special_functions/detail/bessel_jy_derivatives_asym.hpp>
0016 #include <boost/math/special_functions/detail/bessel_jy_derivatives_series.hpp>
0017 #include <boost/math/special_functions/detail/bessel_derivatives_linear.hpp>
0018
0019 namespace boost{ namespace math{
0020
0021 namespace detail{
0022
0023 template <class Tag, class T, class Policy>
0024 inline T cyl_bessel_j_prime_imp(T v, T x, const Policy& pol)
0025 {
0026 static const char* const function = "boost::math::cyl_bessel_j_prime<%1%>(%1%,%1%)";
0027 BOOST_MATH_STD_USING
0028
0029
0030
0031 if (x < 0 && floor(v) != v)
0032 return boost::math::policies::raise_domain_error<T>(
0033 function,
0034 "Got x = %1%, but function requires x >= 0", x, pol);
0035
0036
0037
0038 if (x == 0)
0039 {
0040 if (v == 1)
0041 return static_cast<T>(0.5);
0042 else if (v == -1)
0043 return static_cast<T>(-0.5);
0044 else if (floor(v) == v || v > 1)
0045 return 0;
0046 else return boost::math::policies::raise_domain_error<T>(
0047 function,
0048 "Got x = %1%, but function is indeterminate for this order", x, pol);
0049 }
0050
0051
0052
0053 if (boost::math::detail::asymptotic_bessel_derivative_large_x_limit(v, x))
0054 return boost::math::detail::asymptotic_bessel_j_derivative_large_x_2(v, x, pol);
0055
0056
0057
0058 if ((abs(x) < 5) || (abs(v) > x * x / 4))
0059 {
0060 bool inversed = false;
0061 if (floor(v) == v && v < 0)
0062 {
0063 v = -v;
0064 if (itrunc(v, pol) & 1)
0065 inversed = true;
0066 }
0067 T r = boost::math::detail::bessel_j_derivative_small_z_series(v, x, pol);
0068 return inversed ? T(-r) : r;
0069 }
0070
0071
0072
0073 if (v == 0)
0074 return -boost::math::detail::cyl_bessel_j_imp<T>(1, x, Tag(), pol);
0075
0076
0077
0078 return boost::math::detail::bessel_j_derivative_linear(v, x, Tag(), pol);
0079 }
0080
0081 template <class T, class Policy>
0082 inline T sph_bessel_j_prime_imp(unsigned v, T x, const Policy& pol)
0083 {
0084 static const char* const function = "boost::math::sph_bessel_prime<%1%>(%1%,%1%)";
0085
0086
0087
0088 if (x < 0)
0089 return boost::math::policies::raise_domain_error<T>(
0090 function,
0091 "Got x = %1%, but function requires x >= 0.", x, pol);
0092
0093
0094
0095 if (v == 0)
0096 return (x == 0) ? boost::math::policies::raise_overflow_error<T>(function, nullptr, pol)
0097 : static_cast<T>(-boost::math::detail::sph_bessel_j_imp<T>(1, x, pol));
0098
0099
0100
0101 if (x == 0)
0102 return boost::math::policies::raise_domain_error<T>(
0103 function,
0104 "Got x = %1%, but function is indeterminate for this order", x, pol);
0105
0106
0107
0108 return boost::math::detail::sph_bessel_j_derivative_linear(v, x, pol);
0109 }
0110
0111 template <class T, class Policy>
0112 inline T cyl_bessel_i_prime_imp(T v, T x, const Policy& pol)
0113 {
0114 static const char* const function = "boost::math::cyl_bessel_i_prime<%1%>(%1%,%1%)";
0115 BOOST_MATH_STD_USING
0116
0117
0118
0119 if (x < 0 && floor(v) != v)
0120 return boost::math::policies::raise_domain_error<T>(
0121 function,
0122 "Got x = %1%, but function requires x >= 0", x, pol);
0123
0124
0125
0126 if (x == 0)
0127 {
0128 if (v == 1 || v == -1)
0129 return static_cast<T>(0.5);
0130 else if (floor(v) == v || v > 1)
0131 return 0;
0132 else return boost::math::policies::raise_domain_error<T>(
0133 function,
0134 "Got x = %1%, but function is indeterminate for this order", x, pol);
0135 }
0136
0137
0138
0139 if (v == 0)
0140 return boost::math::detail::cyl_bessel_i_imp<T>(1, x, pol);
0141
0142
0143
0144 return boost::math::detail::bessel_i_derivative_linear(v, x, pol);
0145 }
0146
0147 template <class Tag, class T, class Policy>
0148 inline T cyl_bessel_k_prime_imp(T v, T x, const Policy& pol)
0149 {
0150
0151
0152
0153 if (x <= 0)
0154 return boost::math::policies::raise_domain_error<T>(
0155 "boost::math::cyl_bessel_k_prime<%1%>(%1%,%1%)",
0156 "Got x = %1%, but function requires x > 0", x, pol);
0157
0158
0159
0160 if (v == 0)
0161 return -boost::math::detail::cyl_bessel_k_imp<T>(1, x, Tag(), pol);
0162
0163
0164
0165 return boost::math::detail::bessel_k_derivative_linear(v, x, Tag(), pol);
0166 }
0167
0168 template <class Tag, class T, class Policy>
0169 inline T cyl_neumann_prime_imp(T v, T x, const Policy& pol)
0170 {
0171 BOOST_MATH_STD_USING
0172
0173
0174
0175 if (x <= 0)
0176 return boost::math::policies::raise_domain_error<T>(
0177 "boost::math::cyl_neumann_prime<%1%>(%1%,%1%)",
0178 "Got x = %1%, but function requires x > 0", x, pol);
0179
0180
0181
0182 if (boost::math::detail::asymptotic_bessel_derivative_large_x_limit(v, x))
0183 return boost::math::detail::asymptotic_bessel_y_derivative_large_x_2(v, x, pol);
0184
0185
0186
0187 if (v > 0 && floor(v) != v)
0188 {
0189 const T eps = boost::math::policies::get_epsilon<T, Policy>();
0190 if (log(eps / 2) > v * log((x * x) / (v * 4)))
0191 return boost::math::detail::bessel_y_derivative_small_z_series(v, x, pol);
0192 }
0193
0194
0195
0196 if (v == 0)
0197 return -boost::math::detail::cyl_neumann_imp<T>(1, x, Tag(), pol);
0198
0199
0200
0201 return boost::math::detail::bessel_y_derivative_linear(v, x, Tag(), pol);
0202 }
0203
0204 template <class T, class Policy>
0205 inline T sph_neumann_prime_imp(unsigned v, T x, const Policy& pol)
0206 {
0207
0208
0209
0210 if (x <= 0)
0211 return boost::math::policies::raise_domain_error<T>(
0212 "boost::math::sph_neumann_prime<%1%>(%1%,%1%)",
0213 "Got x = %1%, but function requires x > 0.", x, pol);
0214
0215
0216
0217 if (v == 0)
0218 return -boost::math::detail::sph_neumann_imp<T>(1, x, pol);
0219
0220
0221
0222 return boost::math::detail::sph_neumann_derivative_linear(v, x, pol);
0223 }
0224
0225 }
0226
0227 template <class T1, class T2, class Policy>
0228 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_j_prime(T1 v, T2 x, const Policy& )
0229 {
0230 BOOST_FPU_EXCEPTION_GUARD
0231 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
0232 typedef typename detail::bessel_traits<T1, T2, Policy>::optimisation_tag tag_type;
0233 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0234 typedef typename policies::normalise<
0235 Policy,
0236 policies::promote_float<false>,
0237 policies::promote_double<false>,
0238 policies::discrete_quantile<>,
0239 policies::assert_undefined<> >::type forwarding_policy;
0240 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_bessel_j_prime_imp<tag_type, value_type>(static_cast<value_type>(v), static_cast<value_type>(x), forwarding_policy()), "boost::math::cyl_bessel_j_prime<%1%,%1%>(%1%,%1%)");
0241 }
0242
0243 template <class T1, class T2>
0244 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_j_prime(T1 v, T2 x)
0245 {
0246 return cyl_bessel_j_prime(v, x, policies::policy<>());
0247 }
0248
0249 template <class T, class Policy>
0250 inline typename detail::bessel_traits<T, T, Policy>::result_type sph_bessel_prime(unsigned v, T x, const Policy& )
0251 {
0252 BOOST_FPU_EXCEPTION_GUARD
0253 typedef typename detail::bessel_traits<T, T, Policy>::result_type result_type;
0254 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0255 typedef typename policies::normalise<
0256 Policy,
0257 policies::promote_float<false>,
0258 policies::promote_double<false>,
0259 policies::discrete_quantile<>,
0260 policies::assert_undefined<> >::type forwarding_policy;
0261 return policies::checked_narrowing_cast<result_type, Policy>(detail::sph_bessel_j_prime_imp<value_type>(v, static_cast<value_type>(x), forwarding_policy()), "boost::math::sph_bessel_j_prime<%1%>(%1%,%1%)");
0262 }
0263
0264 template <class T>
0265 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_bessel_prime(unsigned v, T x)
0266 {
0267 return sph_bessel_prime(v, x, policies::policy<>());
0268 }
0269
0270 template <class T1, class T2, class Policy>
0271 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_i_prime(T1 v, T2 x, const Policy& )
0272 {
0273 BOOST_FPU_EXCEPTION_GUARD
0274 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
0275 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0276 typedef typename policies::normalise<
0277 Policy,
0278 policies::promote_float<false>,
0279 policies::promote_double<false>,
0280 policies::discrete_quantile<>,
0281 policies::assert_undefined<> >::type forwarding_policy;
0282 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_bessel_i_prime_imp<value_type>(static_cast<value_type>(v), static_cast<value_type>(x), forwarding_policy()), "boost::math::cyl_bessel_i_prime<%1%>(%1%,%1%)");
0283 }
0284
0285 template <class T1, class T2>
0286 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_i_prime(T1 v, T2 x)
0287 {
0288 return cyl_bessel_i_prime(v, x, policies::policy<>());
0289 }
0290
0291 template <class T1, class T2, class Policy>
0292 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_k_prime(T1 v, T2 x, const Policy& )
0293 {
0294 BOOST_FPU_EXCEPTION_GUARD
0295 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
0296 typedef typename detail::bessel_traits<T1, T2, Policy>::optimisation_tag tag_type;
0297 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0298 typedef typename policies::normalise<
0299 Policy,
0300 policies::promote_float<false>,
0301 policies::promote_double<false>,
0302 policies::discrete_quantile<>,
0303 policies::assert_undefined<> >::type forwarding_policy;
0304 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_bessel_k_prime_imp<tag_type, value_type>(static_cast<value_type>(v), static_cast<value_type>(x), forwarding_policy()), "boost::math::cyl_bessel_k_prime<%1%,%1%>(%1%,%1%)");
0305 }
0306
0307 template <class T1, class T2>
0308 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_k_prime(T1 v, T2 x)
0309 {
0310 return cyl_bessel_k_prime(v, x, policies::policy<>());
0311 }
0312
0313 template <class T1, class T2, class Policy>
0314 inline typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_neumann_prime(T1 v, T2 x, const Policy& )
0315 {
0316 BOOST_FPU_EXCEPTION_GUARD
0317 typedef typename detail::bessel_traits<T1, T2, Policy>::result_type result_type;
0318 typedef typename detail::bessel_traits<T1, T2, Policy>::optimisation_tag tag_type;
0319 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0320 typedef typename policies::normalise<
0321 Policy,
0322 policies::promote_float<false>,
0323 policies::promote_double<false>,
0324 policies::discrete_quantile<>,
0325 policies::assert_undefined<> >::type forwarding_policy;
0326 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_neumann_prime_imp<tag_type, value_type>(static_cast<value_type>(v), static_cast<value_type>(x), forwarding_policy()), "boost::math::cyl_neumann_prime<%1%,%1%>(%1%,%1%)");
0327 }
0328
0329 template <class T1, class T2>
0330 inline typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_neumann_prime(T1 v, T2 x)
0331 {
0332 return cyl_neumann_prime(v, x, policies::policy<>());
0333 }
0334
0335 template <class T, class Policy>
0336 inline typename detail::bessel_traits<T, T, Policy>::result_type sph_neumann_prime(unsigned v, T x, const Policy& )
0337 {
0338 BOOST_FPU_EXCEPTION_GUARD
0339 typedef typename detail::bessel_traits<T, T, Policy>::result_type result_type;
0340 typedef typename policies::evaluation<result_type, Policy>::type value_type;
0341 typedef typename policies::normalise<
0342 Policy,
0343 policies::promote_float<false>,
0344 policies::promote_double<false>,
0345 policies::discrete_quantile<>,
0346 policies::assert_undefined<> >::type forwarding_policy;
0347 return policies::checked_narrowing_cast<result_type, Policy>(detail::sph_neumann_prime_imp<value_type>(v, static_cast<value_type>(x), forwarding_policy()), "boost::math::sph_neumann_prime<%1%>(%1%,%1%)");
0348 }
0349
0350 template <class T>
0351 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_neumann_prime(unsigned v, T x)
0352 {
0353 return sph_neumann_prime(v, x, policies::policy<>());
0354 }
0355
0356 }
0357 }
0358
0359 #endif