Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
0
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;

    }
}
Exemple #4
0
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);
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}