Пример #1
0
int
gsl_sf_bessel_Ynu_e(double nu, double x, gsl_sf_result * result)
{
  /* CHECK_POINTER(result) */

  if(x <= 0.0 || nu < 0.0) {
    DOMAIN_ERROR(result);
  }
  else if(nu > 50.0) {
    return gsl_sf_bessel_Ynu_asymp_Olver_e(nu, x, result);
  }
  else {
    /* -1/2 <= mu <= 1/2 */
    int N = (int)(nu + 0.5);
    double mu = nu - N;

    gsl_sf_result Y_mu, Y_mup1;
    int stat_mu;
    double Ynm1;
    double Yn;
    double Ynp1;
    int n;

    if(x < 2.0) {
      /* Determine Ymu, Ymup1 directly. This is really
       * an optimization since this case could as well
       * be handled by a call to gsl_sf_bessel_JY_mu_restricted(),
       * as below.
       */
      stat_mu = gsl_sf_bessel_Y_temme(mu, x, &Y_mu, &Y_mup1);
    }
    else {
      /* Determine Ymu, Ymup1 and Jmu, Jmup1.
       */
      gsl_sf_result J_mu, J_mup1;
      stat_mu = gsl_sf_bessel_JY_mu_restricted(mu, x, &J_mu, &J_mup1, &Y_mu, &Y_mup1);
    }

    /* Forward recursion to get Ynu, Ynup1.
     */
    Ynm1 = Y_mu.val;
    Yn   = Y_mup1.val;
    for(n=1; n<=N; n++) {
      Ynp1 = 2.0*(mu+n)/x * Yn - Ynm1;
      Ynm1 = Yn;
      Yn   = Ynp1;
    }

    result->val  = Ynm1; /* Y_nu */
    result->err  = (N + 1.0) * fabs(Ynm1) * (fabs(Y_mu.err/Y_mu.val) + fabs(Y_mup1.err/Y_mup1.val));
    result->err += 2.0 * GSL_DBL_EPSILON * fabs(Ynm1);

    return stat_mu;
  }
}
Пример #2
0
int gsl_sf_bessel_yl_e(int l, const double x, gsl_sf_result * result)
{
    /* CHECK_POINTER(result) */

    if(l < 0 || x <= 0.0) {
        DOMAIN_ERROR(result);
    }
    else if(l == 0) {
        return gsl_sf_bessel_y0_e(x, result);
    }
    else if(l == 1) {
        return gsl_sf_bessel_y1_e(x, result);
    }
    else if(l == 2) {
        return gsl_sf_bessel_y2_e(x, result);
    }
    else if(x < 3.0) {
        return bessel_yl_small_x(l, x, result);
    }
    else if(GSL_ROOT3_DBL_EPSILON * x > (l*l + l + 1.0)) {
        int status = gsl_sf_bessel_Ynu_asympx_e(l + 0.5, x, result);
        double pre = sqrt((0.5*M_PI)/x);
        result->val *= pre;
        result->err *= pre;
        return status;
    }
    else if(l > 40) {
        int status = gsl_sf_bessel_Ynu_asymp_Olver_e(l + 0.5, x, result);
        double pre = sqrt((0.5*M_PI)/x);
        result->val *= pre;
        result->err *= pre;
        return status;
    }
    else {
        /* recurse upward */
        gsl_sf_result r_by;
        gsl_sf_result r_bym;
        int stat_1 = gsl_sf_bessel_y1_e(x, &r_by);
        int stat_0 = gsl_sf_bessel_y0_e(x, &r_bym);
        double bym = r_bym.val;
        double by  = r_by.val;
        double byp;
        int j;
        for(j=1; j<l; j++) {
            byp = (2*j+1)/x*by - bym;
            bym = by;
            by  = byp;
        }
        result->val = by;
        result->err = fabs(result->val) * (GSL_DBL_EPSILON + fabs(r_by.err/r_by.val) + fabs(r_bym.err/r_bym.val));

        return GSL_ERROR_SELECT_2(stat_1, stat_0);
    }
}
Пример #3
0
int
gsl_sf_bessel_Yn_e(int n, const double x, gsl_sf_result * result)
{
  int sign = 1;

  if(n < 0) {
    /* reduce to case n >= 0 */
    n = -n;
    if(GSL_IS_ODD(n)) sign = -1;
  }

  /* CHECK_POINTER(result) */

  if(n == 0) {
    int status = gsl_sf_bessel_Y0_e(x, result);
    result->val *= sign;
    return status;
  }
  else if(n == 1) {
    int status = gsl_sf_bessel_Y1_e(x, result);
    result->val *= sign;
    return status;
  }
  else {
    if(x <= 0.0) {
      DOMAIN_ERROR(result);
    }
    if(x < 5.0) {
      int status = bessel_Yn_small_x(n, x, result);
      result->val *= sign;
      return status;
    }
    else if(GSL_ROOT3_DBL_EPSILON * x > (n*n + 1.0)) {
      int status = gsl_sf_bessel_Ynu_asympx_e((double)n, x, result);
      result->val *= sign;
      return status;
    }
    else if(n > 50) {
      int status = gsl_sf_bessel_Ynu_asymp_Olver_e((double)n, x, result);
      result->val *= sign;
      return status;
    }
    else {
      double two_over_x = 2.0/x;
      gsl_sf_result r_by;
      gsl_sf_result r_bym;
      int stat_1 = gsl_sf_bessel_Y1_e(x, &r_by);
      int stat_0 = gsl_sf_bessel_Y0_e(x, &r_bym);
      double bym = r_bym.val;
      double by  = r_by.val;
      double byp;
      int j;

      for(j=1; j<n; j++) { 
        byp = j*two_over_x*by - bym;
        bym = by;
        by  = byp;
      }
      result->val  = sign * by;
      result->err  = fabs(result->val) * (fabs(r_by.err/r_by.val) + fabs(r_bym.err/r_bym.val));
      result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);

      return GSL_ERROR_SELECT_2(stat_1, stat_0);
    }
  }
}