示例#1
0
/* [Abramowitz+Stegun, 10.1.3]
 * with lmax=15, precision ~ 15D for x < 3
 *
 * checked OK [GJ] Wed May 13 15:41:25 MDT 1998
 */
static int bessel_yl_small_x(int l, const double x, gsl_sf_result * result)
{
    gsl_sf_result num_fact;
    double den = gsl_sf_pow_int(x, l+1);
    int stat_df = gsl_sf_doublefact_e(2*l-1, &num_fact);

    if(stat_df != GSL_SUCCESS || den == 0.0) {
        OVERFLOW_ERROR(result);
    }
    else {
        const int lmax = 200;
        double t = -0.5*x*x;
        double sum = 1.0;
        double t_coeff = 1.0;
        double t_power = 1.0;
        double delta;
        int i;
        for(i=1; i<=lmax; i++) {
            t_coeff /= i*(2*(i-l) - 1);
            t_power *= t;
            delta = t_power*t_coeff;
            sum += delta;
            if(fabs(delta/sum) < 0.5*GSL_DBL_EPSILON) break;
        }
        result->val = -num_fact.val/den * sum;
        result->err = GSL_DBL_EPSILON * fabs(result->val);

        return GSL_SUCCESS;
    }
}
示例#2
0
/// Double factorial.
double
double_factorial(int n)
{
  gsl_sf_result result;
  int stat = gsl_sf_doublefact_e(n, &result);
  if (stat != GSL_SUCCESS)
    {
      std::ostringstream msg("Error in double_factorial:");
      msg << " n=" << n;
      throw std::runtime_error(msg.str());
    }
  else
    return result.val;
}
示例#3
0
/* [Abramowitz+Stegun, 10.2.4 + 10.2.6]
 * with lmax=15, precision ~ 15D for x < 3
 *
 * assumes l >= 1
 */
static int bessel_kl_scaled_small_x(int l, const double x, gsl_sf_result * result)
{
  gsl_sf_result num_fact;
  double den  = gsl_sf_pow_int(x, l+1);
  int stat_df = gsl_sf_doublefact_e((unsigned int) (2*l-1), &num_fact);

  if(stat_df != GSL_SUCCESS || den == 0.0) {
    OVERFLOW_ERROR(result);
  }
  else {
    const int lmax = 50;
    gsl_sf_result ipos_term;
    double ineg_term;
    double sgn = (GSL_IS_ODD(l) ? -1.0 : 1.0);
    double ex  = exp(x);
    double t = 0.5*x*x;
    double sum = 1.0;
    double t_coeff = 1.0;
    double t_power = 1.0;
    double delta;
    int stat_il;
    int i;

    for(i=1; i<lmax; i++) {
      t_coeff /= i*(2*(i-l) - 1);
      t_power *= t;
      delta = t_power*t_coeff;
      sum += delta;
      if(fabs(delta/sum) < GSL_DBL_EPSILON) break;
    }

    stat_il = gsl_sf_bessel_il_scaled_e(l, x, &ipos_term);
    ineg_term =  sgn * num_fact.val/den * sum;
    result->val = -sgn * 0.5*M_PI * (ex*ipos_term.val - ineg_term);
    result->val *= ex;
    result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
    return stat_il;
  }
}