00001
00010 #include "Gammaq.h"
00011
00012 using std::cerr;
00013 using std::endl;
00014 using std::abs;
00015
00016 namespace hippodraw {
00017 namespace Numeric {
00018
00019 double gammln( double xx )
00020 {
00021 double x, y, tmp, ser;
00022 static double cof[6]={76.18009172947146,-86.50532032941677,
00023 24.01409824083091,-1.231739572450155,
00024 0.1208650973866179e-2,-0.5395239384953e-5};
00025
00026 y = x = xx;
00027 tmp = x + 5.5;
00028 tmp -= ( x + 0.5 ) * log( tmp );
00029 ser = 1.000000000190015;
00030
00031 for ( int j = 0; j <= 5; j++)
00032 ser += cof[j] / (++y);
00033
00034 return -tmp + log( 2.5066282746310005 * ser / x);
00035 }
00036
00037
00038 void gser(double *gamser, double a, double x, double *gln)
00039 {
00040 int n;
00041 double sum, del, ap;
00042
00043 *gln = gammln( a );
00044
00045 if ( x <= 0.0 )
00046 {
00047 if (x < 0.0) cerr << "Error: x less than 0 in routine gser" << endl;
00048 *gamser=0.0;
00049 return;
00050 }
00051 else
00052 {
00053 ap = a;
00054 del = sum =1.0 / a;
00055 for (n = 1; n <= ITMAX; n++)
00056 {
00057 ++ap;
00058 del *= x/ap;
00059 sum += del;
00060
00061 if (abs(del) < abs(sum)*EPS)
00062 {
00063 *gamser = sum * exp( -x + a * log( x ) -( *gln ) );
00064 return;
00065 }
00066 }
00067
00068 cerr << "ERROR: a too large, ITMAX too small in routine gser" << endl;
00069 return;
00070 }
00071 }
00072
00073 void gcf( double *gammcf, double a, double x, double *gln )
00074 {
00075 int i;
00076 double an,b,c,d,del,h;
00077
00078 *gln = gammln( a );
00079 b = x + 1.0 - a;
00080 c = 1.0 / FPMIN;
00081 d = 1.0 / b;
00082 h = d;
00083
00084 for( i = 1; i <= ITMAX; i++ )
00085 {
00086 an = -i*(i-a);
00087 b += 2.0;
00088 d=an*d+b;
00089
00090 if ( abs( d ) < FPMIN )
00091 d = FPMIN;
00092
00093 c = b + an / c;
00094
00095 if ( abs( c ) < FPMIN )
00096 c = FPMIN;
00097
00098 d = 1.0 / d;
00099 del = d * c;
00100 h *= del;
00101
00102 if ( abs( del - 1.0 ) < EPS)
00103 break;
00104 }
00105
00106 if (i > ITMAX) cerr << "a too large, ITMAX too small in gcf" << endl;
00107
00108 *gammcf = exp( -x + a * log( x ) -( *gln ) ) * h;
00109 }
00110
00111 double gammq(double a, double x)
00112 {
00113 void gcf(double *gammcf, double a, double x, double *gln);
00114
00115 double gamser,gammcf,gln;
00116
00117 if (x < 0.0 || a <= 0.0)
00118 {
00119 cerr << "a = " << a << " x = " << x << endl;
00120 cerr << "Invalid arguments in routine GAMMQ" << endl;
00121 assert(0);
00122 }
00123
00124 if (x < (a+1.0))
00125 {
00126 gser(&gamser,a,x,&gln);
00127 return 1.0-gamser;
00128 }
00129 else
00130 {
00131 gcf(&gammcf,a,x,&gln);
00132 return gammcf;
00133 }
00134 }
00135
00136 }
00137 }
00138
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 #undef ITMAX
00182 #undef EPS
00183 #undef FPMIN
00184 #undef MAXSTR