00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <math.h>
00030
00031 double probChiSquared(double x, unsigned int n)
00032 {
00033 if(x < 0) return 0;
00034
00035 const unsigned int nmax = 300;
00036 const double r1 = 1;
00037 const double hf = r1/2;
00038 const double th = r1/3;
00039 const double f1 = 2*r1/9;
00040 const double c1 = 1.128379167095513;
00041 const double chipdf = 100;
00042 const double xmax = 174.673;
00043 const double xmax2 = 2*xmax;
00044 const double xlim = 24;
00045 const double eps = 1e-30;
00046
00047 int m, i;
00048 double h, w, s, t, fi, e;
00049 double u = hf*x;
00050
00051 if (x == 0 || n/20 > x)
00052 h=1;
00053 else if (n == 1) {
00054 w = ::sqrt(u);
00055 h = w < xlim ? erfc(w) : 0;
00056 }
00057 else if (n > nmax) {
00058 s = r1/n;
00059 t = f1*s;
00060 w = (::pow(x*s,th)-(1-t))/::sqrt(2*t);
00061 if (w < -xlim)
00062 h=1;
00063 else if (w < xlim)
00064 h=hf*erfc(w);
00065 else
00066 h=0;
00067 }
00068 else {
00069 m=n/2;
00070 if(u < xmax2 && (x/n) <= chipdf ) {
00071 s=exp(-hf*u);
00072 t=s;
00073 e=s;
00074 if (2*m == (int)n) {
00075 fi=0;
00076 for (i=1; i<m; i++) {
00077 fi += 1;
00078 t=u*t/fi;
00079 s=s+t;
00080 }
00081 h=s*e;
00082 }
00083 else {
00084 fi=1;
00085 for (i=1; i<m; i++) {
00086 fi+=2;
00087 t=t*x/fi;
00088 s=s+t;
00089 }
00090 w=::sqrt(u);
00091 h = w < xlim ? c1*w*s*e+erfc(w) : 0;
00092 }
00093 }
00094 else
00095 h=0;
00096 }
00097 return h > eps ? h : 0;
00098 }