+//NUmerical recipes pg. 245 - Returns the complementary error function erfc(x) with fractional error everywhere less than 1.2 × 10−7.
+double LinearAlgebra::erfcc(double x){
+ try {
+ double t,z,ans;
+ z=fabs(x);
+ t=1.0/(1.0+0.5*z);
+
+ ans=t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
+ t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
+ t*(-0.82215223+t*0.17087277)))))))));
+
+ //cout << "in erfcc " << t << '\t' << ans<< endl;
+ return (x >= 0.0 ? ans : 2.0 - ans);
+ }
+ catch(exception& e) {
+ m->errorOut(e, "LinearAlgebra", "betai");
+ exit(1);
+ }
+}
+/*********************************************************************************************************************************/
+//Numerical Recipes pg. 232
+double LinearAlgebra::betai(const double a, const double b, const double x) {
+ try {
+ double bt;
+ double result = 0.0;
+
+ if (x < 0.0 || x > 1.0) { m->mothurOut("[ERROR]: bad x in betai.\n"); m->control_pressed = true; return 0.0; }
+
+ if (x == 0.0 || x == 1.0) { bt = 0.0; }
+ else { bt = exp(gammln(a+b)-gammln(a)-gammln(b)+a*log(x)+b*log(1.0-x)); }
+
+ if (x < (a+1.0) / (a+b+2.0)) { result = bt*betacf(a,b,x)/a; }
+ else { result = 1.0-bt*betacf(b,a,1.0-x)/b; }
+
+ return result;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "LinearAlgebra", "betai");
+ exit(1);
+ }
+}
+/*********************************************************************************************************************************/
+//Numerical Recipes pg. 219
+double LinearAlgebra::gammln(const double xx) {
+ try {
+ int j;
+ double x,y,tmp,ser;
+ static const double cof[6]={76.18009172947146,-86.50532032941677,24.01409824083091,
+ -1.231739572450155,0.120858003e-2,-0.536382e-5};
+
+ y=x=xx;
+ tmp=x+5.5;
+ tmp -= (x+0.5)*log(tmp);
+ ser=1.0;
+ for (j=0;j<6;j++) {
+ ser += cof[j]/++y;
+ }
+ return -tmp+log(2.5066282746310005*ser/x);
+ }
+ catch(exception& e) {
+ m->errorOut(e, "LinearAlgebra", "gammln");
+ exit(1);
+ }
+}
+/*********************************************************************************************************************************/
+//Numerical Recipes pg. 223
+double LinearAlgebra::gammp(const double a, const double x) {
+ try {
+ double gamser,gammcf,gln;
+
+ if (x < 0.0 || a <= 0.0) { m->mothurOut("[ERROR]: Invalid arguments in routine GAMMP\n"); m->control_pressed = true; return 0.0;}
+ if (x < (a+1.0)) {
+ gser(gamser,a,x,gln);
+ return gamser;
+ } else {
+ gcf(gammcf,a,x,gln);
+ return 1.0-gammcf;
+ }
+
+ return 0;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "LinearAlgebra", "gammp");
+ exit(1);
+ }
+}
+/*********************************************************************************************************************************/
+//Numerical Recipes pg. 223
+double LinearAlgebra::gammq(const double a, const double x) {
+ try {
+ double gamser,gammcf,gln;
+
+ if (x < 0.0 || a <= 0.0) { m->mothurOut("[ERROR]: Invalid arguments in routine GAMMQ\n"); m->control_pressed = true; return 0.0; }
+ if (x < (a+1.0)) {
+ gser(gamser,a,x,gln);
+ return 1.0-gamser;
+ } else {
+ gcf(gammcf,a,x,gln);
+ return gammcf;
+ }
+
+ return 0;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "LinearAlgebra", "gammp");
+ exit(1);
+ }
+}
+/*********************************************************************************************************************************/
+//Numerical Recipes pg. 224
+double LinearAlgebra::gcf(double& gammcf, const double a, const double x, double& gln){
+ try {
+ const int ITMAX=100;
+ const double EPS=numeric_limits<double>::epsilon();
+ const double FPMIN=numeric_limits<double>::min()/EPS;
+ int i;
+ double an,b,c,d,del,h;
+
+ gln=gammln(a);
+ b=x+1.0-a;
+ c=1.0/FPMIN;
+ d=1.0/b;
+ h=d;
+ for (i=1;i<=ITMAX;i++) {
+ an = -i*(i-a);
+ b += 2.0;
+ d=an*d+b;
+ if (fabs(d) < FPMIN) { d=FPMIN; }
+ c=b+an/c;
+ if (fabs(c) < FPMIN) { c=FPMIN; }
+ d=1.0/d;
+ del=d*c;
+ h *= del;
+ if (fabs(del-1.0) <= EPS) break;
+ }
+ if (i > ITMAX) { m->mothurOut("[ERROR]: a too large, ITMAX too small in gcf\n"); m->control_pressed = true; }
+ gammcf=exp(-x+a*log(x)-gln)*h;
+
+ return 0.0;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "LinearAlgebra", "gcf");
+ exit(1);
+ }
+
+}
+/*********************************************************************************************************************************/
+//Numerical Recipes pg. 223
+double LinearAlgebra::gser(double& gamser, const double a, const double x, double& gln) {
+ try {
+ int n;
+ double sum,del,ap;
+ const double EPS = numeric_limits<double>::epsilon();
+
+ gln=gammln(a);
+ if (x <= 0.0) {
+ if (x < 0.0) { m->mothurOut("[ERROR]: x less than 0 in routine GSER\n"); m->control_pressed = true; }
+ gamser=0.0; return 0.0;
+ } else {
+ ap=a;
+ del=sum=1.0/a;
+ for (n=0;n<100;n++) {
+ ++ap;
+ del *= x/ap;
+ sum += del;
+ if (fabs(del) < fabs(sum)*EPS) {
+ gamser=sum*exp(-x+a*log(x)-gln);
+ return 0.0;
+ }
+ }
+
+ m->mothurOut("[ERROR]: a too large, ITMAX too small in routine GSER\n");
+ return 0.0;
+ }
+ return 0;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "LinearAlgebra", "gser");
+ exit(1);
+ }
+}
+/*********************************************************************************************************************************/
+//Numerical Recipes pg. 233
+double LinearAlgebra::betacf(const double a, const double b, const double x) {
+ try {
+ const int MAXIT = 100;
+ const double EPS = numeric_limits<double>::epsilon();
+ const double FPMIN = numeric_limits<double>::min() / EPS;
+ int m1, m2;
+ double aa, c, d, del, h, qab, qam, qap;
+
+ qab=a+b;
+ qap=a+1.0;
+ qam=a-1.0;
+ c=1.0;
+ d=1.0-qab*x/qap;
+ if (fabs(d) < FPMIN) d=FPMIN;
+ d=1.0/d;
+ h=d;
+ for (m1=1;m1<=MAXIT;m1++) {
+ m2=2*m1;
+ aa=m1*(b-m1)*x/((qam+m2)*(a+m2));
+ d=1.0+aa*d;
+ if (fabs(d) < FPMIN) d=FPMIN;
+ c=1.0+aa/c;
+ if (fabs(c) < FPMIN) c=FPMIN;
+ d=1.0/d;
+ h *= d*c;
+ aa = -(a+m1)*(qab+m1)*x/((a+m2)*(qap+m2));
+ d=1.0+aa*d;
+ if (fabs(d) < FPMIN) d=FPMIN;
+ c=1.0+aa/c;
+ if (fabs(c) < FPMIN) c=FPMIN;
+ d=1.0/d;
+ del=d*c;
+ h *= del;
+ if (fabs(del-1.0) < EPS) break;
+ }
+
+ if (m1 > MAXIT) { m->mothurOut("[ERROR]: a or b too big or MAXIT too small in betacf."); m->mothurOutEndLine(); m->control_pressed = true; }
+ return h;
+
+ }
+ catch(exception& e) {
+ m->errorOut(e, "LinearAlgebra", "betacf");
+ exit(1);
+ }
+}
+/*********************************************************************************************************************************/