Beispiel #1
0
/// Airy Ai function.
double
airy_ai(double x)
{
  const gsl_mode_t mode = GSL_PREC_DOUBLE;
  gsl_sf_result result;
  int stat = gsl_sf_airy_Ai_e(x, mode, &result);
  if (stat != GSL_SUCCESS)
    {
      std::ostringstream msg("Error in airy_ai:");
      msg << " x=" << x;
      throw std::runtime_error(msg.str());
    }
  else
    return result.val;
}
/* uniform asymptotic, nu -> Inf, [Abramowitz+Stegun, 9.3.35]
 *
 * error:
 *    nu =  2: uniformly good to >  6D
 *    nu =  5: uniformly good to >  8D
 *    nu = 10: uniformly good to > 10D
 *    nu = 20: uniformly good to > 13D
 *
 */
int gsl_sf_bessel_Jnu_asymp_Olver_e(double nu, double x, gsl_sf_result * result)
{
  /* CHECK_POINTER(result) */

  if(x <= 0.0 || nu <= 0.0) {
    DOMAIN_ERROR(result);
  }  
  else {
    double zeta, abs_zeta;
    double arg;
    double pre;
    double asum, bsum, asum_err;
    gsl_sf_result ai;
    gsl_sf_result aip;
    double z = x/nu;
    double crnu = pow(nu, 1.0/3.0);
    double nu3  = nu*nu*nu;
    double nu11 = nu3*nu3*nu3*nu*nu;
    int stat_a, stat_ap;

    if(fabs(1.0-z) < 0.02) {
      const double a = 1.0-z;
      const double c0 = 1.25992104989487316476721060728;
      const double c1 = 0.37797631496846194943016318218;
      const double c2 = 0.230385563409348235843147082474;
      const double c3 = 0.165909603649648694839821892031;
      const double c4 = 0.12931387086451008907;
      const double c5 = 0.10568046188858133991;
      const double c6 = 0.08916997952268186978;
      const double c7 = 0.07700014900618802456;
      pre = c0 + a*(c1 + a*(c2 + a*(c3 + a*(c4 + a*(c5 + a*(c6 + a*c7))))));
      zeta = a * pre;
      pre  = sqrt(2.0*sqrt(pre/(1.0+z)));
      abs_zeta = fabs(zeta);
    }
    else if(z < 1.0) {
      double rt   = sqrt(1.0 - z*z);
      abs_zeta = pow(1.5*(log((1.0+rt)/z) - rt), 2.0/3.0);
      zeta = abs_zeta;
      pre  = sqrt(2.0*sqrt(abs_zeta/(rt*rt)));
    }
    else {
      /* z > 1 */
      double rt = z * sqrt(1.0 - 1.0/(z*z));
      abs_zeta = pow(1.5*(rt - acos(1.0/z)), 2.0/3.0);
      zeta = -abs_zeta;
      pre  = sqrt(2.0*sqrt(abs_zeta/(rt*rt)));
    }

    asum = olver_Asum(nu, z, abs_zeta, &asum_err);
    bsum = olver_Bsum(nu, z, abs_zeta);

    arg  = crnu*crnu * zeta;
    stat_a  = gsl_sf_airy_Ai_e(arg, GSL_MODE_DEFAULT, &ai);
    stat_ap = gsl_sf_airy_Ai_deriv_e(arg, GSL_MODE_DEFAULT, &aip);

    result->val  = pre * (ai.val*asum/crnu + aip.val*bsum/(nu*crnu*crnu));
    result->err  = pre * (ai.err * fabs(asum/crnu));
    result->err += pre * fabs(ai.val) * asum_err / crnu;
    result->err += pre * fabs(ai.val * asum) / (crnu*nu11);
    result->err += 8.0 * GSL_DBL_EPSILON * fabs(result->val);

    return GSL_ERROR_SELECT_2(stat_a, stat_ap);
  }
}
Beispiel #3
0
static VALUE Airy_Ai_e(VALUE self, VALUE x, VALUE mode) {
  int ret;
  gsl_sf_result r;
  ret = gsl_sf_airy_Ai_e(NUM2DBL(x), NUM2UINT(mode), &r);
  return RESULT(&r);
}