/* igam.c
*
* Incomplete gamma integral
*
*
*
* SYNOPSIS :
*
* double a , x , y , igam ( ) ;
*
* y = igam ( a , x ) ;
*
* DESCRIPTION :
*
* The function is defined by
*
* x
* -
* 1 | | - t a - 1
* igam ( a , x ) = - - - - - | e t dt .
* - | |
* | ( a ) -
* 0
*
*
* In this implementation both arguments must be positive .
* The integral is evaluated by either a power series or
* continued fraction expansion , depending on the relative
* values of a and x .
*
* ACCURACY :
*
* Relative error :
* arithmetic domain # trials peak rms
* IEEE 0 , 30 200000 3 . 6 e - 14 2 . 9 e - 15
* IEEE 0 , 100 300000 9 . 9 e - 14 1 . 5 e - 14
*/
/* igamc()
*
* Complemented incomplete gamma integral
*
*
*
* SYNOPSIS :
*
* double a , x , y , igamc ( ) ;
*
* y = igamc ( a , x ) ;
*
* DESCRIPTION :
*
* The function is defined by
*
*
* igamc ( a , x ) = 1 - igam ( a , x )
*
* inf .
* -
* 1 | | - t a - 1
* = - - - - - | e t dt .
* - | |
* | ( a ) -
* x
*
*
* In this implementation both arguments must be positive .
* The integral is evaluated by either a power series or
* continued fraction expansion , depending on the relative
* values of a and x .
*
* ACCURACY :
*
* Tested at random a , x .
* a x Relative error :
* arithmetic domain domain # trials peak rms
* IEEE 0 . 5 , 100 0 , 100 200000 1 . 9 e - 14 1 . 7 e - 15
* IEEE 0 . 01 , 0 . 5 0 , 100 200000 1 . 4 e - 13 1 . 6 e - 15
*/
/*
Cephes Math Library Release 2 . 8 : June , 2000
Copyright 1985 , 1987 , 2000 by Stephen L . Moshier
*/
#include "mconf.h"
#ifdef ANSIPROT
extern double lgam(double );
extern double exp(double );
extern double log(double );
extern double fabs(double );
extern double igam(double , double );
extern double igamc(double , double );
#else
double lgam(), exp(), log(), fabs(), igam(), igamc();
#endif
extern double MACHEP, MAXLOG;
static double big = 4 .503599627370496 e15;
static double biginv = 2 .22044604925031308085 e-16 ;
double igamc(a, x) double a, 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);
}
/* left tail of incomplete gamma function:
*
* inf . k
* a - x - x
* x e > - - - - - - - - - -
* - -
* k = 0 | ( a + k + 1 )
*
*/
double igam(a, x) double a, x;
{
double ans, ax, c, r;
if ((x <= 0 ) || (a <= 0 ))
return (0 .0 );
if ((x > 1 .0 ) && (x > a))
return (1 .0 - igamc(a, x));
/* Compute x**a * exp(-x) / gamma(a) */
ax = a * log(x) - x - lgam(a);
if (ax < -MAXLOG) {
mtherr("igam" , UNDERFLOW);
return (0 .0 );
}
ax = exp(ax);
/* power series */
r = a;
c = 1 .0 ;
ans = 1 .0 ;
do {
r += 1 .0 ;
c *= x / r;
ans += c;
} while (c / ans > MACHEP);
return (ans * ax / a);
}
Messung V0.5 in Prozent C=94 H=91 G=92
¤ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland