Ejemplo n.º 1
0
static VALUE rb_gsl_sf_pow_int_e(VALUE obj, VALUE x, VALUE n)
{
  gsl_sf_result *rslt = NULL;
  VALUE v;
  int status;
  Need_Float(x);
  CHECK_FIXNUM(n);
  v = Data_Make_Struct(cgsl_sf_result, gsl_sf_result, 0, free, rslt);
  status = gsl_sf_pow_int_e(NUM2DBL(x), FIX2INT(n), rslt);
  return v;
}
Ejemplo n.º 2
0
double gsl_sf_pow_int(const double x, const int n)
{
  EVAL_RESULT(gsl_sf_pow_int_e(x, n, &result));
}
Ejemplo n.º 3
0
int
gsl_sf_bessel_zero_Jnu_e(double nu, unsigned int s, gsl_sf_result * result)
{
  /* CHECK_POINTER(result) */

  if(nu <= -1.0) {
    DOMAIN_ERROR(result);
  }
  else if(s == 0) {
    result->val = 0.0;
    result->err = 0.0;
    if (nu == 0.0) {
      GSL_ERROR ("no zero-th root for nu = 0.0", GSL_EINVAL);
    }
    return GSL_SUCCESS;
  }
  else if(nu < 0.0) {
    /* This can be done, I'm just lazy now. */
    result->val = 0.0;
    result->err = 0.0;
    GSL_ERROR("unimplemented", GSL_EUNIMPL);
  }
  else if(s == 1) {
    /* Chebyshev fits for the first positive zero.
     * For some reason Nemeth made this different from the others.
     */
    if(nu < 2.0) {
      const double * c = coef_jnu_a[s];
      const size_t   L = size_jnu_a[s];
      const double arg = nu/2.0;
      const double chb = clenshaw(c, L-1, arg);
      result->val = chb;
      result->err = 2.0e-15 * result->val;
    }
    else {
      const double * c = coef_jnu_b[s];
      const size_t   L = size_jnu_b[s];
      const double arg = pow(2.0/nu, 2.0/3.0);
      const double chb = clenshaw(c, L-1, arg);
      result->val = nu * chb;
      result->err = 2.0e-15 * result->val;
    }
    return GSL_SUCCESS;
  }
  else if(s <= 10) {
    /* Chebyshev fits for the first 10 positive zeros. */
    if(nu < s) {
      const double * c = coef_jnu_a[s];
      const size_t   L = size_jnu_a[s];
      const double arg = nu/s;
      const double chb = clenshaw(c, L-1, arg);
      result->val = chb;
      result->err = 2.0e-15 * result->val;
    }
    else {
      const double * c = coef_jnu_b[s];
      const size_t   L = size_jnu_b[s];
      const double arg = pow(s/nu, 2.0/3.0);
      const double chb = clenshaw(c, L-1, arg);
      result->val = nu * chb;
      result->err = 2.0e-15 * result->val;

      /* FIXME: truth in advertising for the screwed up
       * s = 5 fit. Need to fix that.
       */
      if(s == 5) {
        result->err *= 5.0e+06;
      }
    }
    return GSL_SUCCESS;
  }
  else if(s > 0.5*nu && s <= 20) {
    /* Chebyshev fits for 10 < s <= 20. */
    const double * c = coef_jnu_a[s];
    const size_t   L = size_jnu_a[s];
    const double arg = nu/(2.0*s);
    const double chb = clenshaw(c, L-1, arg);
    result->val = chb;
    result->err = 4.0e-15 * chb;
    return GSL_SUCCESS;
  }
  else if(s > 2.0 * nu) {
    /* McMahon expansion if s is large compared to nu. */
    const double beta = (s + 0.5*nu - 0.25) * M_PI;
    const double mc   = mcmahon_correction(4.0*nu*nu, beta);
    gsl_sf_result rat12;
    gsl_sf_pow_int_e(nu/beta, 14, &rat12);
    result->val  = beta * mc;
    result->err  = 4.0 * fabs(beta) * rat12.val;
    result->err += 4.0 * fabs(GSL_DBL_EPSILON * result->val);
    return GSL_SUCCESS;
  }
  else {
    /* Olver uniform asymptotic. */
    gsl_sf_result as;
    const int stat_as = gsl_sf_airy_zero_Ai_e(s, &as);
    const double minus_zeta = -pow(nu,-2.0/3.0) * as.val;
    const double z  = gsl_sf_bessel_Olver_zofmzeta(minus_zeta);
    const double f1 = olver_f1(z, minus_zeta);
    result->val  = nu * (z + f1/(nu*nu));
    result->err  = 0.001/(nu*nu*nu);
    result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
    return stat_as;
  }
}