File indexing completed on 2025-10-30 08:22:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_MATH_SF_DETAIL_BESSEL_JY_ASYM_HPP
0013 #define BOOST_MATH_SF_DETAIL_BESSEL_JY_ASYM_HPP
0014
0015 #ifdef _MSC_VER
0016 #pragma once
0017 #endif
0018
0019 #include <boost/math/tools/config.hpp>
0020 #include <boost/math/constants/constants.hpp>
0021 #include <boost/math/special_functions/factorials.hpp>
0022 #include <boost/math/special_functions/fpclassify.hpp>
0023
0024 namespace boost{ namespace math{ namespace detail{
0025
0026 template <class T>
0027 BOOST_MATH_GPU_ENABLED inline T asymptotic_bessel_amplitude(T v, T x)
0028 {
0029
0030
0031 BOOST_MATH_STD_USING
0032 T s = 1;
0033 T mu = 4 * v * v;
0034 T txq = 2 * x;
0035 txq *= txq;
0036
0037 s += (mu - 1) / (2 * txq);
0038 s += 3 * (mu - 1) * (mu - 9) / (txq * txq * 8);
0039 s += 15 * (mu - 1) * (mu - 9) * (mu - 25) / (txq * txq * txq * 8 * 6);
0040
0041 return sqrt(s * 2 / (constants::pi<T>() * x));
0042 }
0043
0044 template <class T>
0045 BOOST_MATH_GPU_ENABLED T asymptotic_bessel_phase_mx(T v, T x)
0046 {
0047
0048
0049
0050
0051
0052
0053 T mu = 4 * v * v;
0054 T denom = 4 * x;
0055 T denom_mult = denom * denom;
0056
0057 T s = 0;
0058 s += (mu - 1) / (2 * denom);
0059 denom *= denom_mult;
0060 s += (mu - 1) * (mu - 25) / (6 * denom);
0061 denom *= denom_mult;
0062 s += (mu - 1) * (mu * mu - 114 * mu + 1073) / (5 * denom);
0063 denom *= denom_mult;
0064 s += (mu - 1) * (5 * mu * mu * mu - 1535 * mu * mu + 54703 * mu - 375733) / (14 * denom);
0065 return s;
0066 }
0067
0068 template <class T, class Policy>
0069 BOOST_MATH_GPU_ENABLED inline T asymptotic_bessel_y_large_x_2(T v, T x, const Policy& pol)
0070 {
0071
0072 BOOST_MATH_STD_USING
0073
0074 T ampl = asymptotic_bessel_amplitude(v, x);
0075 if (0 == ampl)
0076 return ampl;
0077 T phase = asymptotic_bessel_phase_mx(v, x);
0078 BOOST_MATH_INSTRUMENT_VARIABLE(ampl);
0079 BOOST_MATH_INSTRUMENT_VARIABLE(phase);
0080
0081
0082
0083
0084
0085
0086 T cx = cos(x);
0087 T sx = sin(x);
0088 T ci = boost::math::cos_pi(v / 2 + 0.25f, pol);
0089 T si = boost::math::sin_pi(v / 2 + 0.25f, pol);
0090 T sin_phase = sin(phase) * (cx * ci + sx * si) + cos(phase) * (sx * ci - cx * si);
0091 BOOST_MATH_INSTRUMENT_CODE(sin(phase));
0092 BOOST_MATH_INSTRUMENT_CODE(cos(x));
0093 BOOST_MATH_INSTRUMENT_CODE(cos(phase));
0094 BOOST_MATH_INSTRUMENT_CODE(sin(x));
0095 return sin_phase * ampl;
0096 }
0097
0098 template <class T, class Policy>
0099 BOOST_MATH_GPU_ENABLED inline T asymptotic_bessel_j_large_x_2(T v, T x, const Policy& pol)
0100 {
0101
0102 BOOST_MATH_STD_USING
0103
0104 T ampl = asymptotic_bessel_amplitude(v, x);
0105 if (0 == ampl)
0106 return ampl;
0107 T phase = asymptotic_bessel_phase_mx(v, x);
0108 BOOST_MATH_INSTRUMENT_VARIABLE(ampl);
0109 BOOST_MATH_INSTRUMENT_VARIABLE(phase);
0110
0111
0112
0113
0114
0115
0116 BOOST_MATH_INSTRUMENT_CODE(cos(phase));
0117 BOOST_MATH_INSTRUMENT_CODE(cos(x));
0118 BOOST_MATH_INSTRUMENT_CODE(sin(phase));
0119 BOOST_MATH_INSTRUMENT_CODE(sin(x));
0120 T cx = cos(x);
0121 T sx = sin(x);
0122 T ci = boost::math::cos_pi(v / 2 + 0.25f, pol);
0123 T si = boost::math::sin_pi(v / 2 + 0.25f, pol);
0124 T sin_phase = cos(phase) * (cx * ci + sx * si) - sin(phase) * (sx * ci - cx * si);
0125 BOOST_MATH_INSTRUMENT_VARIABLE(sin_phase);
0126 return sin_phase * ampl;
0127 }
0128
0129 template <class T>
0130 BOOST_MATH_GPU_ENABLED inline bool asymptotic_bessel_large_x_limit(int v, const T& x)
0131 {
0132 BOOST_MATH_STD_USING
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 BOOST_MATH_ASSERT(v >= 0);
0144 return (v ? v : 1) < x * 0.004f;
0145 }
0146
0147 template <class T>
0148 BOOST_MATH_GPU_ENABLED inline bool asymptotic_bessel_large_x_limit(const T& v, const T& x)
0149 {
0150 BOOST_MATH_STD_USING
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 return BOOST_MATH_GPU_SAFE_MAX(T(fabs(v)), T(1)) < x * sqrt(tools::forth_root_epsilon<T>());
0162 }
0163
0164 template <class T, class Policy>
0165 BOOST_MATH_GPU_ENABLED void temme_asymptotic_y_small_x(T v, T x, T* Y, T* Y1, const Policy& pol)
0166 {
0167 T c = 1;
0168 T p = (v / boost::math::sin_pi(v, pol)) * pow(x / 2, -v) / boost::math::tgamma(1 - v, pol);
0169 T q = (v / boost::math::sin_pi(v, pol)) * pow(x / 2, v) / boost::math::tgamma(1 + v, pol);
0170 T f = (p - q) / v;
0171 T g_prefix = boost::math::sin_pi(v / 2, pol);
0172 g_prefix *= g_prefix * 2 / v;
0173 T g = f + g_prefix * q;
0174 T h = p;
0175 T c_mult = -x * x / 4;
0176
0177 T y(c * g), y1(c * h);
0178
0179 for(int k = 1; k < policies::get_max_series_iterations<Policy>(); ++k)
0180 {
0181 f = (k * f + p + q) / (k*k - v*v);
0182 p /= k - v;
0183 q /= k + v;
0184 c *= c_mult / k;
0185 T c1 = pow(-x * x / 4, T(k)) / factorial<T>(k, pol);
0186 g = f + g_prefix * q;
0187 h = -k * g + p;
0188 y += c * g;
0189 y1 += c * h;
0190 if(c * g / tools::epsilon<T>() < y)
0191 break;
0192 }
0193
0194 *Y = -y;
0195 *Y1 = (-2 / x) * y1;
0196 }
0197
0198 template <class T, class Policy>
0199 BOOST_MATH_GPU_ENABLED T asymptotic_bessel_i_large_x(T v, T x, const Policy& pol)
0200 {
0201 BOOST_MATH_STD_USING
0202 T s = 1;
0203 T mu = 4 * v * v;
0204 T ex = 8 * x;
0205 T num = mu - 1;
0206 T denom = ex;
0207
0208 s -= num / denom;
0209
0210 num *= mu - 9;
0211 denom *= ex * 2;
0212 s += num / denom;
0213
0214 num *= mu - 25;
0215 denom *= ex * 3;
0216 s -= num / denom;
0217
0218
0219 T e = exp(x/2);
0220
0221 s = e * (e * s / sqrt(2 * x * constants::pi<T>()));
0222
0223 return (boost::math::isfinite)(s) ?
0224 s : policies::raise_overflow_error<T>("boost::math::asymptotic_bessel_i_large_x<%1%>(%1%,%1%)", nullptr, pol);
0225 }
0226
0227 }}}
0228
0229 #endif
0230