예제 #1
0
/* Q large x asymptotic
 */
static
int
gamma_inc_Q_large_x(const double a, const double x, gsl_sf_result * result)
{
  const int nmax = 5000;

  gsl_sf_result D;
  const int stat_D = gamma_inc_D(a, x, &D);

  double sum  = 1.0;
  double term = 1.0;
  double last = 1.0;
  int n;
  for(n=1; n<nmax; n++) {
    term *= (a-n)/x;
    if(fabs(term/last) > 1.0) break;
    if(fabs(term/sum)  < GSL_DBL_EPSILON) break;
    sum  += term;
    last  = term;
  }

  result->val  = D.val * (a/x) * sum;
  result->err  = D.err * fabs((a/x) * sum);
  result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);

  if(n == nmax)
    GSL_ERROR ("error", GSL_EMAXITER);
  else
    return stat_D;
}
예제 #2
0
/* P series representation.
 */
static
int
gamma_inc_P_series(const double a, const double x, gsl_sf_result * result)
{
  const int nmax = 5000;

  gsl_sf_result D;
  int stat_D = gamma_inc_D(a, x, &D);

  double sum  = 1.0;
  double term = 1.0;
  int n;
  for(n=1; n<nmax; n++) {
    term *= x/(a+n);
    sum  += term;
    if(fabs(term/sum) < GSL_DBL_EPSILON) break;
  }

  result->val  = D.val * sum;
  result->err  = D.err * fabs(sum);
  result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);

  if(n == nmax)
    GSL_ERROR ("error", GSL_EMAXITER);
  else
    return stat_D;
}
예제 #3
0
/* Continued fraction for Q.
 *
 * Q(a,x) = D(a,x) a/x F(a,x)
 *             1   (1-a)/x  1/x  (2-a)/x   2/x  (3-a)/x
 *  F(a.x) =  ---- ------- ----- -------- ----- -------- ...
 *            1 +   1 +     1 +   1 +      1 +   1 +
 *
 * Uses Gautschi equivalent series method for the CF evaluation.
 *
 * Assumes a != x + 1, so that the first term of the
 * CF recursion is not undefined. This is why we need
 * gamma_inc_Q_CF_protected() below. Based on a problem
 * report by Teemu Ikonen [Tue Oct 10 12:17:19 MDT 2000].
 */
static
int
gamma_inc_Q_CF(const double a, const double x, gsl_sf_result * result)
{
  const int kmax = 5000;

  gsl_sf_result D;
  const int stat_D = gamma_inc_D(a, x, &D);

  double sum  = 1.0;
  double tk   = 1.0;
  double rhok = 0.0;
  int k;

  for(k=1; k<kmax; k++) {
    double ak;
    if(GSL_IS_ODD(k))
      ak = (0.5*(k+1.0)-a)/x;
    else
      ak = 0.5*k/x;
    rhok  = -ak*(1.0 + rhok)/(1.0 + ak*(1.0 + rhok));
    tk   *= rhok;
    sum  += tk;
    if(fabs(tk/sum) < GSL_DBL_EPSILON) break;
  }

  result->val  = D.val * (a/x) * sum;
  result->err  = D.err * fabs((a/x) * sum);
  result->err += GSL_DBL_EPSILON * (2.0 + 0.5*k) * fabs(result->val);

  if(k == kmax)
    GSL_ERROR ("error", GSL_EMAXITER);
  else
    return stat_D;
}
예제 #4
0
/* See note above for  gamma_inc_Q_CF(). */
static
int
gamma_inc_Q_CF_protected(const double a, const double x, gsl_sf_result * result)
{
  if(fabs(1.0 - a + x) < 2.0*GSL_DBL_EPSILON) {
    /*
     * This is a problem region because when
     * 1.0 - a + x = 0 the first term of the
     * CF recursion is undefined.
     *
     * I missed this condition when I first
     * implemented gamma_inc_Q_CF() function,
     * so now I have to fix it by side-stepping
     * this point, using the recursion relation
     *   Q(a,x) = Q(a-1,x) + x^(a-1) e^(-z) / Gamma(a)
     *          = Q(a-1,x) + D(a-1,x)
     * to lower 'a' by one, giving an a=x point,
     * which is fine.
     */

    gsl_sf_result D;
    gsl_sf_result tmp_CF;

    const int stat_tmp_CF = gamma_inc_Q_CF(a-1.0, x, &tmp_CF);
    const int stat_D = gamma_inc_D(a-1.0, x, &D);
    result->val  = tmp_CF.val + D.val;
    result->err  = tmp_CF.err + D.err;
    result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
    return GSL_ERROR_SELECT_2(stat_tmp_CF, stat_D);
  }
  else {
    return gamma_inc_Q_CF(a, x, result);
  }
}
예제 #5
0
파일: gamma_inc.c 프로젝트: altoplano/RICO
/* Continued fraction for Q.
 *
 * Q(a,x) = D(a,x) a/x F(a,x)
 *
 * Hans E. Plesser, 2002-01-22 (hans dot plesser at itf dot nlh dot no):
 *
 * Since the Gautschi equivalent series method for CF evaluation may lead
 * to singularities, I have replaced it with the modified Lentz algorithm
 * given in
 *
 * I J Thompson and A R Barnett
 * Coulomb and Bessel Functions of Complex Arguments and Order
 * J Computational Physics 64:490-509 (1986)
 *
 * In consequence, gamma_inc_Q_CF_protected() is now obsolete and has been
 * removed.
 *
 * Identification of terms between the above equation for F(a, x) and
 * the first equation in the appendix of Thompson&Barnett is as follows:
 *
 *    b_0 = 0, b_n = 1 for all n > 0
 *
 *    a_1 = 1
 *    a_n = (n/2-a)/x    for n even
 *    a_n = (n-1)/(2x)   for n odd
 *
 */
static
int
gamma_inc_Q_CF(const double a, const double x, gsl_sf_result * result)
{
  gsl_sf_result D;
  gsl_sf_result F;
  const int stat_D = gamma_inc_D(a, x, &D);
  const int stat_F = gamma_inc_F_CF(a, x, &F);

  result->val  = D.val * (a/x) * F.val;
  result->err  = D.err * fabs((a/x) * F.val) + fabs(D.val * a/x * F.err);

  return GSL_ERROR_SELECT_2(stat_F, stat_D);
}