bug-gsl
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-gsl] Incomplete gamma functions


From: Michel Lespinasse
Subject: [Bug-gsl] Incomplete gamma functions
Date: Sat, 13 Nov 2004 23:46:58 -0800
User-agent: Mutt/1.5.6+20040722i

Hi all,

I've recently been looking for good implementations of the incomplete
gamma functions. Note that I dont actually know much about statistics
or numerical mathematics, but I just need an incomplete gamma function
to implement the chi-square function in a spam filter :)

Anyway. I found out that the following program fails at runtime in
gamma_inc.c:97

#include <stdio.h>
#include <gsl/gsl_sf_gamma.h>

int main (void)
{
    printf ("%g\n", gsl_sf_gamma_inc_Q (1e6 - 1, 1e6 - 2));
    return 0;
}

I also wanted to point out a few things about this gamma_inc.c file,
and ask a few questions too:

* In gsl_sf_gamma_inc_Q_e, you first test for a <= x (line 487) and then
  for a < 0.8*x (line 505). The second test will always fail - otherwise,
  the first one would have succeeded. I think this is the cause of the bug
  I noted above - you try to use the P_series in a region where it converges
  too slowly. Maybe line 505 really meant to test for 0.8*a < x ???
  (I do not know how fast the Q_CF algorithm would converge in that region).

* gsl_sf_gamma_inc_P_e and gsl_sf_gamma_inc_Q_e are curiously asymetrical
  in the way they select the proper numerical algorithm depending on
  which region we are in. gsl_sf_gamma_inc_Q_e selects the Q_large_x
  algorithm for any x > 1e6 (even as x-a might be small), while
  gsl_sf_gamma_inc_P_e only selects Q_large_x for a < 0.2 * x.
  Anyone understands why we have this difference ?

* In the region a>1e6, (x-a)<sqrt(a), you're using the Q_asymp_unif
  algorithm from Temme. Do you know how precise your implementation is in
  that region ? (the function comment says you're missing the c1 coefficient).
  Also, gnu R uses a different implementation for that region, using a
  normal distribution approximation. The reference I have is
  "Algorithm AS 239, Incomplete Gamma Function, Applied Statistics 37, 1988".
  I do not have access to that publication though, so I dont know if
  it's any good. Anyone knows how it compares to the Temme algorithm ?

Since I'm there, I might also copy in my own pgamma function, which
makes use of the normal approximation I found in gnu R. As I've said,
I don't know how precise this really is, though it seems to have about
9 digits of precision in practice. If anyone knows more or has comments,
I'd like to hear.

double pgamma (double a, double x)
{
    if (a > 1e5) {
        // Use normal approximation.
        return 0.5 * erfcl (-3 * sqrtl (0.5 * a) *
                            (cbrtl (x / a) - 1 + (1 / 9.0L) / a));
    } else if (x < a + 1) {
        // Use series approximation.
        long double an     = a;
        long double factor = 1 / an;
        long double sum    = factor;

        do
            sum += factor *= x / ++an;
        while (factor > LDBL_EPSILON * sum);
        return expl (a * logl (x) - x - lgammal (a)) * sum;
    } else {
        // Use continued fraction approximation.
        long double frac = LDBL_MAX;
        long double xa1  = x - a - 1;
        long double n    = 450;  // Keep in FP register for efficiency.

        while (--n > 0)
            frac = n * (a - n) / frac + xa1 + n + n;
        return 1 - expl (a * logl (x) - x - lgammal (a)) / frac;
    }
}

Hope this helps. I'm not on the lists, so I would appreciate to be
copied in any replies.

Thanks,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]