File indexing completed on 2025-01-18 09:40:00
0001
0002
0003
0004
0005
0006 #ifndef BOOST_MATH_BESSEL_JY_DERIVATIVES_SERIES_HPP
0007 #define BOOST_MATH_BESSEL_JY_DERIVATIVES_SERIES_HPP
0008
0009 #ifdef _MSC_VER
0010 #pragma once
0011 #endif
0012
0013 #include <cmath>
0014 #include <cstdint>
0015
0016 namespace boost{ namespace math{ namespace detail{
0017
0018 template <class T, class Policy>
0019 struct bessel_j_derivative_small_z_series_term
0020 {
0021 typedef T result_type;
0022
0023 bessel_j_derivative_small_z_series_term(T v_, T x)
0024 : N(0), v(v_), term(1), mult(x / 2)
0025 {
0026 mult *= -mult;
0027
0028
0029 if (v == 0)
0030 iterate();
0031 }
0032 T operator()()
0033 {
0034 T r = term * (v + 2 * N);
0035 iterate();
0036 return r;
0037 }
0038 private:
0039 void iterate()
0040 {
0041 ++N;
0042 term *= mult / (N * (N + v));
0043 }
0044 unsigned N;
0045 T v;
0046 T term;
0047 T mult;
0048 };
0049
0050
0051
0052
0053
0054 template <class T, class Policy>
0055 inline T bessel_j_derivative_small_z_series(T v, T x, const Policy& pol)
0056 {
0057 BOOST_MATH_STD_USING
0058 T prefix;
0059 if (v < boost::math::max_factorial<T>::value)
0060 {
0061 prefix = pow(x / 2, v - 1) / 2 / boost::math::tgamma(v + 1, pol);
0062 }
0063 else
0064 {
0065 prefix = (v - 1) * log(x / 2) - constants::ln_two<T>() - boost::math::lgamma(v + 1, pol);
0066 prefix = exp(prefix);
0067 }
0068 if (0 == prefix)
0069 return prefix;
0070
0071 bessel_j_derivative_small_z_series_term<T, Policy> s(v, x);
0072 std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations<Policy>();
0073
0074 T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
0075
0076 boost::math::policies::check_series_iterations<T>("boost::math::bessel_j_derivative_small_z_series<%1%>(%1%,%1%)", max_iter, pol);
0077 return prefix * result;
0078 }
0079
0080 template <class T, class Policy>
0081 struct bessel_y_derivative_small_z_series_term_a
0082 {
0083 typedef T result_type;
0084
0085 bessel_y_derivative_small_z_series_term_a(T v_, T x)
0086 : N(0), v(v_)
0087 {
0088 mult = x / 2;
0089 mult *= -mult;
0090 term = 1;
0091 }
0092 T operator()()
0093 {
0094 T r = term * (-v + 2 * N);
0095 ++N;
0096 term *= mult / (N * (N - v));
0097 return r;
0098 }
0099 private:
0100 unsigned N;
0101 T v;
0102 T mult;
0103 T term;
0104 };
0105
0106 template <class T, class Policy>
0107 struct bessel_y_derivative_small_z_series_term_b
0108 {
0109 typedef T result_type;
0110
0111 bessel_y_derivative_small_z_series_term_b(T v_, T x)
0112 : N(0), v(v_)
0113 {
0114 mult = x / 2;
0115 mult *= -mult;
0116 term = 1;
0117 }
0118 T operator()()
0119 {
0120 T r = term * (v + 2 * N);
0121 ++N;
0122 term *= mult / (N * (N + v));
0123 return r;
0124 }
0125 private:
0126 unsigned N;
0127 T v;
0128 T mult;
0129 T term;
0130 };
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140 template <class T, class Policy>
0141 inline T bessel_y_derivative_small_z_series(T v, T x, const Policy& pol)
0142 {
0143 BOOST_MATH_STD_USING
0144 static const char* function = "bessel_y_derivative_small_z_series<%1%>(%1%,%1%)";
0145 T prefix;
0146 T gam;
0147 T p = log(x / 2);
0148 T scale = 1;
0149 bool need_logs = (v >= boost::math::max_factorial<T>::value) || (boost::math::tools::log_max_value<T>() / v < fabs(p));
0150 if (!need_logs)
0151 {
0152 gam = boost::math::tgamma(v, pol);
0153 p = pow(x / 2, v + 1) * 2;
0154 if (boost::math::tools::max_value<T>() * p < gam)
0155 {
0156 scale /= gam;
0157 gam = 1;
0158 if (boost::math::tools::max_value<T>() * p < gam)
0159 {
0160
0161 return boost::math::policies::raise_overflow_error<T>(function, nullptr, pol);
0162 }
0163 }
0164 prefix = -gam / (boost::math::constants::pi<T>() * p);
0165 }
0166 else
0167 {
0168 gam = boost::math::lgamma(v, pol);
0169 p = (v + 1) * p + constants::ln_two<T>();
0170 prefix = gam - log(boost::math::constants::pi<T>()) - p;
0171 if (boost::math::tools::log_max_value<T>() < prefix)
0172 {
0173 prefix -= log(boost::math::tools::max_value<T>() / 4);
0174 scale /= (boost::math::tools::max_value<T>() / 4);
0175 if (boost::math::tools::log_max_value<T>() < prefix)
0176 {
0177 return boost::math::policies::raise_overflow_error<T>(function, nullptr, pol);
0178 }
0179 }
0180 prefix = -exp(prefix);
0181 }
0182 bessel_y_derivative_small_z_series_term_a<T, Policy> s(v, x);
0183 std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations<Policy>();
0184
0185 T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
0186
0187 boost::math::policies::check_series_iterations<T>("boost::math::bessel_y_derivative_small_z_series<%1%>(%1%,%1%)", max_iter, pol);
0188 result *= prefix;
0189
0190 p = pow(x / 2, v - 1) / 2;
0191 if (!need_logs)
0192 {
0193 prefix = boost::math::tgamma(-v, pol) * boost::math::cos_pi(v, pol) * p / boost::math::constants::pi<T>();
0194 }
0195 else
0196 {
0197 int sgn {};
0198 prefix = boost::math::lgamma(-v, &sgn, pol) + (v - 1) * log(x / 2) - constants::ln_two<T>();
0199 prefix = exp(prefix) * sgn / boost::math::constants::pi<T>();
0200 }
0201 bessel_y_derivative_small_z_series_term_b<T, Policy> s2(v, x);
0202 max_iter = boost::math::policies::get_max_series_iterations<Policy>();
0203
0204 T b = boost::math::tools::sum_series(s2, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
0205
0206 result += scale * prefix * b;
0207 return result;
0208 }
0209
0210
0211
0212
0213
0214 }}}
0215
0216 #endif