std::complex<T> hankel_imp(T v, T x, const bessel_no_int_tag&, const Policy& pol, int sign) { BOOST_MATH_STD_USING static const char* function = "boost::math::cyl_hankel_1<%1%>(%1%,%1%)"; if(x < 0) { bool isint_v = floor(v) == v; T j, y; bessel_jy(v, -x, &j, &y, need_j | need_y, pol); std::complex<T> cx(x), cv(v); std::complex<T> j_result, y_result; if(isint_v) { int s = (iround(v) & 1) ? -1 : 1; j_result = j * s; y_result = T(s) * (y - (2 / constants::pi<T>()) * (log(-x) - log(cx)) * j); } else { j_result = pow(cx, v) * pow(-cx, -v) * j; T p1 = pow(-x, v); std::complex<T> p2 = pow(cx, v); y_result = p1 * y / p2 + (p2 / p1 - p1 / p2) * j / tan(constants::pi<T>() * v); } // multiply y_result by i: y_result = std::complex<T>(-sign * y_result.imag(), sign * y_result.real()); return j_result + y_result; } if(x == 0) { if(v == 0) { // J is 1, Y is -INF return std::complex<T>(1, sign * -policies::raise_overflow_error<T>(function, 0, pol)); } else { // At least one of J and Y is complex infinity: return std::complex<T>(policies::raise_overflow_error<T>(function, 0, pol), sign * policies::raise_overflow_error<T>(function, 0, pol)); } } T j, y; bessel_jy(v, x, &j, &y, need_j | need_y, pol); return std::complex<T>(j, sign * y); }
T cyl_bessel_j_imp(T v, T x, const bessel_no_int_tag& t, const Policy& pol) { BOOST_MATH_STD_USING static const char* function = "boost::math::bessel_j<%1%>(%1%,%1%)"; if(x < 0) { // better have integer v: if(floor(v) == v) { T r = cyl_bessel_j_imp(v, T(-x), t, pol); if(iround(v, pol) & 1) r = -r; return r; } else return policies::raise_domain_error<T>( function, "Got x = %1%, but we need x >= 0", x, pol); } if(x == 0) return (v == 0) ? 1 : (v > 0) ? 0 : policies::raise_domain_error<T>( function, "Got v = %1%, but require v >= 0 or a negative integer: the result would be complex.", v, pol); if((v >= 0) && ((x < 1) || (v > x * x / 4))) { return bessel_j_small_z_series(v, x, pol); } T j, y; bessel_jy(v, x, &j, &y, need_j, pol); return j; }
void airy( double x, double *ai, double *bi, double *aip, double *bip ) { double absx, ri, rip, rj, rjp, rk, rkp, rootx, ry, ryp, z; absx = fabs(x); rootx = sqrt(absx); z = 2.0*absx*rootx/3.0; if ( x > 0.0 ) { bessel_ik( 1.0/3.0, z, &ri, &rk, &rip, &rkp ); *ai = rootx*rk/(SQRT3*PI); *bi = rootx*(rk/PI + 2.0*ri/SQRT3); bessel_ik( 2.0/3.0, z, &ri, &rk, &rip, &rkp ); *aip = -x*rk/(SQRT3*PI); *bip = x*(rk/PI + 2.0*ri/SQRT3); } else if ( x < 0.0 ) { bessel_jy( 1.0/3.0, z, &rj, &ry, &rjp, &ryp ); *ai = 0.5*rootx*(rj - ry/SQRT3); *bi = -0.5*rootx*(ry + rj/SQRT3); bessel_jy( 2.0/3.0, z, &rj, &ry, &rjp, &ryp ); *aip = 0.5*absx*(ry/SQRT3 + rj); *bip = 0.5*absx*(rj/SQRT3 - ry); } else { *ai = 0.35512420385917071; *bi = *ai*SQRT3; *aip = -0.25874932837133380; *bip = -*aip*SQRT3; } }
void sph_bessel( int n, double x, double *sj, double *sy, double *sjp, double *syp ) { double factor, order, rj, rjp, ry, ryp; if ( n < 0 || x < 0.0 ) nrerror( "Bad arguments in sph_bessel." ); order = n + 0.5; bessel_jy( x, order, &rj, &ry, &rjp, &ryp ); factor = SQRTPIO2/sqrt(x); *sj = factor*rj; *sy = factor*ry; *sjp = factor*rjp - *sj/(2.0*x); *syp = factor*ryp - *sy/(2.0*x); }
T cyl_bessel_j_imp(T v, T x, const bessel_no_int_tag& t, const Policy& pol) { BOOST_MATH_STD_USING static const char* function = "boost::math::bessel_j<%1%>(%1%,%1%)"; if(x < 0) { // better have integer v: if(floor(v) == v) { T r = cyl_bessel_j_imp(v, T(-x), t, pol); if(iround(v, pol) & 1) r = -r; return r; } else return policies::raise_domain_error<T>( function, "Got x = %1%, but we need x >= 0", x, pol); } if(x == 0) return (v == 0) ? 1 : (v > 0) ? 0 : policies::raise_domain_error<T>( function, "Got v = %1%, but require v >= 0 or a negative integer: the result would be complex.", v, pol); if((v >= 0) && ((x < 1) || (v > x * x / 4) || (x < 5))) { // // This series will actually converge rapidly for all small // x - say up to x < 20 - but the first few terms are large // and divergent which leads to large errors :-( // return bessel_j_small_z_series(v, x, pol); } T j, y; bessel_jy(v, x, &j, &y, need_j, pol); return j; }
T cyl_bessel_j_imp(T v, T x, const bessel_no_int_tag& t, const Policy& pol) { BOOST_MATH_STD_USING static const char* function = "boost::math::bessel_j<%1%>(%1%,%1%)"; if(x < 0) { // better have integer v: if(floor(v) == v) { T r = cyl_bessel_j_imp(v, T(-x), t, pol); if(iround(v, pol) & 1) r = -r; return r; } else return policies::raise_domain_error<T>( function, "Got x = %1%, but we need x >= 0", x, pol); } T j, y; bessel_jy(v, x, &j, &y, need_j, pol); return j; }