inline long double gamma_p(long double x, long double y) { #ifdef BOOST_MSVC return igam((double)x, (double)y); #else return igaml(x, y); #endif }
double chdtr (double df, double x) { if (x < 0.0 || df < 1.0) { mtherr("chdtr", CEPHES_DOMAIN); return 0.0; } return igam(df/2.0, x/2.0); }
double pdtrc( int k, double m ) { double v; if( (k < 0) || (m <= 0.0) ) { mtherr( "pdtrc", DOMAIN ); return( 0.0 ); } v = k+1; return( igam( v, m ) ); }
double igami(double a, double p) { int i; double x, fac, f_fp, fpp_fp; if (npy_isnan(a) || npy_isnan(p)) { return NPY_NAN; } else if ((a < 0) || (p < 0) || (p > 1)) { mtherr("gammaincinv", DOMAIN); } else if (p == 0.0) { return 0.0; } else if (p == 1.0) { return NPY_INFINITY; } else if (p > 0.9) { return igamci(a, 1 - p); } x = find_inverse_gamma(a, p, 1 - p); /* Halley's method */ for (i = 0; i < 3; i++) { fac = igam_fac(a, x); if (fac == 0.0) { return x; } f_fp = (igam(a, x) - p) * x / fac; /* The ratio of the first and second derivatives simplifies */ fpp_fp = -1.0 + (a - 1) / x; if (npy_isinf(fpp_fp)) { /* Resort to Newton's method in the case of overflow */ x = x - f_fp; } else { x = x - f_fp / (1.0 - 0.5 * f_fp * fpp_fp); } } return x; }
inline double gamma_p(double x, double y) { return igam(x, y); }
static DBL igamc(DBL a, DBL x) { DBL ans, c, yc, ax, y, z; DBL pk, pkm1, pkm2, qk, qkm1, qkm2; DBL r, t; int sgngam = 0; if ((x <= 0) || (a <= 0)) { return (1.0); } if ((x < 1.0) || (x < a)) { return (1.0 - igam(a, x)); } ax = a * log(x) - x - lgam(a, &sgngam); if (ax < -MAXLOG) { /* mtherr("igamc", UNDERFLOW); */ return (0.0); } ax = exp(ax); /* continued fraction */ y = 1.0 - a; z = x + y + 1.0; c = 0.0; pkm2 = 1.0; qkm2 = x; pkm1 = x + 1.0; qkm1 = z * x; ans = pkm1 / qkm1; do { c += 1.0; y += 1.0; z += 2.0; yc = y * c; pk = pkm1 * z - pkm2 * yc; qk = qkm1 * z - qkm2 * yc; if (qk != 0) { r = pk / qk; t = fabs((ans - r) / r); ans = r; } else { t = 1.0; } pkm2 = pkm1; pkm1 = pk; qkm2 = qkm1; qkm1 = qk; if (fabs(pk) > BIG) { pkm2 /= BIG; pkm1 /= BIG; qkm2 /= BIG; qkm1 /= BIG; } } while (t > MACHEP); return (ans * ax); }
double igamc( double a, double x ) { double ans, ax, c, yc, r, t, y, z; double pk, pkm1, pkm2, qk, qkm1, qkm2; if( (x <= 0) || ( a <= 0) ) return( 1.0 ); if( (x < 1.0) || (x < a) ) return( 1.0 - igam(a,x) ); ax = a * log(x) - x - lgam(a); if( ax < -MAXLOG ) { mtherr( "igamc", UNDERFLOW ); return( 0.0 ); } ax = exp(ax); /* continued fraction */ y = 1.0 - a; z = x + y + 1.0; c = 0.0; pkm2 = 1.0; qkm2 = x; pkm1 = x + 1.0; qkm1 = z * x; ans = pkm1/qkm1; do { c += 1.0; y += 1.0; z += 2.0; yc = y * c; pk = pkm1 * z - pkm2 * yc; qk = qkm1 * z - qkm2 * yc; if( qk != 0 ) { r = pk/qk; t = fabs( (ans - r)/r ); ans = r; } else t = 1.0; pkm2 = pkm1; pkm1 = pk; qkm2 = qkm1; qkm1 = qk; if( fabs(pk) > big ) { pkm2 *= biginv; pkm1 *= biginv; qkm2 *= biginv; qkm1 *= biginv; } } while( t > MACHEP ); return( ans * ax ); }
static double gammainc(double x, double params[2]) { return /*cephes_*/igam(params[0], x) - params[1]; }