TPCCLIB
Loading...
Searching...
No Matches
rgamma.c
Go to the documentation of this file.
1
6/*****************************************************************************/
7#include "tpcclibConfig.h"
8/*****************************************************************************/
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12#include <float.h> // DBL_EPSILON, DBL_MAX_10_EXP
13#include <time.h>
14#include <string.h>
15/*****************************************************************************/
16#include "tpcextensions.h"
17/*****************************************************************************/
18#include "tpcfunc.h"
19/*****************************************************************************/
20
21/*****************************************************************************/
29double igam(
31 double a,
33 double x
34) {
35 /* Check parameters */
36 if(x==0.0) return(0.0);
37 if((x<0.0) || (a<=0.0)) return(nan(""));
38
39 if((x>1.0) && (x>a)) return(1.0 - igamc(a, x));
40
41 /* Left tail of incomplete Gamma function:
42 x^a * e^-x * Sum(k=0,Inf)(x^k / Gamma(a+k+1)) */
43
44 double ans, ax, c, r;
45
46 /* Compute x**a * exp(-x) / Gamma(a) */
47 ax=a*log(x) - x - lgamma(a);
48 if(ax<-DBL_MAX_10_EXP) return(0.0); // underflow
49 ax=exp(ax);
50
51 /* power series */
52 r=a; c=1.0; ans=1.0;
53 do {
54 r+=1.0;
55 c*=x/r;
56 ans+=c;
57 } while(c/ans > DBL_EPSILON);
58 return(ans*ax/a);
59}
60/*****************************************************************************/
61
62/*****************************************************************************/
70double igamc(
72 double a,
74 double x
75) {
76 /* Check parameters */
77 if((x<0.0) || (a<=0.0)) return(nan(""));
78
79 if((x<1.0) || (x<a)) return(1.0-igam(a, x));
80
81 double ans, ax, c, yc, r, t, y, z;
82 double pk, pkm1, pkm2, qk, qkm1, qkm2;
83 double big=4.503599627370496E+015;
84 double biginv=2.22044604925031308085E-016;
85
86 ax = a*log(x) - x - lgamma(a);
87 if(ax < -DBL_MAX_10_EXP) return(0.0); // underflow
88 ax=exp(ax);
89
90 /* continued fraction */
91 y=1.0-a; z=x+y+1.0; c=0.0;
92 pkm2=1.0; qkm2=x; pkm1=x+1.0; qkm1=z*x;
93 ans=pkm1/qkm1;
94 do {
95 c+=1.0; y+=1.0; z+=2.0;
96 yc=y*c; pk=pkm1*z - pkm2*yc; qk=qkm1*z - qkm2*yc;
97 if(qk!=0.0) {r=pk/qk; t=fabs((ans-r)/r); ans=r;}
98 else t=1.0;
99 pkm2=pkm1; pkm1=pk; qkm2=qkm1; qkm1=qk;
100 if(fabs(pk)>big) {pkm2*=biginv; pkm1*=biginv; qkm2*=biginv; qkm1*=biginv;}
101 } while(t>DBL_EPSILON);
102 return(ans*ax);
103}
104/*****************************************************************************/
105
106/*****************************************************************************/
double igam(double a, double x)
Definition rgamma.c:29
double igamc(double a, double x)
Definition rgamma.c:70
Header file for library libtpcextensions.
Header file for libtpcfunc.