Skip to content.

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation » source

Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

nifti_stats.c

Go to the documentation of this file.
00001 
00002  /************************************************************************/
00003  /**  Functions to compute cumulative distributions and their inverses  **/
00004  /**  for the NIfTI-1 statistical types.  Much of this code is taken    **/
00005  /**  from other sources.  In particular, the cdflib functions by       **/
00006  /**  Brown and Lovato make up the bulk of this file.  That code        **/
00007  /**  was placed in the public domain.  The code by K. Krishnamoorthy   **/
00008  /**  is also released for unrestricted use.  Finally, the other parts  **/
00009  /**  of this file (by RW Cox) are released to the public domain.       **/
00010  /**                                                                    **/
00011  /**  Most of this file comprises a set of "static" functions, to be    **/
00012  /**  called by the user-level functions at the very end of the file.   **/
00013  /**  At the end of the file is a simple main program to drive these    **/
00014  /**  functions.                                                        **/
00015  /**                                                                    **/
00016  /**  To find the user-level functions, search forward for the string   **/
00017  /**  "nifti_", which will be at about line 11000.                      **/
00018  /************************************************************************/
00019  /*****==============================================================*****/
00020  /***** Neither the National Institutes of Health (NIH), the DFWG,   *****/
00021  /***** nor any of the members or employees of these institutions    *****/
00022  /***** imply any warranty of usefulness of this material for any    *****/
00023  /***** purpose, and do not assume any liability for damages,        *****/
00024  /***** incidental or otherwise, caused by any use of this document. *****/
00025  /***** If these conditions are not acceptable, do not use this!     *****/
00026  /*****==============================================================*****/
00027  /************************************************************************/
00028 
00029  /*.......................................................................
00030     To compile with gcc, for example:
00031 
00032     gcc -O3 -ffast-math -o nifti_stats nifti_stats.c -lm
00033  ........................................................................*/
00034 
00035 #include "nifti1.h"   /* for the NIFTI_INTENT_* constants */
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <math.h>
00039 
00040  /************************************************************************/
00041  /************ Include all the cdflib functions here and now *************/
00042  /************     [about 9900 lines of code below here]     *************/
00043  /************************************************************************/
00044 
00045 /** Prototypes for cdflib functions **/
00046 
00047 static double algdiv(double*,double*);
00048 static double alngam(double*);
00049 static double alnrel(double*);
00050 static double apser(double*,double*,double*,double*);
00051 static double basym(double*,double*,double*,double*);
00052 static double bcorr(double*,double*);
00053 static double betaln(double*,double*);
00054 static double bfrac(double*,double*,double*,double*,double*,double*);
00055 static void bgrat(double*,double*,double*,double*,double*,double*,int*i);
00056 static double bpser(double*,double*,double*,double*);
00057 static void bratio(double*,double*,double*,double*,double*,double*,int*);
00058 static double brcmp1(int*,double*,double*,double*,double*);
00059 static double brcomp(double*,double*,double*,double*);
00060 static double bup(double*,double*,double*,double*,int*,double*);
00061 static void cdfbet(int*,double*,double*,double*,double*,double*,double*,
00062                    int*,double*);
00063 static void cdfbin(int*,double*,double*,double*,double*,double*,double*,
00064                    int*,double*);
00065 static void cdfchi(int*,double*,double*,double*,double*,int*,double*);
00066 static void cdfchn(int*,double*,double*,double*,double*,double*,int*,double*);
00067 static void cdff(int*,double*,double*,double*,double*,double*,int*,double*);
00068 static void cdffnc(int*,double*,double*,double*,double*,double*,double*,
00069                    int*s,double*);
00070 static void cdfgam(int*,double*,double*,double*,double*,double*,int*,double*);
00071 static void cdfnbn(int*,double*,double*,double*,double*,double*,double*,
00072                    int*,double*);
00073 static void cdfnor(int*,double*,double*,double*,double*,double*,int*,double*);
00074 static void cdfpoi(int*,double*,double*,double*,double*,int*,double*);
00075 static void cdft(int*,double*,double*,double*,double*,int*,double*);
00076 static void cumbet(double*,double*,double*,double*,double*,double*);
00077 static void cumbin(double*,double*,double*,double*,double*,double*);
00078 static void cumchi(double*,double*,double*,double*);
00079 static void cumchn(double*,double*,double*,double*,double*);
00080 static void cumf(double*,double*,double*,double*,double*);
00081 static void cumfnc(double*,double*,double*,double*,double*,double*);
00082 static void cumgam(double*,double*,double*,double*);
00083 static void cumnbn(double*,double*,double*,double*,double*,double*);
00084 static void cumnor(double*,double*,double*);
00085 static void cumpoi(double*,double*,double*,double*);
00086 static void cumt(double*,double*,double*,double*);
00087 static double dbetrm(double*,double*);
00088 static double devlpl(double [],int*,double*);
00089 static double dexpm1(double*);
00090 static double dinvnr(double *p,double *q);
00091 static void E0000(int,int*,double*,double*,unsigned long*,
00092                   unsigned long*,double*,double*,double*,
00093                   double*,double*,double*,double*);
00094 static void dinvr(int*,double*,double*,unsigned long*,unsigned long*);
00095 static void dstinv(double*,double*,double*,double*,double*,double*,
00096                    double*);
00097 static double dlanor(double*);
00098 static double dln1mx(double*);
00099 static double dln1px(double*);
00100 static double dlnbet(double*,double*);
00101 static double dlngam(double*);
00102 static double dstrem(double*);
00103 static double dt1(double*,double*,double*);
00104 static void E0001(int,int*,double*,double*,double*,double*,
00105                   unsigned long*,unsigned long*,double*,double*,
00106                   double*,double*);
00107 static void dzror(int*,double*,double*,double*,double *,
00108                   unsigned long*,unsigned long*);
00109 static void dstzr(double *zxlo,double *zxhi,double *zabstl,double *zreltl);
00110 static double erf1(double*);
00111 static double erfc1(int*,double*);
00112 static double esum(int*,double*);
00113 static double exparg(int*);
00114 static double fpser(double*,double*,double*,double*);
00115 static double gam1(double*);
00116 static void gaminv(double*,double*,double*,double*,double*,int*);
00117 static double gamln(double*);
00118 static double gamln1(double*);
00119 static double Xgamm(double*);
00120 static void grat1(double*,double*,double*,double*,double*,double*);
00121 static void gratio(double*,double*,double*,double*,int*);
00122 static double gsumln(double*,double*);
00123 static double psi(double*);
00124 static double rcomp(double*,double*);
00125 static double rexp(double*);
00126 static double rlog(double*);
00127 static double rlog1(double*);
00128 static double spmpar(int*);
00129 static double stvaln(double*);
00130 static double fifdint(double);
00131 static double fifdmax1(double,double);
00132 static double fifdmin1(double,double);
00133 static double fifdsign(double,double);
00134 static long fifidint(double);
00135 static long fifmod(long,long);
00136 static void ftnstop(char*);
00137 static int ipmpar(int*);
00138 
00139 /***=====================================================================***/
00140 static double algdiv(double *a,double *b)
00141 /*
00142 -----------------------------------------------------------------------
00143 
00144      COMPUTATION OF LN(GAMMA(B)/GAMMA(A+B)) WHEN B .GE. 8
00145 
00146                          --------
00147 
00148      IN THIS ALGORITHM, DEL(X) IS THE FUNCTION DEFINED BY
00149      LN(GAMMA(X)) = (X - 0.5)*LN(X) - X + 0.5*LN(2*PI) + DEL(X).
00150 
00151 -----------------------------------------------------------------------
00152 */
00153 {
00154 static double c0 = .833333333333333e-01;
00155 static double c1 = -.277777777760991e-02;
00156 static double c2 = .793650666825390e-03;
00157 static double c3 = -.595202931351870e-03;
00158 static double c4 = .837308034031215e-03;
00159 static double c5 = -.165322962780713e-02;
00160 static double algdiv,c,d,h,s11,s3,s5,s7,s9,t,u,v,w,x,x2,T1;
00161 /*
00162      ..
00163      .. Executable Statements ..
00164 */
00165     if(*a <= *b) goto S10;
00166     h = *b/ *a;
00167     c = 1.0e0/(1.0e0+h);
00168     x = h/(1.0e0+h);
00169     d = *a+(*b-0.5e0);
00170     goto S20;
00171 S10:
00172     h = *a/ *b;
00173     c = h/(1.0e0+h);
00174     x = 1.0e0/(1.0e0+h);
00175     d = *b+(*a-0.5e0);
00176 S20:
00177 /*
00178                 SET SN = (1 - X**N)/(1 - X)
00179 */
00180     x2 = x*x;
00181     s3 = 1.0e0+(x+x2);
00182     s5 = 1.0e0+(x+x2*s3);
00183     s7 = 1.0e0+(x+x2*s5);
00184     s9 = 1.0e0+(x+x2*s7);
00185     s11 = 1.0e0+(x+x2*s9);
00186 /*
00187                 SET W = DEL(B) - DEL(A + B)
00188 */
00189     t = pow(1.0e0/ *b,2.0);
00190     w = ((((c5*s11*t+c4*s9)*t+c3*s7)*t+c2*s5)*t+c1*s3)*t+c0;
00191     w *= (c/ *b);
00192 /*
00193                     COMBINE THE RESULTS
00194 */
00195     T1 = *a/ *b;
00196     u = d*alnrel(&T1);
00197     v = *a*(log(*b)-1.0e0);
00198     if(u <= v) goto S30;
00199     algdiv = w-v-u;
00200     return algdiv;
00201 S30:
00202     algdiv = w-u-v;
00203     return algdiv;
00204 } /* END */
00205 
00206 /***=====================================================================***/
00207 static double alngam(double *x)
00208 /*
00209 **********************************************************************
00210 
00211      double alngam(double *x)
00212                  double precision LN of the GAMma function
00213 
00214 
00215                               Function
00216 
00217 
00218      Returns the natural logarithm of GAMMA(X).
00219 
00220 
00221                               Arguments
00222 
00223 
00224      X --> value at which scaled log gamma is to be returned
00225                     X is DOUBLE PRECISION
00226 
00227 
00228                               Method
00229 
00230 
00231      If X .le. 6.0, then use recursion to get X below 3
00232      then apply rational approximation number 5236 of
00233      Hart et al, Computer Approximations, John Wiley and
00234      Sons, NY, 1968.
00235 
00236      If X .gt. 6.0, then use recursion to get X to at least 12 and
00237      then use formula 5423 of the same source.
00238 
00239 **********************************************************************
00240 */
00241 {
00242 #define hln2pi 0.91893853320467274178e0
00243 static double coef[5] = {
00244     0.83333333333333023564e-1,-0.27777777768818808e-2,0.79365006754279e-3,
00245     -0.594997310889e-3,0.8065880899e-3
00246 };
00247 static double scoefd[4] = {
00248     0.62003838007126989331e2,0.9822521104713994894e1,-0.8906016659497461257e1,
00249     0.1000000000000000000e1
00250 };
00251 static double scoefn[9] = {
00252     0.62003838007127258804e2,0.36036772530024836321e2,0.20782472531792126786e2,
00253     0.6338067999387272343e1,0.215994312846059073e1,0.3980671310203570498e0,
00254     0.1093115956710439502e0,0.92381945590275995e-2,0.29737866448101651e-2
00255 };
00256 static int K1 = 9;
00257 static int K3 = 4;
00258 static int K5 = 5;
00259 static double alngam,offset,prod,xx;
00260 static int i,n;
00261 static double T2,T4,T6;
00262 /*
00263      ..
00264      .. Executable Statements ..
00265 */
00266     if(!(*x <= 6.0e0)) goto S70;
00267     prod = 1.0e0;
00268     xx = *x;
00269     if(!(*x > 3.0e0)) goto S30;
00270 S10:
00271     if(!(xx > 3.0e0)) goto S20;
00272     xx -= 1.0e0;
00273     prod *= xx;
00274     goto S10;
00275 S30:
00276 S20:
00277     if(!(*x < 2.0e0)) goto S60;
00278 S40:
00279     if(!(xx < 2.0e0)) goto S50;
00280     prod /= xx;
00281     xx += 1.0e0;
00282     goto S40;
00283 S60:
00284 S50:
00285     T2 = xx-2.0e0;
00286     T4 = xx-2.0e0;
00287     alngam = devlpl(scoefn,&K1,&T2)/devlpl(scoefd,&K3,&T4);
00288 /*
00289      COMPUTE RATIONAL APPROXIMATION TO GAMMA(X)
00290 */
00291     alngam *= prod;
00292     alngam = log(alngam);
00293     goto S110;
00294 S70:
00295     offset = hln2pi;
00296 /*
00297      IF NECESSARY MAKE X AT LEAST 12 AND CARRY CORRECTION IN OFFSET
00298 */
00299     n = fifidint(12.0e0-*x);
00300     if(!(n > 0)) goto S90;
00301     prod = 1.0e0;
00302     for(i=1; i<=n; i++) prod *= (*x+(double)(i-1));
00303     offset -= log(prod);
00304     xx = *x+(double)n;
00305     goto S100;
00306 S90:
00307     xx = *x;
00308 S100:
00309 /*
00310      COMPUTE POWER SERIES
00311 */
00312     T6 = 1.0e0/pow(xx,2.0);
00313     alngam = devlpl(coef,&K5,&T6)/xx;
00314     alngam += (offset+(xx-0.5e0)*log(xx)-xx);
00315 S110:
00316     return alngam;
00317 #undef hln2pi
00318 } /* END */
00319 
00320 /***=====================================================================***/
00321 static double alnrel(double *a)
00322 /*
00323 -----------------------------------------------------------------------
00324             EVALUATION OF THE FUNCTION LN(1 + A)
00325 -----------------------------------------------------------------------
00326 */
00327 {
00328 static double p1 = -.129418923021993e+01;
00329 static double p2 = .405303492862024e+00;
00330 static double p3 = -.178874546012214e-01;
00331 static double q1 = -.162752256355323e+01;
00332 static double q2 = .747811014037616e+00;
00333 static double q3 = -.845104217945565e-01;
00334 static double alnrel,t,t2,w,x;
00335 /*
00336      ..
00337      .. Executable Statements ..
00338 */
00339     if(fabs(*a) > 0.375e0) goto S10;
00340     t = *a/(*a+2.0e0);
00341     t2 = t*t;
00342     w = (((p3*t2+p2)*t2+p1)*t2+1.0e0)/(((q3*t2+q2)*t2+q1)*t2+1.0e0);
00343     alnrel = 2.0e0*t*w;
00344     return alnrel;
00345 S10:
00346     x = 1.e0+*a;
00347     alnrel = log(x);
00348     return alnrel;
00349 } /* END */
00350 
00351 /***=====================================================================***/
00352 static double apser(double *a,double *b,double *x,double *eps)
00353 /*
00354 -----------------------------------------------------------------------
00355      APSER YIELDS THE INCOMPLETE BETA RATIO I(SUB(1-X))(B,A) FOR
00356      A .LE. MIN(EPS,EPS*B), B*X .LE. 1, AND X .LE. 0.5. USED WHEN
00357      A IS VERY SMALL. USE ONLY IF ABOVE INEQUALITIES ARE SATISFIED.
00358 -----------------------------------------------------------------------
00359 */
00360 {
00361 static double g = .577215664901533e0;
00362 static double apser,aj,bx,c,j,s,t,tol;
00363 /*
00364      ..
00365      .. Executable Statements ..
00366 */
00367     bx = *b**x;
00368     t = *x-bx;
00369     if(*b**eps > 2.e-2) goto S10;
00370     c = log(*x)+psi(b)+g+t;
00371     goto S20;
00372 S10:
00373     c = log(bx)+g+t;
00374 S20:
00375     tol = 5.0e0**eps*fabs(c);
00376     j = 1.0e0;
00377     s = 0.0e0;
00378 S30:
00379     j += 1.0e0;
00380     t *= (*x-bx/j);
00381     aj = t/j;
00382     s += aj;
00383     if(fabs(aj) > tol) goto S30;
00384     apser = -(*a*(c+s));
00385     return apser;
00386 } /* END */
00387 
00388 /***=====================================================================***/
00389 static double basym(double *a,double *b,double *lambda,double *eps)
00390 /*
00391 -----------------------------------------------------------------------
00392      ASYMPTOTIC EXPANSION FOR IX(A,B) FOR LARGE A AND B.
00393      LAMBDA = (A + B)*Y - B  AND EPS IS THE TOLERANCE USED.
00394      IT IS ASSUMED THAT LAMBDA IS NONNEGATIVE AND THAT
00395      A AND B ARE GREATER THAN OR EQUAL TO 15.
00396 -----------------------------------------------------------------------
00397 */
00398 {
00399 static double e0 = 1.12837916709551e0;
00400 static double e1 = .353553390593274e0;
00401 static int num = 20;
00402 /*
00403 ------------------------
00404      ****** NUM IS THE MAXIMUM VALUE THAT N CAN TAKE IN THE DO LOOP
00405             ENDING AT STATEMENT 50. IT IS REQUIRED THAT NUM BE EVEN.
00406             THE ARRAYS A0, B0, C, D HAVE DIMENSION NUM + 1.
00407 ------------------------
00408      E0 = 2/SQRT(PI)
00409      E1 = 2**(-3/2)
00410 ------------------------
00411 */
00412 static int K3 = 1;
00413 static double basym,bsum,dsum,f,h,h2,hn,j0,j1,r,r0,r1,s,sum,t,t0,t1,u,w,w0,z,z0,
00414     z2,zn,znm1;
00415 static int i,im1,imj,j,m,mm1,mmj,n,np1;
00416 static double a0[21],b0[21],c[21],d[21],T1,T2;
00417 /*
00418      ..
00419      .. Executable Statements ..
00420 */
00421     basym = 0.0e0;
00422     if(*a >= *b) goto S10;
00423     h = *a/ *b;
00424     r0 = 1.0e0/(1.0e0+h);
00425     r1 = (*b-*a)/ *b;
00426     w0 = 1.0e0/sqrt(*a*(1.0e0+h));
00427     goto S20;
00428 S10:
00429     h = *b/ *a;
00430     r0 = 1.0e0/(1.0e0+h);
00431     r1 = (*b-*a)/ *a;
00432     w0 = 1.0e0/sqrt(*b*(1.0e0+h));
00433 S20:
00434     T1 = -(*lambda/ *a);
00435     T2 = *lambda/ *b;
00436     f = *a*rlog1(&T1)+*b*rlog1(&T2);
00437     t = exp(-f);
00438     if(t == 0.0e0) return basym;
00439     z0 = sqrt(f);
00440     z = 0.5e0*(z0/e1);
00441     z2 = f+f;
00442     a0[0] = 2.0e0/3.0e0*r1;
00443     c[0] = -(0.5e0*a0[0]);
00444     d[0] = -c[0];
00445     j0 = 0.5e0/e0*erfc1(&K3,&z0);
00446     j1 = e1;
00447     sum = j0+d[0]*w0*j1;
00448     s = 1.0e0;
00449     h2 = h*h;
00450     hn = 1.0e0;
00451     w = w0;
00452     znm1 = z;
00453     zn = z2;
00454     for(n=2; n<=num; n+=2) {
00455         hn = h2*hn;
00456         a0[n-1] = 2.0e0*r0*(1.0e0+h*hn)/((double)n+2.0e0);
00457         np1 = n+1;
00458         s += hn;
00459         a0[np1-1] = 2.0e0*r1*s/((double)n+3.0e0);
00460         for(i=n; i<=np1; i++) {
00461             r = -(0.5e0*((double)i+1.0e0));
00462             b0[0] = r*a0[0];
00463             for(m=2; m<=i; m++) {
00464                 bsum = 0.0e0;
00465                 mm1 = m-1;
00466                 for(j=1; j<=mm1; j++) {
00467                     mmj = m-j;
00468                     bsum += (((double)j*r-(double)mmj)*a0[j-1]*b0[mmj-1]);
00469                 }
00470                 b0[m-1] = r*a0[m-1]+bsum/(double)m;
00471             }
00472             c[i-1] = b0[i-1]/((double)i+1.0e0);
00473             dsum = 0.0e0;
00474             im1 = i-1;
00475             for(j=1; j<=im1; j++) {
00476                 imj = i-j;
00477                 dsum += (d[imj-1]*c[j-1]);
00478             }
00479             d[i-1] = -(dsum+c[i-1]);
00480         }
00481         j0 = e1*znm1+((double)n-1.0e0)*j0;
00482         j1 = e1*zn+(double)n*j1;
00483         znm1 = z2*znm1;
00484         zn = z2*zn;
00485         w = w0*w;
00486         t0 = d[n-1]*w*j0;
00487         w = w0*w;
00488         t1 = d[np1-1]*w*j1;
00489         sum += (t0+t1);
00490         if(fabs(t0)+fabs(t1) <= *eps*sum) goto S80;
00491     }
00492 S80:
00493     u = exp(-bcorr(a,b));
00494     basym = e0*t*u*sum;
00495     return basym;
00496 } /* END */
00497 
00498 /***=====================================================================***/
00499 static double bcorr(double *a0,double *b0)
00500 /*
00501 -----------------------------------------------------------------------
00502 
00503      EVALUATION OF  DEL(A0) + DEL(B0) - DEL(A0 + B0)  WHERE
00504      LN(GAMMA(A)) = (A - 0.5)*LN(A) - A + 0.5*LN(2*PI) + DEL(A).
00505      IT IS ASSUMED THAT A0 .GE. 8 AND B0 .GE. 8.
00506 
00507 -----------------------------------------------------------------------
00508 */
00509 {
00510 static double c0 = .833333333333333e-01;
00511 static double c1 = -.277777777760991e-02;
00512 static double c2 = .793650666825390e-03;
00513 static double c3 = -.595202931351870e-03;
00514 static double c4 = .837308034031215e-03;
00515 static double c5 = -.165322962780713e-02;
00516 static double bcorr,a,b,c,h,s11,s3,s5,s7,s9,t,w,x,x2;
00517 /*
00518      ..
00519      .. Executable Statements ..
00520 */
00521     a = fifdmin1(*a0,*b0);
00522     b = fifdmax1(*a0,*b0);
00523     h = a/b;
00524     c = h/(1.0e0+h);
00525     x = 1.0e0/(1.0e0+h);
00526     x2 = x*x;
00527 /*
00528                 SET SN = (1 - X**N)/(1 - X)
00529 */
00530     s3 = 1.0e0+(x+x2);
00531     s5 = 1.0e0+(x+x2*s3);
00532     s7 = 1.0e0+(x+x2*s5);
00533     s9 = 1.0e0+(x+x2*s7);
00534     s11 = 1.0e0+(x+x2*s9);
00535 /*
00536                 SET W = DEL(B) - DEL(A + B)
00537 */
00538     t = pow(1.0e0/b,2.0);
00539     w = ((((c5*s11*t+c4*s9)*t+c3*s7)*t+c2*s5)*t+c1*s3)*t+c0;
00540     w *= (c/b);
00541 /*
00542                    COMPUTE  DEL(A) + W
00543 */
00544     t = pow(1.0e0/a,2.0);
00545     bcorr = (((((c5*t+c4)*t+c3)*t+c2)*t+c1)*t+c0)/a+w;
00546     return bcorr;
00547 } /* END */
00548 
00549 /***=====================================================================***/
00550 static double betaln(double *a0,double *b0)
00551 /*
00552 -----------------------------------------------------------------------
00553      EVALUATION OF THE LOGARITHM OF THE BETA FUNCTION
00554 -----------------------------------------------------------------------
00555      E = 0.5*LN(2*PI)
00556 --------------------------
00557 */
00558 {
00559 static double e = .918938533204673e0;
00560 static double betaln,a,b,c,h,u,v,w,z;
00561 static int i,n;
00562 static double T1;
00563 /*
00564      ..
00565      .. Executable Statements ..
00566 */
00567     a = fifdmin1(*a0,*b0);
00568     b = fifdmax1(*a0,*b0);
00569     if(a >= 8.0e0) goto S100;
00570     if(a >= 1.0e0) goto S20;
00571 /*
00572 -----------------------------------------------------------------------
00573                    PROCEDURE WHEN A .LT. 1
00574 -----------------------------------------------------------------------
00575 */
00576     if(b >= 8.0e0) goto S10;
00577     T1 = a+b;
00578     betaln = gamln(&a)+(gamln(&b)-gamln(&T1));
00579     return betaln;
00580 S10:
00581     betaln = gamln(&a)+algdiv(&a,&b);
00582     return betaln;
00583 S20:
00584 /*
00585 -----------------------------------------------------------------------
00586                 PROCEDURE WHEN 1 .LE. A .LT. 8
00587 -----------------------------------------------------------------------
00588 */
00589     if(a > 2.0e0) goto S40;
00590     if(b > 2.0e0) goto S30;
00591     betaln = gamln(&a)+gamln(&b)-gsumln(&a,&b);
00592     return betaln;
00593 S30:
00594     w = 0.0e0;
00595     if(b < 8.0e0) goto S60;
00596     betaln = gamln(&a)+algdiv(&a,&b);
00597     return betaln;
00598 S40:
00599 /*
00600                 REDUCTION OF A WHEN B .LE. 1000
00601 */
00602     if(b > 1000.0e0) goto S80;
00603     n = a-1.0e0;
00604     w = 1.0e0;
00605     for(i=1; i<=n; i++) {
00606         a -= 1.0e0;
00607         h = a/b;
00608         w *= (h/(1.0e0+h));
00609     }
00610     w = log(w);
00611     if(b < 8.0e0) goto S60;
00612     betaln = w+gamln(&a)+algdiv(&a,&b);
00613     return betaln;
00614 S60:
00615 /*
00616                  REDUCTION OF B WHEN B .LT. 8
00617 */
00618     n = b-1.0e0;
00619     z = 1.0e0;
00620     for(i=1; i<=n; i++) {
00621         b -= 1.0e0;
00622         z *= (b/(a+b));
00623     }
00624     betaln = w+log(z)+(gamln(&a)+(gamln(&b)-gsumln(&a,&b)));
00625     return betaln;
00626 S80:
00627 /*
00628                 REDUCTION OF A WHEN B .GT. 1000
00629 */
00630     n = a-1.0e0;
00631     w = 1.0e0;
00632     for(i=1; i<=n; i++) {
00633         a -= 1.0e0;
00634         w *= (a/(1.0e0+a/b));
00635     }
00636     betaln = log(w)-(double)n*log(b)+(gamln(&a)+algdiv(&a,&b));
00637     return betaln;
00638 S100:
00639 /*
00640 -----------------------------------------------------------------------
00641                    PROCEDURE WHEN A .GE. 8
00642 -----------------------------------------------------------------------
00643 */
00644     w = bcorr(&a,&b);
00645     h = a/b;
00646     c = h/(1.0e0+h);
00647     u = -((a-0.5e0)*log(c));
00648     v = b*alnrel(&h);
00649     if(u <= v) goto S110;
00650     betaln = -(0.5e0*log(b))+e+w-v-u;
00651     return betaln;
00652 S110:
00653     betaln = -(0.5e0*log(b))+e+w-u-v;
00654     return betaln;
00655 } /* END */
00656 
00657 /***=====================================================================***/
00658 static double bfrac(double *a,double *b,double *x,double *y,double *lambda,
00659              double *eps)
00660 /*
00661 -----------------------------------------------------------------------
00662      CONTINUED FRACTION EXPANSION FOR IX(A,B) WHEN A,B .GT. 1.
00663      IT IS ASSUMED THAT  LAMBDA = (A + B)*Y - B.
00664 -----------------------------------------------------------------------
00665 */
00666 {
00667 static double bfrac,alpha,an,anp1,beta,bn,bnp1,c,c0,c1,e,n,p,r,r0,s,t,w,yp1;
00668 /*
00669      ..
00670      .. Executable Statements ..
00671 */
00672     bfrac = brcomp(a,b,x,y);
00673     if(bfrac == 0.0e0) return bfrac;
00674     c = 1.0e0+*lambda;
00675     c0 = *b/ *a;
00676     c1 = 1.0e0+1.0e0/ *a;
00677     yp1 = *y+1.0e0;
00678     n = 0.0e0;
00679     p = 1.0e0;
00680     s = *a+1.0e0;
00681     an = 0.0e0;
00682     bn = anp1 = 1.0e0;
00683     bnp1 = c/c1;
00684     r = c1/c;
00685 S10:
00686 /*
00687         CONTINUED FRACTION CALCULATION
00688 */
00689     n += 1.0e0;
00690     t = n/ *a;
00691     w = n*(*b-n)**x;
00692     e = *a/s;
00693     alpha = p*(p+c0)*e*e*(w**x);
00694     e = (1.0e0+t)/(c1+t+t);
00695     beta = n+w/s+e*(c+n*yp1);
00696     p = 1.0e0+t;
00697     s += 2.0e0;
00698 /*
00699         UPDATE AN, BN, ANP1, AND BNP1
00700 */
00701     t = alpha*an+beta*anp1;
00702     an = anp1;
00703     anp1 = t;
00704     t = alpha*bn+beta*bnp1;
00705     bn = bnp1;
00706     bnp1 = t;
00707     r0 = r;
00708     r = anp1/bnp1;
00709     if(fabs(r-r0) <= *eps*r) goto S20;
00710 /*
00711         RESCALE AN, BN, ANP1, AND BNP1
00712 */
00713     an /= bnp1;
00714     bn /= bnp1;
00715     anp1 = r;
00716     bnp1 = 1.0e0;
00717     goto S10;
00718 S20:
00719 /*
00720                  TERMINATION
00721 */
00722     bfrac *= r;
00723     return bfrac;
00724 } /* END */
00725 
00726 /***=====================================================================***/
00727 static void bgrat(double *a,double *b,double *x,double *y,double *w,
00728            double *eps,int *ierr)
00729 /*
00730 -----------------------------------------------------------------------
00731      ASYMPTOTIC EXPANSION FOR IX(A,B) WHEN A IS LARGER THAN B.
00732      THE RESULT OF THE EXPANSION IS ADDED TO W. IT IS ASSUMED
00733      THAT A .GE. 15 AND B .LE. 1.  EPS IS THE TOLERANCE USED.
00734      IERR IS A VARIABLE THAT REPORTS THE STATUS OF THE RESULTS.
00735 -----------------------------------------------------------------------
00736 */
00737 {
00738 static double bm1,bp2n,cn,coef,dj,j,l,lnx,n2,nu,p,q,r,s,sum,t,t2,u,v,z;
00739 static int i,n,nm1;
00740 static double c[30],d[30],T1;
00741 /*
00742      ..
00743      .. Executable Statements ..
00744 */
00745     bm1 = *b-0.5e0-0.5e0;
00746     nu = *a+0.5e0*bm1;
00747     if(*y > 0.375e0) goto S10;
00748     T1 = -*y;
00749     lnx = alnrel(&T1);
00750     goto S20;
00751 S10:
00752     lnx = log(*x);
00753 S20:
00754     z = -(nu*lnx);
00755     if(*b*z == 0.0e0) goto S70;
00756 /*
00757                  COMPUTATION OF THE EXPANSION
00758                  SET R = EXP(-Z)*Z**B/GAMMA(B)
00759 */
00760     r = *b*(1.0e0+gam1(b))*exp(*b*log(z));
00761     r *= (exp(*a*lnx)*exp(0.5e0*bm1*lnx));
00762     u = algdiv(b,a)+*b*log(nu);
00763     u = r*exp(-u);
00764     if(u == 0.0e0) goto S70;
00765     grat1(b,&z,&r,&p,&q,eps);
00766     v = 0.25e0*pow(1.0e0/nu,2.0);
00767     t2 = 0.25e0*lnx*lnx;
00768     l = *w/u;
00769     j = q/r;
00770     sum = j;
00771     t = cn = 1.0e0;
00772     n2 = 0.0e0;
00773     for(n=1; n<=30; n++) {
00774         bp2n = *b+n2;
00775         j = (bp2n*(bp2n+1.0e0)*j+(z+bp2n+1.0e0)*t)*v;
00776         n2 += 2.0e0;
00777         t *= t2;
00778         cn /= (n2*(n2+1.0e0));
00779         c[n-1] = cn;
00780         s = 0.0e0;
00781         if(n == 1) goto S40;
00782         nm1 = n-1;
00783         coef = *b-(double)n;
00784         for(i=1; i<=nm1; i++) {
00785             s += (coef*c[i-1]*d[n-i-1]);
00786             coef += *b;
00787         }
00788 S40:
00789         d[n-1] = bm1*cn+s/(double)n;
00790         dj = d[n-1]*j;
00791         sum += dj;
00792         if(sum <= 0.0e0) goto S70;
00793         if(fabs(dj) <= *eps*(sum+l)) goto S60;
00794     }
00795 S60:
00796 /*
00797                     ADD THE RESULTS TO W
00798 */
00799     *ierr = 0;
00800     *w += (u*sum);
00801     return;
00802 S70:
00803 /*
00804                THE EXPANSION CANNOT BE COMPUTED
00805 */
00806     *ierr = 1;
00807     return;
00808 } /* END */
00809 
00810 /***=====================================================================***/
00811 static double bpser(double *a,double *b,double *x,double *eps)
00812 /*
00813 -----------------------------------------------------------------------
00814      POWER SERIES EXPANSION FOR EVALUATING IX(A,B) WHEN B .LE. 1
00815      OR B*X .LE. 0.7.  EPS IS THE TOLERANCE USED.
00816 -----------------------------------------------------------------------
00817 */
00818 {
00819 static double bpser,a0,apb,b0,c,n,sum,t,tol,u,w,z;
00820 static int i,m;
00821 /*
00822      ..
00823      .. Executable Statements ..
00824 */
00825     bpser = 0.0e0;
00826     if(*x == 0.0e0) return bpser;
00827 /*
00828 -----------------------------------------------------------------------
00829             COMPUTE THE FACTOR X**A/(A*BETA(A,B))
00830 -----------------------------------------------------------------------
00831 */
00832     a0 = fifdmin1(*a,*b);
00833     if(a0 < 1.0e0) goto S10;
00834     z = *a*log(*x)-betaln(a,b);
00835     bpser = exp(z)/ *a;
00836     goto S100;
00837 S10:
00838     b0 = fifdmax1(*a,*b);
00839     if(b0 >= 8.0e0) goto S90;
00840     if(b0 > 1.0e0) goto S40;
00841 /*
00842             PROCEDURE FOR A0 .LT. 1 AND B0 .LE. 1
00843 */
00844     bpser = pow(*x,*a);
00845     if(bpser == 0.0e0) return bpser;
00846     apb = *a+*b;
00847     if(apb > 1.0e0) goto S20;
00848     z = 1.0e0+gam1(&apb);
00849     goto S30;
00850 S20:
00851     u = *a+*b-1.e0;
00852     z = (1.0e0+gam1(&u))/apb;
00853 S30:
00854     c = (1.0e0+gam1(a))*(1.0e0+gam1(b))/z;
00855     bpser *= (c*(*b/apb));
00856     goto S100;
00857 S40:
00858 /*
00859          PROCEDURE FOR A0 .LT. 1 AND 1 .LT. B0 .LT. 8
00860 */
00861     u = gamln1(&a0);
00862     m = b0-1.0e0;
00863     if(m < 1) goto S60;
00864     c = 1.0e0;
00865     for(i=1; i<=m; i++) {
00866         b0 -= 1.0e0;
00867         c *= (b0/(a0+b0));
00868     }
00869     u = log(c)+u;
00870 S60:
00871     z = *a*log(*x)-u;
00872     b0 -= 1.0e0;
00873     apb = a0+b0;
00874     if(apb > 1.0e0) goto S70;
00875     t = 1.0e0+gam1(&apb);
00876     goto S80;
00877 S70:
00878     u = a0+b0-1.e0;
00879     t = (1.0e0+gam1(&u))/apb;
00880 S80:
00881     bpser = exp(z)*(a0/ *a)*(1.0e0+gam1(&b0))/t;
00882     goto S100;
00883 S90:
00884 /*
00885             PROCEDURE FOR A0 .LT. 1 AND B0 .GE. 8
00886 */
00887     u = gamln1(&a0)+algdiv(&a0,&b0);
00888     z = *a*log(*x)-u;
00889     bpser = a0/ *a*exp(z);
00890 S100:
00891     if(bpser == 0.0e0 || *a <= 0.1e0**eps) return bpser;
00892 /*
00893 -----------------------------------------------------------------------
00894                      COMPUTE THE SERIES
00895 -----------------------------------------------------------------------
00896 */
00897     sum = n = 0.0e0;
00898     c = 1.0e0;
00899     tol = *eps/ *a;
00900 S110:
00901     n += 1.0e0;
00902     c *= ((0.5e0+(0.5e0-*b/n))**x);
00903     w = c/(*a+n);
00904     sum += w;
00905     if(fabs(w) > tol) goto S110;
00906     bpser *= (1.0e0+*a*sum);
00907     return bpser;
00908 } /* END */
00909 
00910 /***=====================================================================***/
00911 static void bratio(double *a,double *b,double *x,double *y,double *w,
00912             double *w1,int *ierr)
00913 /*
00914 -----------------------------------------------------------------------
00915 
00916             EVALUATION OF THE INCOMPLETE BETA FUNCTION IX(A,B)
00917 
00918                      --------------------
00919 
00920      IT IS ASSUMED THAT A AND B ARE NONNEGATIVE, AND THAT X .LE. 1
00921      AND Y = 1 - X.  BRATIO ASSIGNS W AND W1 THE VALUES
00922 
00923                       W  = IX(A,B)
00924                       W1 = 1 - IX(A,B)
00925 
00926      IERR IS A VARIABLE THAT REPORTS THE STATUS OF THE RESULTS.
00927      IF NO INPUT ERRORS ARE DETECTED THEN IERR IS SET TO 0 AND
00928      W AND W1 ARE COMPUTED. OTHERWISE, IF AN ERROR IS DETECTED,
00929      THEN W AND W1 ARE ASSIGNED THE VALUE 0 AND IERR IS SET TO
00930      ONE OF THE FOLLOWING VALUES ...
00931 
00932         IERR = 1  IF A OR B IS NEGATIVE
00933         IERR = 2  IF A = B = 0
00934         IERR = 3  IF X .LT. 0 OR X .GT. 1
00935         IERR = 4  IF Y .LT. 0 OR Y .GT. 1
00936         IERR = 5  IF X + Y .NE. 1
00937         IERR = 6  IF X = A = 0
00938         IERR = 7  IF Y = B = 0
00939 
00940 --------------------
00941      WRITTEN BY ALFRED H. MORRIS, JR.
00942         NAVAL SURFACE WARFARE CENTER
00943         DAHLGREN, VIRGINIA
00944      REVISED ... NOV 1991
00945 -----------------------------------------------------------------------
00946 */
00947 {
00948 static int K1 = 1;
00949 static double a0,b0,eps,lambda,t,x0,y0,z;
00950 static int ierr1,ind,n;
00951 static double T2,T3,T4,T5;
00952 /*
00953      ..
00954      .. Executable Statements ..
00955 */
00956 /*
00957      ****** EPS IS A MACHINE DEPENDENT CONSTANT. EPS IS THE SMALLEST
00958             FLOATING POINT NUMBER FOR WHICH 1.0 + EPS .GT. 1.0
00959 */
00960     eps = spmpar(&K1);
00961     *w = *w1 = 0.0e0;
00962     if(*a < 0.0e0 || *b < 0.0e0) goto S270;
00963     if(*a == 0.0e0 && *b == 0.0e0) goto S280;
00964     if(*x < 0.0e0 || *x > 1.0e0) goto S290;
00965     if(*y < 0.0e0 || *y > 1.0e0) goto S300;
00966     z = *x+*y-0.5e0-0.5e0;
00967     if(fabs(z) > 3.0e0*eps) goto S310;
00968     *ierr = 0;
00969     if(*x == 0.0e0) goto S210;
00970     if(*y == 0.0e0) goto S230;
00971     if(*a == 0.0e0) goto S240;
00972     if(*b == 0.0e0) goto S220;
00973     eps = fifdmax1(eps,1.e-15);
00974     if(fifdmax1(*a,*b) < 1.e-3*eps) goto S260;
00975     ind = 0;
00976     a0 = *a;
00977     b0 = *b;
00978     x0 = *x;
00979     y0 = *y;
00980     if(fifdmin1(a0,b0) > 1.0e0) goto S40;
00981 /*
00982              PROCEDURE FOR A0 .LE. 1 OR B0 .LE. 1
00983 */
00984     if(*x <= 0.5e0) goto S10;
00985     ind = 1;
00986     a0 = *b;
00987     b0 = *a;
00988     x0 = *y;
00989     y0 = *x;
00990 S10:
00991     if(b0 < fifdmin1(eps,eps*a0)) goto S90;
00992     if(a0 < fifdmin1(eps,eps*b0) && b0*x0 <= 1.0e0) goto S100;
00993     if(fifdmax1(a0,b0) > 1.0e0) goto S20;
00994     if(a0 >= fifdmin1(0.2e0,b0)) goto S110;
00995     if(pow(x0,a0) <= 0.9e0) goto S110;
00996     if(x0 >= 0.3e0) goto S120;
00997     n = 20;
00998     goto S140;
00999 S20:
01000     if(b0 <= 1.0e0) goto S110;
01001     if(x0 >= 0.3e0) goto S120;
01002     if(x0 >= 0.1e0) goto S30;
01003     if(pow(x0*b0,a0) <= 0.7e0) goto S110;
01004 S30:
01005     if(b0 > 15.0e0) goto S150;
01006     n = 20;
01007     goto S140;
01008 S40:
01009 /*
01010              PROCEDURE FOR A0 .GT. 1 AND B0 .GT. 1
01011 */
01012     if(*a > *b) goto S50;
01013     lambda = *a-(*a+*b)**x;
01014     goto S60;
01015 S50:
01016     lambda = (*a+*b)**y-*b;
01017 S60:
01018     if(lambda >= 0.0e0) goto S70;
01019     ind = 1;
01020     a0 = *b;
01021     b0 = *a;
01022     x0 = *y;
01023     y0 = *x;
01024     lambda = fabs(lambda);
01025 S70:
01026     if(b0 < 40.0e0 && b0*x0 <= 0.7e0) goto S110;
01027     if(b0 < 40.0e0) goto S160;
01028     if(a0 > b0) goto S80;
01029     if(a0 <= 100.0e0) goto S130;
01030     if(lambda > 0.03e0*a0) goto S130;
01031     goto S200;
01032 S80:
01033     if(b0 <= 100.0e0) goto S130;
01034     if(lambda > 0.03e0*b0) goto S130;
01035     goto S200;
01036 S90:
01037 /*
01038             EVALUATION OF THE APPROPRIATE ALGORITHM
01039 */
01040     *w = fpser(&a0,&b0,&x0,&eps);
01041     *w1 = 0.5e0+(0.5e0-*w);
01042     goto S250;
01043 S100:
01044     *w1 = apser(&a0,&b0,&x0,&eps);
01045     *w = 0.5e0+(0.5e0-*w1);
01046     goto S250;
01047 S110:
01048     *w = bpser(&a0,&b0,&x0,&eps);
01049     *w1 = 0.5e0+(0.5e0-*w);
01050     goto S250;
01051 S120:
01052     *w1 = bpser(&b0,&a0,&y0,&eps);
01053     *w = 0.5e0+(0.5e0-*w1);
01054     goto S250;
01055 S130:
01056     T2 = 15.0e0*eps;
01057     *w = bfrac(&a0,&b0,&x0,&y0,&lambda,&T2);
01058     *w1 = 0.5e0+(0.5e0-*w);
01059     goto S250;
01060 S140:
01061     *w1 = bup(&b0,&a0,&y0,&x0,&n,&eps);
01062     b0 += (double)n;
01063 S150:
01064     T3 = 15.0e0*eps;
01065     bgrat(&b0,&a0,&y0,&x0,w1,&T3,&ierr1);
01066     *w = 0.5e0+(0.5e0-*w1);
01067     goto S250;
01068 S160:
01069     n = b0;
01070     b0 -= (double)n;
01071     if(b0 != 0.0e0) goto S170;
01072     n -= 1;
01073     b0 = 1.0e0;
01074 S170:
01075     *w = bup(&b0,&a0,&y0,&x0,&n,&eps);
01076     if(x0 > 0.7e0) goto S180;
01077     *w += bpser(&a0,&b0,&x0,&eps);
01078     *w1 = 0.5e0+(0.5e0-*w);
01079     goto S250;
01080 S180:
01081     if(a0 > 15.0e0) goto S190;
01082     n = 20;
01083     *w += bup(&a0,&b0,&x0,&y0,&n,&eps);
01084     a0 += (double)n;
01085 S190:
01086     T4 = 15.0e0*eps;
01087     bgrat(&a0,&b0,&x0,&y0,w,&T4,&ierr1);
01088     *w1 = 0.5e0+(0.5e0-*w);
01089     goto S250;
01090 S200:
01091     T5 = 100.0e0*eps;
01092     *w = basym(&a0,&b0,&lambda,&T5);
01093     *w1 = 0.5e0+(0.5e0-*w);
01094     goto S250;
01095 S210:
01096 /*
01097                TERMINATION OF THE PROCEDURE
01098 */
01099     if(*a == 0.0e0) goto S320;
01100 S220:
01101     *w = 0.0e0;
01102     *w1 = 1.0e0;
01103     return;
01104 S230:
01105     if(*b == 0.0e0) goto S330;
01106 S240:
01107     *w = 1.0e0;
01108     *w1 = 0.0e0;
01109     return;
01110 S250:
01111     if(ind == 0) return;
01112     t = *w;
01113     *w = *w1;
01114     *w1 = t;
01115     return;
01116 S260:
01117 /*
01118            PROCEDURE FOR A AND B .LT. 1.E-3*EPS
01119 */
01120     *w = *b/(*a+*b);
01121     *w1 = *a/(*a+*b);
01122     return;
01123 S270:
01124 /*
01125                        ERROR RETURN
01126 */
01127     *ierr = 1;
01128     return;
01129 S280:
01130     *ierr = 2;
01131     return;
01132 S290:
01133     *ierr = 3;
01134     return;
01135 S300:
01136     *ierr = 4;
01137     return;
01138 S310:
01139     *ierr = 5;
01140     return;
01141 S320:
01142     *ierr = 6;
01143     return;
01144 S330:
01145     *ierr = 7;
01146     return;
01147 } /* END */
01148 
01149 /***=====================================================================***/
01150 static double brcmp1(int *mu,double *a,double *b,double *x,double *y)
01151 /*
01152 -----------------------------------------------------------------------
01153           EVALUATION OF  EXP(MU) * (X**A*Y**B/BETA(A,B))
01154 -----------------------------------------------------------------------
01155 */
01156 {
01157 static double Const = .398942280401433e0;
01158 static double brcmp1,a0,apb,b0,c,e,h,lambda,lnx,lny,t,u,v,x0,y0,z;
01159 static int i,n;
01160 /*
01161 -----------------
01162      CONST = 1/SQRT(2*PI)
01163 -----------------
01164 */
01165 static double T1,T2,T3,T4;
01166 /*
01167      ..
01168      .. Executable Statements ..
01169 */
01170     a0 = fifdmin1(*a,*b);
01171     if(a0 >= 8.0e0) goto S130;
01172     if(*x > 0.375e0) goto S10;
01173     lnx = log(*x);
01174     T1 = -*x;
01175     lny = alnrel(&T1);
01176     goto S30;
01177 S10:
01178     if(*y > 0.375e0) goto S20;
01179     T2 = -*y;
01180     lnx = alnrel(&T2);
01181     lny = log(*y);
01182     goto S30;
01183 S20:
01184     lnx = log(*x);
01185     lny = log(*y);
01186 S30:
01187     z = *a*lnx+*b*lny;
01188     if(a0 < 1.0e0) goto S40;
01189     z -= betaln(a,b);
01190     brcmp1 = esum(mu,&z);
01191     return brcmp1;
01192 S40:
01193 /*
01194 -----------------------------------------------------------------------
01195               PROCEDURE FOR A .LT. 1 OR B .LT. 1
01196 -----------------------------------------------------------------------
01197 */
01198     b0 = fifdmax1(*a,*b);
01199     if(b0 >= 8.0e0) goto S120;
01200     if(b0 > 1.0e0) goto S70;
01201 /*
01202                    ALGORITHM FOR B0 .LE. 1
01203 */
01204     brcmp1 = esum(mu,&z);
01205     if(brcmp1 == 0.0e0) return brcmp1;
01206     apb = *a+*b;
01207     if(apb > 1.0e0) goto S50;
01208     z = 1.0e0+gam1(&apb);
01209     goto S60;
01210 S50:
01211     u = *a+*b-1.e0;
01212     z = (1.0e0+gam1(&u))/apb;
01213 S60:
01214     c = (1.0e0+gam1(a))*(1.0e0+gam1(b))/z;
01215     brcmp1 = brcmp1*(a0*c)/(1.0e0+a0/b0);
01216     return brcmp1;
01217 S70:
01218 /*
01219                 ALGORITHM FOR 1 .LT. B0 .LT. 8
01220 */
01221     u = gamln1(&a0);
01222     n = b0-1.0e0;
01223     if(n < 1) goto S90;
01224     c = 1.0e0;
01225     for(i=1; i<=n; i++) {
01226         b0 -= 1.0e0;
01227         c *= (b0/(a0+b0));
01228     }
01229     u = log(c)+u;
01230 S90:
01231     z -= u;
01232     b0 -= 1.0e0;
01233     apb = a0+b0;
01234     if(apb > 1.0e0) goto S100;
01235     t = 1.0e0+gam1(&apb);
01236     goto S110;
01237 S100:
01238     u = a0+b0-1.e0;
01239     t = (1.0e0+gam1(&u))/apb;
01240 S110:
01241     brcmp1 = a0*esum(mu,&z)*(1.0e0+gam1(&b0))/t;
01242     return brcmp1;
01243 S120:
01244 /*
01245                    ALGORITHM FOR B0 .GE. 8
01246 */
01247     u = gamln1(&a0)+algdiv(&a0,&b0);
01248     T3 = z-u;
01249     brcmp1 = a0*esum(mu,&T3);
01250     return brcmp1;
01251 S130:
01252 /*
01253 -----------------------------------------------------------------------
01254               PROCEDURE FOR A .GE. 8 AND B .GE. 8
01255 -----------------------------------------------------------------------
01256 */
01257     if(*a > *b) goto S140;
01258     h = *a/ *b;
01259     x0 = h/(1.0e0+h);
01260     y0 = 1.0e0/(1.0e0+h);
01261     lambda = *a-(*a+*b)**x;
01262     goto S150;
01263 S140:
01264     h = *b/ *a;
01265     x0 = 1.0e0/(1.0e0+h);
01266     y0 = h/(1.0e0+h);
01267     lambda = (*a+*b)**y-*b;
01268 S150:
01269     e = -(lambda/ *a);
01270     if(fabs(e) > 0.6e0) goto S160;
01271     u = rlog1(&e);
01272     goto S170;
01273 S160:
01274     u = e-log(*x/x0);
01275 S170:
01276     e = lambda/ *b;
01277     if(fabs(e) > 0.6e0) goto S180;
01278     v = rlog1(&e);
01279     goto S190;
01280 S180:
01281     v = e-log(*y/y0);
01282 S190:
01283     T4 = -(*a*u+*b*v);
01284     z = esum(mu,&T4);
01285     brcmp1 = Const*sqrt(*b*x0)*z*exp(-bcorr(a,b));
01286     return brcmp1;
01287 } /* END */
01288 
01289 /***=====================================================================***/
01290 static double brcomp(double *a,double *b,double *x,double *y)
01291 /*
01292 -----------------------------------------------------------------------
01293                EVALUATION OF X**A*Y**B/BETA(A,B)
01294 -----------------------------------------------------------------------
01295 */
01296 {
01297 static double Const = .398942280401433e0;
01298 static double brcomp,a0,apb,b0,c,e,h,lambda,lnx,lny,t,u,v,x0,y0,z;
01299 static int i,n;
01300 /*
01301 -----------------
01302      CONST = 1/SQRT(2*PI)
01303 -----------------
01304 */
01305 static double T1,T2;
01306 /*
01307      ..
01308      .. Executable Statements ..
01309 */
01310     brcomp = 0.0e0;
01311     if(*x == 0.0e0 || *y == 0.0e0) return brcomp;
01312     a0 = fifdmin1(*a,*b);
01313     if(a0 >= 8.0e0) goto S130;
01314     if(*x > 0.375e0) goto S10;
01315     lnx = log(*x);
01316     T1 = -*x;
01317     lny = alnrel(&T1);
01318     goto S30;
01319 S10:
01320     if(*y > 0.375e0) goto S20;
01321     T2 = -*y;
01322     lnx = alnrel(&T2);
01323     lny = log(*y);
01324     goto S30;
01325 S20:
01326     lnx = log(*x);
01327     lny = log(*y);
01328 S30:
01329     z = *a*lnx+*b*lny;
01330     if(a0 < 1.0e0) goto S40;
01331     z -= betaln(a,b);
01332     brcomp = exp(z);
01333     return brcomp;
01334 S40:
01335 /*
01336 -----------------------------------------------------------------------
01337               PROCEDURE FOR A .LT. 1 OR B .LT. 1
01338 -----------------------------------------------------------------------
01339 */
01340     b0 = fifdmax1(*a,*b);
01341     if(b0 >= 8.0e0) goto S120;
01342     if(b0 > 1.0e0) goto S70;
01343 /*
01344                    ALGORITHM FOR B0 .LE. 1
01345 */
01346     brcomp = exp(z);
01347     if(brcomp == 0.0e0) return brcomp;
01348     apb = *a+*b;
01349     if(apb > 1.0e0) goto S50;
01350     z = 1.0e0+gam1(&apb);
01351     goto S60;
01352 S50:
01353     u = *a+*b-1.e0;
01354     z = (1.0e0+gam1(&u))/apb;
01355 S60:
01356     c = (1.0e0+gam1(a))*(1.0e0+gam1(b))/z;
01357     brcomp = brcomp*(a0*c)/(1.0e0+a0/b0);
01358     return brcomp;
01359 S70:
01360 /*
01361                 ALGORITHM FOR 1 .LT. B0 .LT. 8
01362 */
01363     u = gamln1(&a0);
01364     n = b0-1.0e0;
01365     if(n < 1) goto S90;
01366     c = 1.0e0;
01367     for(i=1; i<=n; i++) {
01368         b0 -= 1.0e0;
01369         c *= (b0/(a0+b0));
01370     }
01371     u = log(c)+u;
01372 S90:
01373     z -= u;
01374     b0 -= 1.0e0;
01375     apb = a0+b0;
01376     if(apb > 1.0e0) goto S100;
01377     t = 1.0e0+gam1(&apb);
01378     goto S110;
01379 S100:
01380     u = a0+b0-1.e0;
01381     t = (1.0e0+gam1(&u))/apb;
01382 S110:
01383     brcomp = a0*exp(z)*(1.0e0+gam1(&b0))/t;
01384     return brcomp;
01385 S120:
01386 /*
01387                    ALGORITHM FOR B0 .GE. 8
01388 */
01389     u = gamln1(&a0)+algdiv(&a0,&b0);
01390     brcomp = a0*exp(z-u);
01391     return brcomp;
01392 S130:
01393 /*
01394 -----------------------------------------------------------------------
01395               PROCEDURE FOR A .GE. 8 AND B .GE. 8
01396 -----------------------------------------------------------------------
01397 */
01398     if(*a > *b) goto S140;
01399     h = *a/ *b;
01400     x0 = h/(1.0e0+h);
01401     y0 = 1.0e0/(1.0e0+h);
01402     lambda = *a-(*a+*b)**x;
01403     goto S150;
01404 S140:
01405     h = *b/ *a;
01406     x0 = 1.0e0/(1.0e0+h);
01407     y0 = h/(1.0e0+h);
01408     lambda = (*a+*b)**y-*b;
01409 S150:
01410     e = -(lambda/ *a);
01411     if(fabs(e) > 0.6e0) goto S160;
01412     u = rlog1(&e);
01413     goto S170;
01414 S160:
01415     u = e-log(*x/x0);
01416 S170:
01417     e = lambda/ *b;
01418     if(fabs(e) > 0.6e0) goto S180;
01419     v = rlog1(&e);
01420     goto S190;
01421 S180:
01422     v = e-log(*y/y0);
01423 S190:
01424     z = exp(-(*a*u+*b*v));
01425     brcomp = Const*sqrt(*b*x0)*z*exp(-bcorr(a,b));
01426     return brcomp;
01427 } /* END */
01428 
01429 /***=====================================================================***/
01430 static double bup(double *a,double *b,double *x,double *y,int *n,double *eps)
01431 /*
01432 -----------------------------------------------------------------------
01433      EVALUATION OF IX(A,B) - IX(A+N,B) WHERE N IS A POSITIVE INTEGER.
01434      EPS IS THE TOLERANCE USED.
01435 -----------------------------------------------------------------------
01436 */
01437 {
01438 static int K1 = 1;
01439 static int K2 = 0;
01440 static double bup,ap1,apb,d,l,r,t,w;
01441 static int i,k,kp1,mu,nm1;
01442 /*
01443      ..
01444      .. Executable Statements ..
01445 */
01446 /*
01447           OBTAIN THE SCALING FACTOR EXP(-MU) AND
01448              EXP(MU)*(X**A*Y**B/BETA(A,B))/A
01449 */
01450     apb = *a+*b;
01451     ap1 = *a+1.0e0;
01452     mu = 0;
01453     d = 1.0e0;
01454     if(*n == 1 || *a < 1.0e0) goto S10;
01455     if(apb < 1.1e0*ap1) goto S10;
01456     mu = fabs(exparg(&K1));
01457     k = exparg(&K2);
01458     if(k < mu) mu = k;
01459     t = mu;
01460     d = exp(-t);
01461 S10:
01462     bup = brcmp1(&mu,a,b,x,y)/ *a;
01463     if(*n == 1 || bup == 0.0e0) return bup;
01464     nm1 = *n-1;
01465     w = d;
01466 /*
01467           LET K BE THE INDEX OF THE MAXIMUM TERM
01468 */
01469     k = 0;
01470     if(*b <= 1.0e0) goto S50;
01471     if(*y > 1.e-4) goto S20;
01472     k = nm1;
01473     goto S30;
01474 S20:
01475     r = (*b-1.0e0)**x/ *y-*a;
01476     if(r < 1.0e0) goto S50;
01477     k = t = nm1;
01478     if(r < t) k = r;
01479 S30:
01480 /*
01481           ADD THE INCREASING TERMS OF THE SERIES
01482 */
01483     for(i=1; i<=k; i++) {
01484         l = i-1;
01485         d = (apb+l)/(ap1+l)**x*d;
01486         w += d;
01487     }
01488     if(k == nm1) goto S70;
01489 S50:
01490 /*
01491           ADD THE REMAINING TERMS OF THE SERIES
01492 */
01493     kp1 = k+1;
01494     for(i=kp1; i<=nm1; i++) {
01495         l = i-1;
01496         d = (apb+l)/(ap1+l)**x*d;
01497         w += d;
01498         if(d <= *eps*w) goto S70;
01499     }
01500 S70:
01501 /*
01502                TERMINATE THE PROCEDURE
01503 */
01504     bup *= w;
01505     return bup;
01506 } /* END */
01507 
01508 /***=====================================================================***/
01509 static void cdfbet(int *which,double *p,double *q,double *x,double *y,
01510             double *a,double *b,int *status,double *bound)
01511 /**********************************************************************
01512 
01513       void cdfbet(int *which,double *p,double *q,double *x,double *y,
01514             double *a,double *b,int *status,double *bound)
01515 
01516                Cumulative Distribution Function
01517                          BETa Distribution
01518 
01519 
01520                               Function
01521 
01522 
01523      Calculates any one parameter of the beta distribution given
01524      values for the others.
01525 
01526 
01527                               Arguments
01528 
01529 
01530      WHICH --> Integer indicating which of the next four argument
01531                values is to be calculated from the others.
01532                Legal range: 1..4
01533                iwhich = 1 : Calculate P and Q from X,Y,A and B
01534                iwhich = 2 : Calculate X and Y from P,Q,A and B
01535                iwhich = 3 : Calculate A from P,Q,X,Y and B
01536                iwhich = 4 : Calculate B from P,Q,X,Y and A
01537 
01538      P <--> The integral from 0 to X of the chi-square
01539             distribution.
01540             Input range: [0, 1].
01541 
01542      Q <--> 1-P.
01543             Input range: [0, 1].
01544             P + Q = 1.0.
01545 
01546      X <--> Upper limit of integration of beta density.
01547             Input range: [0,1].
01548             Search range: [0,1]
01549 
01550      Y <--> 1-X.
01551             Input range: [0,1].
01552             Search range: [0,1]
01553             X + Y = 1.0.
01554 
01555      A <--> The first parameter of the beta density.
01556             Input range: (0, +infinity).
01557             Search range: [1D-300,1D300]
01558 
01559      B <--> The second parameter of the beta density.
01560             Input range: (0, +infinity).
01561             Search range: [1D-300,1D300]
01562 
01563      STATUS <-- 0 if calculation completed correctly
01564                -I if input parameter number I is out of range
01565                 1 if answer appears to be lower than lowest
01566                   search bound
01567                 2 if answer appears to be higher than greatest
01568                   search bound
01569                 3 if P + Q .ne. 1
01570                 4 if X + Y .ne. 1
01571 
01572      BOUND <-- Undefined if STATUS is 0
01573 
01574                Bound exceeded by parameter number I if STATUS
01575                is negative.
01576 
01577                Lower search bound if STATUS is 1.
01578 
01579                Upper search bound if STATUS is 2.
01580 
01581 
01582                               Method
01583 
01584 
01585      Cumulative distribution function  (P)  is calculated directly by
01586      code associated with the following reference.
01587 
01588      DiDinato, A. R. and Morris,  A.   H.  Algorithm 708: Significant
01589      Digit Computation of the Incomplete  Beta  Function Ratios.  ACM
01590      Trans. Math.  Softw. 18 (1993), 360-373.
01591 
01592      Computation of other parameters involve a seach for a value that
01593      produces  the desired  value  of P.   The search relies  on  the
01594      monotinicity of P with the other parameter.
01595 
01596 
01597                               Note
01598 
01599 
01600      The beta density is proportional to
01601                t^(A-1) * (1-t)^(B-1)
01602 
01603 **********************************************************************/
01604 {
01605 #define tol (1.0e-8)
01606 #define atol (1.0e-50)
01607 #define zero (1.0e-300)
01608 #define inf 1.0e300
01609 #define one 1.0e0
01610 static int K1 = 1;
01611 static double K2 = 0.0e0;
01612 static double K3 = 1.0e0;
01613 static double K8 = 0.5e0;
01614 static double K9 = 5.0e0;
01615 static double fx,xhi,xlo,cum,ccum,xy,pq;
01616 static unsigned long qhi,qleft,qporq;
01617 static double T4,T5,T6,T7,T10,T11,T12,T13,T14,T15;
01618 /*
01619      ..
01620      .. Executable Statements ..
01621 */
01622 /*
01623      Check arguments
01624 */
01625     if(!(*which < 1 || *which > 4)) goto S30;
01626     if(!(*which < 1)) goto S10;
01627     *bound = 1.0e0;
01628     goto S20;
01629 S10:
01630     *bound = 4.0e0;
01631 S20:
01632     *status = -1;
01633     return;
01634 S30:
01635     if(*which == 1) goto S70;
01636 /*
01637      P
01638 */
01639     if(!(*p < 0.0e0 || *p > 1.0e0)) goto S60;
01640     if(!(*p < 0.0e0)) goto S40;
01641     *bound = 0.0e0;
01642     goto S50;
01643 S40:
01644     *bound = 1.0e0;
01645 S50:
01646     *status = -2;
01647     return;
01648 S70:
01649 S60:
01650     if(*which == 1) goto S110;
01651 /*
01652      Q
01653 */
01654     if(!(*q < 0.0e0 || *q > 1.0e0)) goto S100;
01655     if(!(*q < 0.0e0)) goto S80;
01656     *bound = 0.0e0;
01657     goto S90;
01658 S80:
01659     *bound = 1.0e0;
01660 S90:
01661     *status = -3;
01662     return;
01663 S110:
01664 S100:
01665     if(*which == 2) goto S150;
01666 /*
01667      X
01668 */
01669     if(!(*x < 0.0e0 || *x > 1.0e0)) goto S140;
01670     if(!(*x < 0.0e0)) goto S120;
01671     *bound = 0.0e0;
01672     goto S130;
01673 S120:
01674     *bound = 1.0e0;
01675 S130:
01676     *status = -4;
01677     return;
01678 S150:
01679 S140:
01680     if(*which == 2) goto S190;
01681 /*
01682      Y
01683 */
01684     if(!(*y < 0.0e0 || *y > 1.0e0)) goto S180;
01685     if(!(*y < 0.0e0)) goto S160;
01686     *bound = 0.0e0;
01687     goto S170;
01688 S160:
01689     *bound = 1.0e0;
01690 S170:
01691     *status = -5;
01692     return;
01693 S190:
01694 S180:
01695     if(*which == 3) goto S210;
01696 /*
01697      A
01698 */
01699     if(!(*a <= 0.0e0)) goto S200;
01700     *bound = 0.0e0;
01701     *status = -6;
01702     return;
01703 S210:
01704 S200:
01705     if(*which == 4) goto S230;
01706 /*
01707      B
01708 */
01709     if(!(*b <= 0.0e0)) goto S220;
01710     *bound = 0.0e0;
01711     *status = -7;
01712     return;
01713 S230:
01714 S220:
01715     if(*which == 1) goto S270;
01716 /*
01717      P + Q
01718 */
01719     pq = *p+*q;
01720     if(!(fabs(pq-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S260;
01721     if(!(pq < 0.0e0)) goto S240;
01722     *bound = 0.0e0;
01723     goto S250;
01724 S240:
01725     *bound = 1.0e0;
01726 S250:
01727     *status = 3;
01728     return;
01729 S270:
01730 S260:
01731     if(*which == 2) goto S310;
01732 /*
01733      X + Y
01734 */
01735     xy = *x+*y;
01736     if(!(fabs(xy-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S300;
01737     if(!(xy < 0.0e0)) goto S280;
01738     *bound = 0.0e0;
01739     goto S290;
01740 S280:
01741     *bound = 1.0e0;
01742 S290:
01743     *status = 4;
01744     return;
01745 S310:
01746 S300:
01747     if(!(*which == 1)) qporq = *p <= *q;
01748 /*
01749      Select the minimum of P or Q
01750      Calculate ANSWERS
01751 */
01752     if(1 == *which) {
01753 /*
01754      Calculating P and Q
01755 */
01756         cumbet(x,y,a,b,p,q);
01757         *status = 0;
01758     }
01759     else if(2 == *which) {
01760 /*
01761      Calculating X and Y
01762 */
01763         T4 = atol;
01764         T5 = tol;
01765         dstzr(&K2,&K3,&T4,&T5);
01766         if(!qporq) goto S340;
01767         *status = 0;
01768         dzror(status,x,&fx,&xlo,&xhi,&qleft,&qhi);
01769         *y = one-*x;
01770 S320:
01771         if(!(*status == 1)) goto S330;
01772         cumbet(x,y,a,b,&cum,&ccum);
01773         fx = cum-*p;
01774         dzror(status,x,&fx,&xlo,&xhi,&qleft,&qhi);
01775         *y = one-*x;
01776         goto S320;
01777 S330:
01778         goto S370;
01779 S340:
01780         *status = 0;
01781         dzror(status,y,&fx,&xlo,&xhi,&qleft,&qhi);
01782         *x = one-*y;
01783 S350:
01784         if(!(*status == 1)) goto S360;
01785         cumbet(x,y,a,b,&cum,&ccum);
01786         fx = ccum-*q;
01787         dzror(status,y,&fx,&xlo,&xhi,&qleft,&qhi);
01788         *x = one-*y;
01789         goto S350;
01790 S370:
01791 S360:
01792         if(!(*status == -1)) goto S400;
01793         if(!qleft) goto S380;
01794         *status = 1;
01795         *bound = 0.0e0;
01796         goto S390;
01797 S380:
01798         *status = 2;
01799         *bound = 1.0e0;
01800 S400:
01801 S390:
01802         ;
01803     }
01804     else if(3 == *which) {
01805 /*
01806      Computing A
01807 */
01808         *a = 5.0e0;
01809         T6 = zero;
01810         T7 = inf;
01811         T10 = atol;
01812         T11 = tol;
01813         dstinv(&T6,&T7,&K8,&K8,&K9,&T10,&T11);
01814         *status = 0;
01815         dinvr(status,a,&fx,&qleft,&qhi);
01816 S410:
01817         if(!(*status == 1)) goto S440;
01818         cumbet(x,y,a,b,&cum,&ccum);
01819         if(!qporq) goto S420;
01820         fx = cum-*p;
01821         goto S430;
01822 S420:
01823         fx = ccum-*q;
01824 S430:
01825         dinvr(status,a,&fx,&qleft,&qhi);
01826         goto S410;
01827 S440:
01828         if(!(*status == -1)) goto S470;
01829         if(!qleft) goto S450;
01830         *status = 1;
01831         *bound = zero;
01832         goto S460;
01833 S450:
01834         *status = 2;
01835         *bound = inf;
01836 S470:
01837 S460:
01838         ;
01839     }
01840     else if(4 == *which) {
01841 /*
01842      Computing B
01843 */
01844         *b = 5.0e0;
01845         T12 = zero;
01846         T13 = inf;
01847         T14 = atol;
01848         T15 = tol;
01849         dstinv(&T12,&T13,&K8,&K8,&K9,&T14,&T15);
01850         *status = 0;
01851         dinvr(status,b,&fx,&qleft,&qhi);
01852 S480:
01853         if(!(*status == 1)) goto S510;
01854         cumbet(x,y,a,b,&cum,&ccum);
01855         if(!qporq) goto S490;
01856         fx = cum-*p;
01857         goto S500;
01858 S490:
01859         fx = ccum-*q;
01860 S500:
01861         dinvr(status,b,&fx,&qleft,&qhi);
01862         goto S480;
01863 S510:
01864         if(!(*status == -1)) goto S540;
01865         if(!qleft) goto S520;
01866         *status = 1;
01867         *bound = zero;
01868         goto S530;
01869 S520:
01870         *status = 2;
01871         *bound = inf;
01872 S530:
01873         ;
01874     }
01875 S540:
01876     return;
01877 #undef tol
01878 #undef atol
01879 #undef zero
01880 #undef inf
01881 #undef one
01882 } /* END */
01883 
01884 /***=====================================================================***/
01885 static void cdfbin(int *which,double *p,double *q,double *s,double *xn,
01886             double *pr,double *ompr,int *status,double *bound)
01887 /**********************************************************************
01888 
01889       void cdfbin(int *which,double *p,double *q,double *s,double *xn,
01890             double *pr,double *ompr,int *status,double *bound)
01891 
01892                Cumulative Distribution Function
01893                          BINomial distribution
01894 
01895 
01896                               Function
01897 
01898 
01899      Calculates any one parameter of the binomial
01900      distribution given values for the others.
01901 
01902 
01903                               Arguments
01904 
01905 
01906      WHICH --> Integer indicating which of the next four argument
01907                values is to be calculated from the others.
01908                Legal range: 1..4
01909                iwhich = 1 : Calculate P and Q from S,XN,PR and OMPR
01910                iwhich = 2 : Calculate S from P,Q,XN,PR and OMPR
01911                iwhich = 3 : Calculate XN from P,Q,S,PR and OMPR
01912                iwhich = 4 : Calculate PR and OMPR from P,Q,S and XN
01913 
01914      P <--> The cumulation from 0 to S of the binomial distribution.
01915             (Probablility of S or fewer successes in XN trials each
01916             with probability of success PR.)
01917             Input range: [0,1].
01918 
01919      Q <--> 1-P.
01920             Input range: [0, 1].
01921             P + Q = 1.0.
01922 
01923      S <--> The number of successes observed.
01924             Input range: [0, XN]
01925             Search range: [0, XN]
01926 
01927      XN  <--> The number of binomial trials.
01928               Input range: (0, +infinity).
01929               Search range: [1E-300, 1E300]
01930 
01931      PR  <--> The probability of success in each binomial trial.
01932               Input range: [0,1].
01933               Search range: [0,1]
01934 
01935      OMPR  <--> 1-PR
01936               Input range: [0,1].
01937               Search range: [0,1]
01938               PR + OMPR = 1.0
01939 
01940      STATUS <-- 0 if calculation completed correctly
01941                -I if input parameter number I is out of range
01942                 1 if answer appears to be lower than lowest
01943                   search bound
01944                 2 if answer appears to be higher than greatest
01945                   search bound
01946                 3 if P + Q .ne. 1
01947                 4 if PR + OMPR .ne. 1
01948 
01949      BOUND <-- Undefined if STATUS is 0
01950 
01951                Bound exceeded by parameter number I if STATUS
01952                is negative.
01953 
01954                Lower search bound if STATUS is 1.
01955 
01956                Upper search bound if STATUS is 2.
01957 
01958 
01959                               Method
01960 
01961 
01962      Formula  26.5.24    of   Abramowitz  and    Stegun,  Handbook   of
01963      Mathematical   Functions (1966) is   used  to reduce the  binomial
01964      distribution  to  the  cumulative incomplete    beta distribution.
01965 
01966      Computation of other parameters involve a seach for a value that
01967      produces  the desired  value  of P.   The search relies  on  the
01968      monotinicity of P with the other parameter.
01969 
01970 
01971 **********************************************************************/
01972 {
01973 #define atol (1.0e-50)
01974 #define tol (1.0e-8)
01975 #define zero (1.0e-300)
01976 #define inf 1.0e300
01977 #define one 1.0e0
01978 static int K1 = 1;
01979 static double K2 = 0.0e0;
01980 static double K3 = 0.5e0;
01981 static double K4 = 5.0e0;
01982 static double K11 = 1.0e0;
01983 static double fx,xhi,xlo,cum,ccum,pq,prompr;
01984 static unsigned long qhi,qleft,qporq;
01985 static double T5,T6,T7,T8,T9,T10,T12,T13;
01986 /*
01987      ..
01988      .. Executable Statements ..
01989 */
01990 /*
01991      Check arguments
01992 */
01993     if(!(*which < 1 && *which > 4)) goto S30;
01994     if(!(*which < 1)) goto S10;
01995     *bound = 1.0e0;
01996     goto S20;
01997 S10:
01998     *bound = 4.0e0;
01999 S20:
02000     *status = -1;
02001     return;
02002 S30:
02003     if(*which == 1) goto S70;
02004 /*
02005      P
02006 */
02007     if(!(*p < 0.0e0 || *p > 1.0e0)) goto S60;
02008     if(!(*p < 0.0e0)) goto S40;
02009     *bound = 0.0e0;
02010     goto S50;
02011 S40:
02012     *bound = 1.0e0;
02013 S50:
02014     *status = -2;
02015     return;
02016 S70:
02017 S60:
02018     if(*which == 1) goto S110;
02019 /*
02020      Q
02021 */
02022     if(!(*q < 0.0e0 || *q > 1.0e0)) goto S100;
02023     if(!(*q < 0.0e0)) goto S80;
02024     *bound = 0.0e0;
02025     goto S90;
02026 S80:
02027     *bound = 1.0e0;
02028 S90:
02029     *status = -3;
02030     return;
02031 S110:
02032 S100:
02033     if(*which == 3) goto S130;
02034 /*
02035      XN
02036 */
02037     if(!(*xn <= 0.0e0)) goto S120;
02038     *bound = 0.0e0;
02039     *status = -5;
02040     return;
02041 S130:
02042 S120:
02043     if(*which == 2) goto S170;
02044 /*
02045      S
02046 */
02047     if(!(*s < 0.0e0 || *which != 3 && *s > *xn)) goto S160;
02048     if(!(*s < 0.0e0)) goto S140;
02049     *bound = 0.0e0;
02050     goto S150;
02051 S140:
02052     *bound = *xn;
02053 S150:
02054     *status = -4;
02055     return;
02056 S170:
02057 S160:
02058     if(*which == 4) goto S210;
02059 /*
02060      PR
02061 */
02062     if(!(*pr < 0.0e0 || *pr > 1.0e0)) goto S200;
02063     if(!(*pr < 0.0e0)) goto S180;
02064     *bound = 0.0e0;
02065     goto S190;
02066 S180:
02067     *bound = 1.0e0;
02068 S190:
02069     *status = -6;
02070     return;
02071 S210:
02072 S200:
02073     if(*which == 4) goto S250;
02074 /*
02075      OMPR
02076 */
02077     if(!(*ompr < 0.0e0 || *ompr > 1.0e0)) goto S240;
02078     if(!(*ompr < 0.0e0)) goto S220;
02079     *bound = 0.0e0;
02080     goto S230;
02081 S220:
02082     *bound = 1.0e0;
02083 S230:
02084     *status = -7;
02085     return;
02086 S250:
02087 S240:
02088     if(*which == 1) goto S290;
02089 /*
02090      P + Q
02091 */
02092     pq = *p+*q;
02093     if(!(fabs(pq-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S280;
02094     if(!(pq < 0.0e0)) goto S260;
02095     *bound = 0.0e0;
02096     goto S270;
02097 S260:
02098     *bound = 1.0e0;
02099 S270:
02100     *status = 3;
02101     return;
02102 S290:
02103 S280:
02104     if(*which == 4) goto S330;
02105 /*
02106      PR + OMPR
02107 */
02108     prompr = *pr+*ompr;
02109     if(!(fabs(prompr-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S320;
02110     if(!(prompr < 0.0e0)) goto S300;
02111     *bound = 0.0e0;
02112     goto S310;
02113 S300:
02114     *bound = 1.0e0;
02115 S310:
02116     *status = 4;
02117     return;
02118 S330:
02119 S320:
02120     if(!(*which == 1)) qporq = *p <= *q;
02121 /*
02122      Select the minimum of P or Q
02123      Calculate ANSWERS
02124 */
02125     if(1 == *which) {
02126 /*
02127      Calculating P
02128 */
02129         cumbin(s,xn,pr,ompr,p,q);
02130         *status = 0;
02131     }
02132     else if(2 == *which) {
02133 /*
02134      Calculating S
02135 */
02136         *s = 5.0e0;
02137         T5 = atol;
02138         T6 = tol;
02139         dstinv(&K2,xn,&K3,&K3,&K4,&T5,&T6);
02140         *status = 0;
02141         dinvr(status,s,&fx,&qleft,&qhi);
02142 S340:
02143         if(!(*status == 1)) goto S370;
02144         cumbin(s,xn,pr,ompr,&cum,&ccum);
02145         if(!qporq) goto S350;
02146         fx = cum-*p;
02147         goto S360;
02148 S350:
02149         fx = ccum-*q;
02150 S360:
02151         dinvr(status,s,&fx,&qleft,&qhi);
02152         goto S340;
02153 S370:
02154         if(!(*status == -1)) goto S400;
02155         if(!qleft) goto S380;
02156         *status = 1;
02157         *bound = 0.0e0;
02158         goto S390;
02159 S380:
02160         *status = 2;
02161         *bound = *xn;
02162 S400:
02163 S390:
02164         ;
02165     }
02166     else if(3 == *which) {
02167 /*
02168      Calculating XN
02169 */
02170         *xn = 5.0e0;
02171         T7 = zero;
02172         T8 = inf;
02173         T9 = atol;
02174         T10 = tol;
02175         dstinv(&T7,&T8,&K3,&K3,&K4,&T9,&T10);
02176         *status = 0;
02177         dinvr(status,xn,&fx,&qleft,&qhi);
02178 S410:
02179         if(!(*status == 1)) goto S440;
02180         cumbin(s,xn,pr,ompr,&cum,&ccum);
02181         if(!qporq) goto S420;
02182         fx = cum-*p;
02183         goto S430;
02184 S420:
02185         fx = ccum-*q;
02186 S430:
02187         dinvr(status,xn,&fx,&qleft,&qhi);
02188         goto S410;
02189 S440:
02190         if(!(*status == -1)) goto S470;
02191         if(!qleft) goto S450;
02192         *status = 1;
02193         *bound = zero;
02194         goto S460;
02195 S450:
02196         *status = 2;
02197         *bound = inf;
02198 S470:
02199 S460:
02200         ;
02201     }
02202     else if(4 == *which) {
02203 /*
02204      Calculating PR and OMPR
02205 */
02206         T12 = atol;
02207         T13 = tol;
02208         dstzr(&K2,&K11,&T12,&T13);
02209         if(!qporq) goto S500;
02210         *status = 0;
02211         dzror(status,pr,&fx,&xlo,&xhi,&qleft,&qhi);
02212         *ompr = one-*pr;
02213 S480:
02214         if(!(*status == 1)) goto S490;
02215         cumbin(s,xn,pr,ompr,&cum,&ccum);
02216         fx = cum-*p;
02217         dzror(status,pr,&fx,&xlo,&xhi,&qleft,&qhi);
02218         *ompr = one-*pr;
02219         goto S480;
02220 S490:
02221         goto S530;
02222 S500:
02223         *status = 0;
02224         dzror(status,ompr,&fx,&xlo,&xhi,&qleft,&qhi);
02225         *pr = one-*ompr;
02226 S510:
02227         if(!(*status == 1)) goto S520;
02228         cumbin(s,xn,pr,ompr,&cum,&ccum);
02229         fx = ccum-*q;
02230         dzror(status,ompr,&fx,&xlo,&xhi,&qleft,&qhi);
02231         *pr = one-*ompr;
02232         goto S510;
02233 S530:
02234 S520:
02235         if(!(*status == -1)) goto S560;
02236         if(!qleft) goto S540;
02237         *status = 1;
02238         *bound = 0.0e0;
02239         goto S550;
02240 S540:
02241         *status = 2;
02242         *bound = 1.0e0;
02243 S550:
02244         ;
02245     }
02246 S560:
02247     return;
02248 #undef atol
02249 #undef tol
02250 #undef zero
02251 #undef inf
02252 #undef one
02253 } /* END */
02254 
02255 /***=====================================================================***/
02256 static void cdfchi(int *which,double *p,double *q,double *x,double *df,
02257             int *status,double *bound)
02258 /**********************************************************************
02259 
02260       void cdfchi(int *which,double *p,double *q,double *x,double *df,
02261             int *status,double *bound)
02262 
02263                Cumulative Distribution Function
02264                CHI-Square distribution
02265 
02266 
02267                               Function
02268 
02269 
02270      Calculates any one parameter of the chi-square
02271      distribution given values for the others.
02272 
02273 
02274                               Arguments
02275 
02276 
02277      WHICH --> Integer indicating which of the next three argument
02278                values is to be calculated from the others.
02279                Legal range: 1..3
02280                iwhich = 1 : Calculate P and Q from X and DF
02281                iwhich = 2 : Calculate X from P,Q and DF
02282                iwhich = 3 : Calculate DF from P,Q and X
02283 
02284      P <--> The integral from 0 to X of the chi-square
02285             distribution.
02286             Input range: [0, 1].
02287 
02288      Q <--> 1-P.
02289             Input range: (0, 1].
02290             P + Q = 1.0.
02291 
02292      X <--> Upper limit of integration of the non-central
02293             chi-square distribution.
02294             Input range: [0, +infinity).
02295             Search range: [0,1E300]
02296 
02297      DF <--> Degrees of freedom of the
02298              chi-square distribution.
02299              Input range: (0, +infinity).
02300              Search range: [ 1E-300, 1E300]
02301 
02302      STATUS <-- 0 if calculation completed correctly
02303                -I if input parameter number I is out of range
02304                 1 if answer appears to be lower than lowest
02305                   search bound
02306                 2 if answer appears to be higher than greatest
02307                   search bound
02308                 3 if P + Q .ne. 1
02309                10 indicates error returned from cumgam.  See
02310                   references in cdfgam
02311 
02312      BOUND <-- Undefined if STATUS is 0
02313 
02314                Bound exceeded by parameter number I if STATUS
02315                is negative.
02316 
02317                Lower search bound if STATUS is 1.
02318 
02319                Upper search bound if STATUS is 2.
02320 
02321 
02322                               Method
02323 
02324 
02325      Formula    26.4.19   of Abramowitz  and     Stegun, Handbook  of
02326      Mathematical Functions   (1966) is used   to reduce the chisqure
02327      distribution to the incomplete distribution.
02328 
02329      Computation of other parameters involve a seach for a value that
02330      produces  the desired  value  of P.   The search relies  on  the
02331      monotinicity of P with the other parameter.
02332 
02333 **********************************************************************/
02334 {
02335 #define tol (1.0e-8)
02336 #define atol (1.0e-50)
02337 #define zero (1.0e-300)
02338 #define inf 1.0e300
02339 static int K1 = 1;
02340 static double K2 = 0.0e0;
02341 static double K4 = 0.5e0;
02342 static double K5 = 5.0e0;
02343 static double fx,cum,ccum,pq,porq;
02344 static unsigned long qhi,qleft,qporq;
02345 static double T3,T6,T7,T8,T9,T10,T11;
02346 /*
02347      ..
02348      .. Executable Statements ..
02349 */
02350 /*
02351      Check arguments
02352 */
02353     if(!(*which < 1 || *which > 3)) goto S30;
02354     if(!(*which < 1)) goto S10;
02355     *bound = 1.0e0;
02356     goto S20;
02357 S10:
02358     *bound = 3.0e0;
02359 S20:
02360     *status = -1;
02361     return;
02362 S30:
02363     if(*which == 1) goto S70;
02364 /*
02365      P
02366 */
02367     if(!(*p < 0.0e0 || *p > 1.0e0)) goto S60;
02368     if(!(*p < 0.0e0)) goto S40;
02369     *bound = 0.0e0;
02370     goto S50;
02371 S40:
02372     *bound = 1.0e0;
02373 S50:
02374     *status = -2;
02375     return;
02376 S70:
02377 S60:
02378     if(*which == 1) goto S110;
02379 /*
02380      Q
02381 */
02382     if(!(*q <= 0.0e0 || *q > 1.0e0)) goto S100;
02383     if(!(*q <= 0.0e0)) goto S80;
02384     *bound = 0.0e0;
02385     goto S90;
02386 S80:
02387     *bound = 1.0e0;
02388 S90:
02389     *status = -3;
02390     return;
02391 S110:
02392 S100:
02393     if(*which == 2) goto S130;
02394 /*
02395      X
02396 */
02397     if(!(*x < 0.0e0)) goto S120;
02398     *bound = 0.0e0;
02399     *status = -4;
02400     return;
02401 S130:
02402 S120:
02403     if(*which == 3) goto S150;
02404 /*
02405      DF
02406 */
02407     if(!(*df <= 0.0e0)) goto S140;
02408     *bound = 0.0e0;
02409     *status = -5;
02410     return;
02411 S150:
02412 S140:
02413     if(*which == 1) goto S190;
02414 /*
02415      P + Q
02416 */
02417     pq = *p+*q;
02418     if(!(fabs(pq-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S180;
02419     if(!(pq < 0.0e0)) goto S160;
02420     *bound = 0.0e0;
02421     goto S170;
02422 S160:
02423     *bound = 1.0e0;
02424 S170:
02425     *status = 3;
02426     return;
02427 S190:
02428 S180:
02429     if(*which == 1) goto S220;
02430 /*
02431      Select the minimum of P or Q
02432 */
02433     qporq = *p <= *q;
02434     if(!qporq) goto S200;
02435     porq = *p;
02436     goto S210;
02437 S200:
02438     porq = *q;
02439 S220:
02440 S210:
02441 /*
02442      Calculate ANSWERS
02443 */
02444     if(1 == *which) {
02445 /*
02446      Calculating P and Q
02447 */
02448         *status = 0;
02449         cumchi(x,df,p,q);
02450         if(porq > 1.5e0) {
02451             *status = 10;
02452             return;
02453         }
02454     }
02455     else if(2 == *which) {
02456 /*
02457      Calculating X
02458 */
02459         *x = 5.0e0;
02460         T3 = inf;
02461         T6 = atol;
02462         T7 = tol;
02463         dstinv(&K2,&T3,&K4,&K4,&K5,&T6,&T7);
02464         *status = 0;
02465         dinvr(status,x,&fx,&qleft,&qhi);
02466 S230:
02467         if(!(*status == 1)) goto S270;
02468         cumchi(x,df,&cum,&ccum);
02469         if(!qporq) goto S240;
02470         fx = cum-*p;
02471         goto S250;
02472 S240:
02473         fx = ccum-*q;
02474 S250:
02475         if(!(fx+porq > 1.5e0)) goto S260;
02476         *status = 10;
02477         return;
02478 S260:
02479         dinvr(status,x,&fx,&qleft,&qhi);
02480         goto S230;
02481 S270:
02482         if(!(*status == -1)) goto S300;
02483         if(!qleft) goto S280;
02484         *status = 1;
02485         *bound = 0.0e0;
02486         goto S290;
02487 S280:
02488         *status = 2;
02489         *bound = inf;
02490 S300:
02491 S290:
02492         ;
02493     }
02494     else if(3 == *which) {
02495 /*
02496      Calculating DF
02497 */
02498         *df = 5.0e0;
02499         T8 = zero;
02500         T9 = inf;
02501         T10 = atol;
02502         T11 = tol;
02503         dstinv(&T8,&T9,&K4,&K4,&K5,&T10,&T11);
02504         *status = 0;
02505         dinvr(status,df,&fx,&qleft,&qhi);
02506 S310:
02507         if(!(*status == 1)) goto S350;
02508         cumchi(x,df,&cum,&ccum);
02509         if(!qporq) goto S320;
02510         fx = cum-*p;
02511         goto S330;
02512 S320:
02513         fx = ccum-*q;
02514 S330:
02515         if(!(fx+porq > 1.5e0)) goto S340;
02516         *status = 10;
02517         return;
02518 S340:
02519         dinvr(status,df,&fx,&qleft,&qhi);
02520         goto S310;
02521 S350:
02522         if(!(*status == -1)) goto S380;
02523         if(!qleft) goto S360;
02524         *status = 1;
02525         *bound = zero;
02526         goto S370;
02527 S360:
02528         *status = 2;
02529         *bound = inf;
02530 S370:
02531         ;
02532     }
02533 S380:
02534     return;
02535 #undef tol
02536 #undef atol
02537 #undef zero
02538 #undef inf
02539 } /* END */
02540 
02541 /***=====================================================================***/
02542 static void cdfchn(int *which,double *p,double *q,double *x,double *df,
02543             double *pnonc,int *status,double *bound)
02544 /**********************************************************************
02545 
02546       void cdfchn(int *which,double *p,double *q,double *x,double *df,
02547             double *pnonc,int *status,double *bound)
02548 
02549                Cumulative Distribution Function
02550                Non-central Chi-Square
02551 
02552 
02553                               Function
02554 
02555 
02556      Calculates any one parameter of the non-central chi-square
02557      distribution given values for the others.
02558 
02559 
02560                               Arguments
02561 
02562 
02563      WHICH --> Integer indicating which of the next three argument
02564                values is to be calculated from the others.
02565                Input range: 1..4
02566                iwhich = 1 : Calculate P and Q from X and DF
02567                iwhich = 2 : Calculate X from P,DF and PNONC
02568                iwhich = 3 : Calculate DF from P,X and PNONC
02569                iwhich = 3 : Calculate PNONC from P,X and DF
02570 
02571      P <--> The integral from 0 to X of the non-central chi-square
02572             distribution.
02573             Input range: [0, 1-1E-16).
02574 
02575      Q <--> 1-P.
02576             Q is not used by this subroutine and is only included
02577             for similarity with other cdf* routines.
02578 
02579      X <--> Upper limit of integration of the non-central
02580             chi-square distribution.
02581             Input range: [0, +infinity).
02582             Search range: [0,1E300]
02583 
02584      DF <--> Degrees of freedom of the non-central
02585              chi-square distribution.
02586              Input range: (0, +infinity).
02587              Search range: [ 1E-300, 1E300]
02588 
02589      PNONC <--> Non-centrality parameter of the non-central
02590                 chi-square distribution.
02591                 Input range: [0, +infinity).
02592                 Search range: [0,1E4]
02593 
02594      STATUS <-- 0 if calculation completed correctly
02595                -I if input parameter number I is out of range
02596                 1 if answer appears to be lower than lowest
02597                   search bound
02598                 2 if answer appears to be higher than greatest
02599                   search bound
02600 
02601      BOUND <-- Undefined if STATUS is 0
02602 
02603                Bound exceeded by parameter number I if STATUS
02604                is negative.
02605 
02606                Lower search bound if STATUS is 1.
02607 
02608                Upper search bound if STATUS is 2.
02609 
02610 
02611                               Method
02612 
02613 
02614      Formula  26.4.25   of   Abramowitz   and   Stegun,  Handbook  of
02615      Mathematical  Functions (1966) is used to compute the cumulative
02616      distribution function.
02617 
02618      Computation of other parameters involve a seach for a value that
02619      produces  the desired  value  of P.   The search relies  on  the
02620      monotinicity of P with the other parameter.
02621 
02622 
02623                             WARNING
02624 
02625      The computation time  required for this  routine is proportional
02626      to the noncentrality  parameter  (PNONC).  Very large  values of
02627      this parameter can consume immense  computer resources.  This is
02628      why the search range is bounded by 10,000.
02629 
02630 **********************************************************************/
02631 {
02632 #define tent4 1.0e4
02633 #define tol (1.0e-8)
02634 #define atol (1.0e-50)
02635 #define zero (1.0e-300)
02636 #define one (1.0e0-1.0e-16)
02637 #define inf 1.0e300
02638 static double K1 = 0.0e0;
02639 static double K3 = 0.5e0;
02640 static double K4 = 5.0e0;
02641 static double fx,cum,ccum;
02642 static unsigned long qhi,qleft;
02643 static double T2,T5,T6,T7,T8,T9,T10,T11,T12,T13;
02644 /*
02645      ..
02646      .. Executable Statements ..
02647 */
02648 /*
02649      Check arguments
02650 */
02651     if(!(*which < 1 || *which > 4)) goto S30;
02652     if(!(*which < 1)) goto S10;
02653     *bound = 1.0e0;
02654     goto S20;
02655 S10:
02656     *bound = 4.0e0;
02657 S20:
02658     *status = -1;
02659     return;
02660 S30:
02661     if(*which == 1) goto S70;
02662 /*
02663      P
02664 */
02665     if(!(*p < 0.0e0 || *p > one)) goto S60;
02666     if(!(*p < 0.0e0)) goto S40;
02667     *bound = 0.0e0;
02668     goto S50;
02669 S40:
02670     *bound = one;
02671 S50:
02672     *status = -2;
02673     return;
02674 S70:
02675 S60:
02676     if(*which == 2) goto S90;
02677 /*
02678      X
02679 */
02680     if(!(*x < 0.0e0)) goto S80;
02681     *bound = 0.0e0;
02682     *status = -4;
02683     return;
02684 S90:
02685 S80:
02686     if(*which == 3) goto S110;
02687 /*
02688      DF
02689 */
02690     if(!(*df <= 0.0e0)) goto S100;
02691     *bound = 0.0e0;
02692     *status = -5;
02693     return;
02694 S110:
02695 S100:
02696     if(*which == 4) goto S130;
02697 /*
02698      PNONC
02699 */
02700     if(!(*pnonc < 0.0e0)) goto S120;
02701     *bound = 0.0e0;
02702     *status = -6;
02703     return;
02704 S130:
02705 S120:
02706 /*
02707      Calculate ANSWERS
02708 */
02709     if(1 == *which) {
02710 /*
02711      Calculating P and Q
02712 */
02713         cumchn(x,df,pnonc,p,q);
02714         *status = 0;
02715     }
02716     else if(2 == *which) {
02717 /*
02718      Calculating X
02719 */
02720         *x = 5.0e0;
02721         T2 = inf;
02722         T5 = atol;
02723         T6 = tol;
02724         dstinv(&K1,&T2,&K3,&K3,&K4,&T5,&T6);
02725         *status = 0;
02726         dinvr(status,x,&fx,&qleft,&qhi);
02727 S140:
02728         if(!(*status == 1)) goto S150;
02729         cumchn(x,df,pnonc,&cum,&ccum);
02730         fx = cum-*p;
02731         dinvr(status,x,&fx,&qleft,&qhi);
02732         goto S140;
02733 S150:
02734         if(!(*status == -1)) goto S180;
02735         if(!qleft) goto S160;
02736         *status = 1;
02737         *bound = 0.0e0;
02738         goto S170;
02739 S160:
02740         *status = 2;
02741         *bound = inf;
02742 S180:
02743 S170:
02744         ;
02745     }
02746     else if(3 == *which) {
02747 /*
02748      Calculating DF
02749 */
02750         *df = 5.0e0;
02751         T7 = zero;
02752         T8 = inf;
02753         T9 = atol;
02754         T10 = tol;
02755         dstinv(&T7,&T8,&K3,&K3,&K4,&T9,&T10);
02756         *status = 0;
02757         dinvr(status,df,&fx,&qleft,&qhi);
02758 S190:
02759         if(!(*status == 1)) goto S200;
02760         cumchn(x,df,pnonc,&cum,&ccum);
02761         fx = cum-*p;
02762         dinvr(status,df,&fx,&qleft,&qhi);
02763         goto S190;
02764 S200:
02765         if(!(*status == -1)) goto S230;
02766         if(!qleft) goto S210;
02767         *status = 1;
02768         *bound = zero;
02769         goto S220;
02770 S210:
02771         *status = 2;
02772         *bound = inf;
02773 S230:
02774 S220:
02775         ;
02776     }
02777     else if(4 == *which) {
02778 /*
02779      Calculating PNONC
02780 */
02781         *pnonc = 5.0e0;
02782         T11 = tent4;
02783         T12 = atol;
02784         T13 = tol;
02785         dstinv(&K1,&T11,&K3,&K3,&K4,&T12,&T13);
02786         *status = 0;
02787         dinvr(status,pnonc,&fx,&qleft,&qhi);
02788 S240:
02789         if(!(*status == 1)) goto S250;
02790         cumchn(x,df,pnonc,&cum,&ccum);
02791         fx = cum-*p;
02792         dinvr(status,pnonc,&fx,&qleft,&qhi);
02793         goto S240;
02794 S250:
02795         if(!(*status == -1)) goto S280;
02796         if(!qleft) goto S260;
02797         *status = 1;
02798         *bound = zero;
02799         goto S270;
02800 S260:
02801         *status = 2;
02802         *bound = tent4;
02803 S270:
02804         ;
02805     }
02806 S280:
02807     return;
02808 #undef tent4
02809 #undef tol
02810 #undef atol
02811 #undef zero
02812 #undef one
02813 #undef inf
02814 } /* END */
02815 
02816 /***=====================================================================***/
02817 static void cdff(int *which,double *p,double *q,double *f,double *dfn,
02818           double *dfd,int *status,double *bound)
02819 /**********************************************************************
02820 
02821       void cdff(int *which,double *p,double *q,double *f,double *dfn,
02822           double *dfd,int *status,double *bound)
02823 
02824                Cumulative Distribution Function
02825                F distribution
02826 
02827 
02828                               Function
02829 
02830 
02831      Calculates any one parameter of the F distribution
02832      given values for the others.
02833 
02834 
02835                               Arguments
02836 
02837 
02838      WHICH --> Integer indicating which of the next four argument
02839                values is to be calculated from the others.
02840                Legal range: 1..4
02841                iwhich = 1 : Calculate P and Q from F,DFN and DFD
02842                iwhich = 2 : Calculate F from P,Q,DFN and DFD
02843                iwhich = 3 : Calculate DFN from P,Q,F and DFD
02844                iwhich = 4 : Calculate DFD from P,Q,F and DFN
02845 
02846        P <--> The integral from 0 to F of the f-density.
02847               Input range: [0,1].
02848 
02849        Q <--> 1-P.
02850               Input range: (0, 1].
02851               P + Q = 1.0.
02852 
02853        F <--> Upper limit of integration of the f-density.
02854               Input range: [0, +infinity).
02855               Search range: [0,1E300]
02856 
02857      DFN < --> Degrees of freedom of the numerator sum of squares.
02858                Input range: (0, +infinity).
02859                Search range: [ 1E-300, 1E300]
02860 
02861      DFD < --> Degrees of freedom of the denominator sum of squares.
02862                Input range: (0, +infinity).
02863                Search range: [ 1E-300, 1E300]
02864 
02865      STATUS <-- 0 if calculation completed correctly
02866                -I if input parameter number I is out of range
02867                 1 if answer appears to be lower than lowest
02868                   search bound
02869                 2 if answer appears to be higher than greatest
02870                   search bound
02871                 3 if P + Q .ne. 1
02872 
02873      BOUND <-- Undefined if STATUS is 0
02874 
02875                Bound exceeded by parameter number I if STATUS
02876                is negative.
02877 
02878                Lower search bound if STATUS is 1.
02879 
02880                Upper search bound if STATUS is 2.
02881 
02882 
02883                               Method
02884 
02885 
02886      Formula   26.6.2   of   Abramowitz   and   Stegun,  Handbook  of
02887      Mathematical  Functions (1966) is used to reduce the computation
02888      of the  cumulative  distribution function for the  F  variate to
02889      that of an incomplete beta.
02890 
02891      Computation of other parameters involve a seach for a value that
02892      produces  the desired  value  of P.   The search relies  on  the
02893      monotinicity of P with the other parameter.
02894 
02895                               WARNING
02896 
02897      The value of the  cumulative  F distribution is  not necessarily
02898      monotone in  either degrees of freedom.  There  thus may  be two
02899      values  that  provide a given CDF  value.   This routine assumes
02900      monotonicity and will find an arbitrary one of the two values.
02901 
02902 **********************************************************************/
02903 {
02904 #define tol (1.0e-8)
02905 #define atol (1.0e-50)
02906 #define zero (1.0e-300)
02907 #define inf 1.0e300
02908 static int K1 = 1;
02909 static double K2 = 0.0e0;
02910 static double K4 = 0.5e0;
02911 static double K5 = 5.0e0;
02912 static double pq,fx,cum,ccum;
02913 static unsigned long qhi,qleft,qporq;
02914 static double T3,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15;
02915 /*
02916      ..
02917      .. Executable Statements ..
02918 */
02919 /*
02920      Check arguments
02921 */
02922     if(!(*which < 1 || *which > 4)) goto S30;
02923     if(!(*which < 1)) goto S10;
02924     *bound = 1.0e0;
02925     goto S20;
02926 S10:
02927     *bound = 4.0e0;
02928 S20:
02929     *status = -1;
02930     return;
02931 S30:
02932     if(*which == 1) goto S70;
02933 /*
02934      P
02935 */
02936     if(!(*p < 0.0e0 || *p > 1.0e0)) goto S60;
02937     if(!(*p < 0.0e0)) goto S40;
02938     *bound = 0.0e0;
02939     goto S50;
02940 S40:
02941     *bound = 1.0e0;
02942 S50:
02943     *status = -2;
02944     return;
02945 S70:
02946 S60:
02947     if(*which == 1) goto S110;
02948 /*
02949      Q
02950 */
02951     if(!(*q <= 0.0e0 || *q > 1.0e0)) goto S100;
02952     if(!(*q <= 0.0e0)) goto S80;
02953     *bound = 0.0e0;
02954     goto S90;
02955 S80:
02956     *bound = 1.0e0;
02957 S90:
02958     *status = -3;
02959     return;
02960 S110:
02961 S100:
02962     if(*which == 2) goto S130;
02963 /*
02964      F
02965 */
02966     if(!(*f < 0.0e0)) goto S120;
02967     *bound = 0.0e0;
02968     *status = -4;
02969     return;
02970 S130:
02971 S120:
02972     if(*which == 3) goto S150;
02973 /*
02974      DFN
02975 */
02976     if(!(*dfn <= 0.0e0)) goto S140;
02977     *bound = 0.0e0;
02978     *status = -5;
02979     return;
02980 S150:
02981 S140:
02982     if(*which == 4) goto S170;
02983 /*
02984      DFD
02985 */
02986     if(!(*dfd <= 0.0e0)) goto S160;
02987     *bound = 0.0e0;
02988     *status = -6;
02989     return;
02990 S170:
02991 S160:
02992     if(*which == 1) goto S210;
02993 /*
02994      P + Q
02995 */
02996     pq = *p+*q;
02997     if(!(fabs(pq-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S200;
02998     if(!(pq < 0.0e0)) goto S180;
02999     *bound = 0.0e0;
03000     goto S190;
03001 S180:
03002     *bound = 1.0e0;
03003 S190:
03004     *status = 3;
03005     return;
03006 S210:
03007 S200:
03008     if(!(*which == 1)) qporq = *p <= *q;
03009 /*
03010      Select the minimum of P or Q
03011      Calculate ANSWERS
03012 */
03013     if(1 == *which) {
03014 /*
03015      Calculating P
03016 */
03017         cumf(f,dfn,dfd,p,q);
03018         *status = 0;
03019     }
03020     else if(2 == *which) {
03021 /*
03022      Calculating F
03023 */
03024         *f = 5.0e0;
03025         T3 = inf;
03026         T6 = atol;
03027         T7 = tol;
03028         dstinv(&K2,&T3,&K4,&K4,&K5,&T6,&T7);
03029         *status = 0;
03030         dinvr(status,f,&fx,&qleft,&qhi);
03031 S220:
03032         if(!(*status == 1)) goto S250;
03033         cumf(f,dfn,dfd,&cum,&ccum);
03034         if(!qporq) goto S230;
03035         fx = cum-*p;
03036         goto S240;
03037 S230:
03038         fx = ccum-*q;
03039 S240:
03040         dinvr(status,f,&fx,&qleft,&qhi);
03041         goto S220;
03042 S250:
03043         if(!(*status == -1)) goto S280;
03044         if(!qleft) goto S260;
03045         *status = 1;
03046         *bound = 0.0e0;
03047         goto S270;
03048 S260:
03049         *status = 2;
03050         *bound = inf;
03051 S280:
03052 S270:
03053         ;
03054     }
03055     else if(3 == *which) {
03056 /*
03057      Calculating DFN
03058 */
03059         *dfn = 5.0e0;
03060         T8 = zero;
03061         T9 = inf;
03062         T10 = atol;
03063         T11 = tol;
03064         dstinv(&T8,&T9,&K4,&K4,&K5,&T10,&T11);
03065         *status = 0;
03066         dinvr(status,dfn,&fx,&qleft,&qhi);
03067 S290:
03068         if(!(*status == 1)) goto S320;
03069         cumf(f,dfn,dfd,&cum,&ccum);
03070         if(!qporq) goto S300;
03071         fx = cum-*p;
03072         goto S310;
03073 S300:
03074         fx = ccum-*q;
03075 S310:
03076         dinvr(status,dfn,&fx,&qleft,&qhi);
03077         goto S290;
03078 S320:
03079         if(!(*status == -1)) goto S350;
03080         if(!qleft) goto S330;
03081         *status = 1;
03082         *bound = zero;
03083         goto S340;
03084 S330:
03085         *status = 2;
03086         *bound = inf;
03087 S350:
03088 S340:
03089         ;
03090     }
03091     else if(4 == *which) {
03092 /*
03093      Calculating DFD
03094 */
03095         *dfd = 5.0e0;
03096         T12 = zero;
03097         T13 = inf;
03098         T14 = atol;
03099         T15 = tol;
03100         dstinv(&T12,&T13,&K4,&K4,&K5,&T14,&T15);
03101         *status = 0;
03102         dinvr(status,dfd,&fx,&qleft,&qhi);
03103 S360:
03104         if(!(*status == 1)) goto S390;
03105         cumf(f,dfn,dfd,&cum,&ccum);
03106         if(!qporq) goto S370;
03107         fx = cum-*p;
03108         goto S380;
03109 S370:
03110         fx = ccum-*q;
03111 S380:
03112         dinvr(status,dfd,&fx,&qleft,&qhi);
03113         goto S360;
03114 S390:
03115         if(!(*status == -1)) goto S420;
03116         if(!qleft) goto S400;
03117         *status = 1;
03118         *bound = zero;
03119         goto S410;
03120 S400:
03121         *status = 2;
03122         *bound = inf;
03123 S410:
03124         ;
03125     }
03126 S420:
03127     return;
03128 #undef tol
03129 #undef atol
03130 #undef zero
03131 #undef inf
03132 } /* END */
03133 
03134 /***=====================================================================***/
03135 static void cdffnc(int *which,double *p,double *q,double *f,double *dfn,
03136             double *dfd,double *phonc,int *status,double *bound)
03137 /**********************************************************************
03138 
03139       void cdffnc(int *which,double *p,double *q,double *f,double *dfn,
03140             double *dfd,double *phonc,int *status,double *bound)
03141 
03142                Cumulative Distribution Function
03143                Non-central F distribution
03144 
03145 
03146                               Function
03147 
03148 
03149      Calculates any one parameter of the Non-central F
03150      distribution given values for the others.
03151 
03152 
03153                               Arguments
03154 
03155 
03156      WHICH --> Integer indicating which of the next five argument
03157                values is to be calculated from the others.
03158                Legal range: 1..5
03159                iwhich = 1 : Calculate P and Q from F,DFN,DFD and PNONC
03160                iwhich = 2 : Calculate F from P,Q,DFN,DFD and PNONC
03161                iwhich = 3 : Calculate DFN from P,Q,F,DFD and PNONC
03162                iwhich = 4 : Calculate DFD from P,Q,F,DFN and PNONC
03163                iwhich = 5 : Calculate PNONC from P,Q,F,DFN and DFD
03164 
03165        P <--> The integral from 0 to F of the non-central f-density.
03166               Input range: [0,1-1E-16).
03167 
03168        Q <--> 1-P.
03169               Q is not used by this subroutine and is only included
03170               for similarity with other cdf* routines.
03171 
03172        F <--> Upper limit of integration of the non-central f-density.
03173               Input range: [0, +infinity).
03174               Search range: [0,1E300]
03175 
03176      DFN < --> Degrees of freedom of the numerator sum of squares.
03177                Input range: (0, +infinity).
03178                Search range: [ 1E-300, 1E300]
03179 
03180      DFD < --> Degrees of freedom of the denominator sum of squares.
03181                Must be in range: (0, +infinity).
03182                Input range: (0, +infinity).
03183                Search range: [ 1E-300, 1E300]
03184 
03185      PNONC <-> The non-centrality parameter
03186                Input range: [0,infinity)
03187                Search range: [0,1E4]
03188 
03189      STATUS <-- 0 if calculation completed correctly
03190                -I if input parameter number I is out of range
03191                 1 if answer appears to be lower than lowest
03192                   search bound
03193                 2 if answer appears to be higher than greatest
03194                   search bound
03195                 3 if P + Q .ne. 1
03196 
03197      BOUND <-- Undefined if STATUS is 0
03198 
03199                Bound exceeded by parameter number I if STATUS
03200                is negative.
03201 
03202                Lower search bound if STATUS is 1.
03203 
03204                Upper search bound if STATUS is 2.
03205 
03206 
03207                               Method
03208 
03209 
03210      Formula  26.6.20   of   Abramowitz   and   Stegun,  Handbook  of
03211      Mathematical  Functions (1966) is used to compute the cumulative
03212      distribution function.
03213 
03214      Computation of other parameters involve a seach for a value that
03215      produces  the desired  value  of P.   The search relies  on  the
03216      monotinicity of P with the other parameter.
03217 
03218                             WARNING
03219 
03220      The computation time  required for this  routine is proportional
03221      to the noncentrality  parameter  (PNONC).  Very large  values of
03222      this parameter can consume immense  computer resources.  This is
03223      why the search range is bounded by 10,000.
03224 
03225                               WARNING
03226 
03227      The  value  of the  cumulative  noncentral F distribution is not
03228      necessarily monotone in either degrees  of freedom.  There  thus
03229      may be two values that provide a given  CDF value.  This routine
03230      assumes monotonicity  and will find  an arbitrary one of the two
03231      values.
03232 
03233 **********************************************************************/
03234 {
03235 #define tent4 1.0e4
03236 #define tol (1.0e-8)
03237 #define atol (1.0e-50)
03238 #define zero (1.0e-300)
03239 #define one (1.0e0-1.0e-16)
03240 #define inf 1.0e300
03241 static double K1 = 0.0e0;
03242 static double K3 = 0.5e0;
03243 static double K4 = 5.0e0;
03244 static double fx,cum,ccum;
03245 static unsigned long qhi,qleft;
03246 static double T2,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17;
03247 /*
03248      ..
03249      .. Executable Statements ..
03250 */
03251 /*
03252      Check arguments
03253 */
03254     if(!(*which < 1 || *which > 5)) goto S30;
03255     if(!(*which < 1)) goto S10;
03256     *bound = 1.0e0;
03257     goto S20;
03258 S10:
03259     *bound = 5.0e0;
03260 S20:
03261     *status = -1;
03262     return;
03263 S30:
03264     if(*which == 1) goto S70;
03265 /*
03266      P
03267 */
03268     if(!(*p < 0.0e0 || *p > one)) goto S60;
03269     if(!(*p < 0.0e0)) goto S40;
03270     *bound = 0.0e0;
03271     goto S50;
03272 S40:
03273     *bound = one;
03274 S50:
03275     *status = -2;
03276     return;
03277 S70:
03278 S60:
03279     if(*which == 2) goto S90;
03280 /*
03281      F
03282 */
03283     if(!(*f < 0.0e0)) goto S80;
03284     *bound = 0.0e0;
03285     *status = -4;
03286     return;
03287 S90:
03288 S80:
03289     if(*which == 3) goto S110;
03290 /*
03291      DFN
03292 */
03293     if(!(*dfn <= 0.0e0)) goto S100;
03294     *bound = 0.0e0;
03295     *status = -5;
03296     return;
03297 S110:
03298 S100:
03299     if(*which == 4) goto S130;
03300 /*
03301      DFD
03302 */
03303     if(!(*dfd <= 0.0e0)) goto S120;
03304     *bound = 0.0e0;
03305     *status = -6;
03306     return;
03307 S130:
03308 S120:
03309     if(*which == 5) goto S150;
03310 /*
03311      PHONC
03312 */
03313     if(!(*phonc < 0.0e0)) goto S140;
03314     *bound = 0.0e0;
03315     *status = -7;
03316     return;
03317 S150:
03318 S140:
03319 /*
03320      Calculate ANSWERS
03321 */
03322     if(1 == *which) {
03323 /*
03324      Calculating P
03325 */
03326         cumfnc(f,dfn,dfd,phonc,p,q);
03327         *status = 0;
03328     }
03329     else if(2 == *which) {
03330 /*
03331      Calculating F
03332 */
03333         *f = 5.0e0;
03334         T2 = inf;
03335         T5 = atol;
03336         T6 = tol;
03337         dstinv(&K1,&T2,&K3,&K3,&K4,&T5,&T6);
03338         *status = 0;
03339         dinvr(status,f,&fx,&qleft,&qhi);
03340 S160:
03341         if(!(*status == 1)) goto S170;
03342         cumfnc(f,dfn,dfd,phonc,&cum,&ccum);
03343         fx = cum-*p;
03344         dinvr(status,f,&fx,&qleft,&qhi);
03345         goto S160;
03346 S170:
03347         if(!(*status == -1)) goto S200;
03348         if(!qleft) goto S180;
03349         *status = 1;
03350         *bound = 0.0e0;
03351         goto S190;
03352 S180:
03353         *status = 2;
03354         *bound = inf;
03355 S200:
03356 S190:
03357         ;
03358     }
03359     else if(3 == *which) {
03360 /*
03361      Calculating DFN
03362 */
03363         *dfn = 5.0e0;
03364         T7 = zero;
03365         T8 = inf;
03366         T9 = atol;
03367         T10 = tol;
03368         dstinv(&T7,&T8,&K3,&K3,&K4,&T9,&T10);
03369         *status = 0;
03370         dinvr(status,dfn,&fx,&qleft,&qhi);
03371 S210:
03372         if(!(*status == 1)) goto S220;
03373         cumfnc(f,dfn,dfd,phonc,&cum,&ccum);
03374         fx = cum-*p;
03375         dinvr(status,dfn,&fx,&qleft,&qhi);
03376         goto S210;
03377 S220:
03378         if(!(*status == -1)) goto S250;
03379         if(!qleft) goto S230;
03380         *status = 1;
03381         *bound = zero;
03382         goto S240;
03383 S230:
03384         *status = 2;
03385         *bound = inf;
03386 S250:
03387 S240:
03388         ;
03389     }
03390     else if(4 == *which) {
03391 /*
03392      Calculating DFD
03393 */
03394         *dfd = 5.0e0;
03395         T11 = zero;
03396         T12 = inf;
03397         T13 = atol;
03398         T14 = tol;
03399         dstinv(&T11,&T12,&K3,&K3,&K4,&T13,&T14);
03400         *status = 0;
03401         dinvr(status,dfd,&fx,&qleft,&qhi);
03402 S260:
03403         if(!(*status == 1)) goto S270;
03404         cumfnc(f,dfn,dfd,phonc,&cum,&ccum);
03405         fx = cum-*p;
03406         dinvr(status,dfd,&fx,&qleft,&qhi);
03407         goto S260;
03408 S270:
03409         if(!(*status == -1)) goto S300;
03410         if(!qleft) goto S280;
03411         *status = 1;
03412         *bound = zero;
03413         goto S290;
03414 S280:
03415         *status = 2;
03416         *bound = inf;
03417 S300:
03418 S290:
03419         ;
03420     }
03421     else if(5 == *which) {
03422 /*
03423      Calculating PHONC
03424 */
03425         *phonc = 5.0e0;
03426         T15 = tent4;
03427         T16 = atol;
03428         T17 = tol;
03429         dstinv(&K1,&T15,&K3,&K3,&K4,&T16,&T17);
03430         *status = 0;
03431         dinvr(status,phonc,&fx,&qleft,&qhi);
03432 S310:
03433         if(!(*status == 1)) goto S320;
03434         cumfnc(f,dfn,dfd,phonc,&cum,&ccum);
03435         fx = cum-*p;
03436         dinvr(status,phonc,&fx,&qleft,&qhi);
03437         goto S310;
03438 S320:
03439         if(!(*status == -1)) goto S350;
03440         if(!qleft) goto S330;
03441         *status = 1;
03442         *bound = 0.0e0;
03443         goto S340;
03444 S330:
03445         *status = 2;
03446         *bound = tent4;
03447 S340:
03448         ;
03449     }
03450 S350:
03451     return;
03452 #undef tent4
03453 #undef tol
03454 #undef atol
03455 #undef zero
03456 #undef one
03457 #undef inf
03458 } /* END */
03459 
03460 /***=====================================================================***/
03461 static void cdfgam(int *which,double *p,double *q,double *x,double *shape,
03462             double *scale,int *status,double *bound)
03463 /**********************************************************************
03464 
03465       void cdfgam(int *which,double *p,double *q,double *x,double *shape,
03466             double *scale,int *status,double *bound)
03467 
03468                Cumulative Distribution Function
03469                          GAMma Distribution
03470 
03471 
03472                               Function
03473 
03474 
03475      Calculates any one parameter of the gamma
03476      distribution given values for the others.
03477 
03478 
03479                               Arguments
03480 
03481 
03482      WHICH --> Integer indicating which of the next four argument
03483                values is to be calculated from the others.
03484                Legal range: 1..4
03485                iwhich = 1 : Calculate P and Q from X,SHAPE and SCALE
03486                iwhich = 2 : Calculate X from P,Q,SHAPE and SCALE
03487                iwhich = 3 : Calculate SHAPE from P,Q,X and SCALE
03488                iwhich = 4 : Calculate SCALE from P,Q,X and SHAPE
03489 
03490      P <--> The integral from 0 to X of the gamma density.
03491             Input range: [0,1].
03492 
03493      Q <--> 1-P.
03494             Input range: (0, 1].
03495             P + Q = 1.0.
03496 
03497      X <--> The upper limit of integration of the gamma density.
03498             Input range: [0, +infinity).
03499             Search range: [0,1E300]
03500 
03501      SHAPE <--> The shape parameter of the gamma density.
03502                 Input range: (0, +infinity).
03503                 Search range: [1E-300,1E300]
03504 
03505      SCALE <--> The scale parameter of the gamma density.
03506                 Input range: (0, +infinity).
03507                 Search range: (1E-300,1E300]
03508 
03509      STATUS <-- 0 if calculation completed correctly
03510                -I if input parameter number I is out of range
03511                 1 if answer appears to be lower than lowest
03512                   search bound
03513                 2 if answer appears to be higher than greatest
03514                   search bound
03515                 3 if P + Q .ne. 1
03516                 10 if the gamma or inverse gamma routine cannot
03517                    compute the answer.  Usually happens only for
03518                    X and SHAPE very large (gt 1E10 or more)
03519 
03520      BOUND <-- Undefined if STATUS is 0
03521 
03522                Bound exceeded by parameter number I if STATUS
03523                is negative.
03524 
03525                Lower search bound if STATUS is 1.
03526 
03527                Upper search bound if STATUS is 2.
03528 
03529 
03530                               Method
03531 
03532 
03533      Cumulative distribution function (P) is calculated directly by
03534      the code associated with:
03535 
03536      DiDinato, A. R. and Morris, A. H. Computation of the  incomplete
03537      gamma function  ratios  and their  inverse.   ACM  Trans.  Math.
03538      Softw. 12 (1986), 377-393.
03539 
03540      Computation of other parameters involve a seach for a value that
03541      produces  the desired  value  of P.   The search relies  on  the
03542      monotinicity of P with the other parameter.
03543 
03544 
03545                               Note
03546 
03547 
03548 
03549      The gamma density is proportional to
03550        T**(SHAPE - 1) * EXP(- SCALE * T)
03551 
03552 **********************************************************************/
03553 {
03554 #define tol (1.0e-8)
03555 #define atol (1.0e-50)
03556 #define zero (1.0e-300)
03557 #define inf 1.0e300
03558 static int K1 = 1;
03559 static double K5 = 0.5e0;
03560 static double K6 = 5.0e0;
03561 static double xx,fx,xscale,cum,ccum,pq,porq;
03562 static int ierr;
03563 static unsigned long qhi,qleft,qporq;
03564 static double T2,T3,T4,T7,T8,T9;
03565 /*
03566      ..
03567      .. Executable Statements ..
03568 */
03569 /*
03570      Check arguments
03571 */
03572     if(!(*which < 1 || *which > 4)) goto S30;
03573     if(!(*which < 1)) goto S10;
03574     *bound = 1.0e0;
03575     goto S20;
03576 S10:
03577     *bound = 4.0e0;
03578 S20:
03579     *status = -1;
03580     return;
03581 S30:
03582     if(*which == 1) goto S70;
03583 /*
03584      P
03585 */
03586     if(!(*p < 0.0e0 || *p > 1.0e0)) goto S60;
03587     if(!(*p < 0.0e0)) goto S40;
03588     *bound = 0.0e0;
03589     goto S50;
03590 S40:
03591     *bound = 1.0e0;
03592 S50:
03593     *status = -2;
03594     return;
03595 S70:
03596 S60:
03597     if(*which == 1) goto S110;
03598 /*
03599      Q
03600 */
03601     if(!(*q <= 0.0e0 || *q > 1.0e0)) goto S100;
03602     if(!(*q <= 0.0e0)) goto S80;
03603     *bound = 0.0e0;
03604     goto S90;
03605 S80:
03606     *bound = 1.0e0;
03607 S90:
03608     *status = -3;
03609     return;
03610 S110:
03611 S100:
03612     if(*which == 2) goto S130;
03613 /*
03614      X
03615 */
03616     if(!(*x < 0.0e0)) goto S120;
03617     *bound = 0.0e0;
03618     *status = -4;
03619     return;
03620 S130:
03621 S120:
03622     if(*which == 3) goto S150;
03623 /*
03624      SHAPE
03625 */
03626     if(!(*shape <= 0.0e0)) goto S140;
03627     *bound = 0.0e0;
03628     *status = -5;
03629     return;
03630 S150:
03631 S140:
03632     if(*which == 4) goto S170;
03633 /*
03634      SCALE
03635 */
03636     if(!(*scale <= 0.0e0)) goto S160;
03637     *bound = 0.0e0;
03638     *status = -6;
03639     return;
03640 S170:
03641 S160:
03642     if(*which == 1) goto S210;
03643 /*
03644      P + Q
03645 */
03646     pq = *p+*q;
03647     if(!(fabs(pq-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S200;
03648     if(!(pq < 0.0e0)) goto S180;
03649     *bound = 0.0e0;
03650     goto S190;
03651 S180:
03652     *bound = 1.0e0;
03653 S190:
03654     *status = 3;
03655     return;
03656 S210:
03657 S200:
03658     if(*which == 1) goto S240;
03659 /*
03660      Select the minimum of P or Q
03661 */
03662     qporq = *p <= *q;
03663     if(!qporq) goto S220;
03664     porq = *p;
03665     goto S230;
03666 S220:
03667     porq = *q;
03668 S240:
03669 S230:
03670 /*
03671      Calculate ANSWERS
03672 */
03673     if(1 == *which) {
03674 /*
03675      Calculating P
03676 */
03677         *status = 0;
03678         xscale = *x**scale;
03679         cumgam(&xscale,shape,p,q);
03680         if(porq > 1.5e0) *status = 10;
03681     }
03682     else if(2 == *which) {
03683 /*
03684      Computing X
03685 */
03686         T2 = -1.0e0;
03687         gaminv(shape,&xx,&T2,p,q,&ierr);
03688         if(ierr < 0.0e0) {
03689             *status = 10;
03690             return;
03691         }
03692         else  {
03693             *x = xx/ *scale;
03694             *status = 0;
03695         }
03696     }
03697     else if(3 == *which) {
03698 /*
03699      Computing SHAPE
03700 */
03701         *shape = 5.0e0;
03702         xscale = *x**scale;
03703         T3 = zero;
03704         T4 = inf;
03705         T7 = atol;
03706         T8 = tol;
03707         dstinv(&T3,&T4,&K5,&K5,&K6,&T7,&T8);
03708         *status = 0;
03709         dinvr(status,shape,&fx,&qleft,&qhi);
03710 S250:
03711         if(!(*status == 1)) goto S290;
03712         cumgam(&xscale,shape,&cum,&ccum);
03713         if(!qporq) goto S260;
03714         fx = cum-*p;
03715         goto S270;
03716 S260:
03717         fx = ccum-*q;
03718 S270:
03719         if(!(qporq && cum > 1.5e0 || !qporq && ccum > 1.5e0)) goto S280;
03720         *status = 10;
03721         return;
03722 S280:
03723         dinvr(status,shape,&fx,&qleft,&qhi);
03724         goto S250;
03725 S290:
03726         if(!(*status == -1)) goto S320;
03727         if(!qleft) goto S300;
03728         *status = 1;
03729         *bound = zero;
03730         goto S310;
03731 S300:
03732         *status = 2;
03733         *bound = inf;
03734 S320:
03735 S310:
03736         ;
03737     }
03738     else if(4 == *which) {
03739 /*
03740      Computing SCALE
03741 */
03742         T9 = -1.0e0;
03743         gaminv(shape,&xx,&T9,p,q,&ierr);
03744         if(ierr < 0.0e0) {
03745             *status = 10;
03746             return;
03747         }
03748         else  {
03749             *scale = xx/ *x;
03750             *status = 0;
03751         }
03752     }
03753     return;
03754 #undef tol
03755 #undef atol
03756 #undef zero
03757 #undef inf
03758 } /* END */
03759 
03760 /***=====================================================================***/
03761 static void cdfnbn(int *which,double *p,double *q,double *s,double *xn,
03762             double *pr,double *ompr,int *status,double *bound)
03763 /**********************************************************************
03764 
03765       void cdfnbn(int *which,double *p,double *q,double *s,double *xn,
03766             double *pr,double *ompr,int *status,double *bound)
03767 
03768                Cumulative Distribution Function
03769                Negative BiNomial distribution
03770 
03771 
03772                               Function
03773 
03774 
03775      Calculates any one parameter of the negative binomial
03776      distribution given values for the others.
03777 
03778      The  cumulative  negative   binomial  distribution  returns  the
03779      probability that there  will be  F or fewer failures before  the
03780      XNth success in binomial trials each of which has probability of
03781      success PR.
03782 
03783      The individual term of the negative binomial is the probability of
03784      S failures before XN successes and is
03785           Choose( S, XN+S-1 ) * PR^(XN) * (1-PR)^S
03786 
03787 
03788                               Arguments
03789 
03790 
03791      WHICH --> Integer indicating which of the next four argument
03792                values is to be calculated from the others.
03793                Legal range: 1..4
03794                iwhich = 1 : Calculate P and Q from S,XN,PR and OMPR
03795                iwhich = 2 : Calculate S from P,Q,XN,PR and OMPR
03796                iwhich = 3 : Calculate XN from P,Q,S,PR and OMPR
03797                iwhich = 4 : Calculate PR and OMPR from P,Q,S and XN
03798 
03799      P <--> The cumulation from 0 to S of the  negative
03800             binomial distribution.
03801             Input range: [0,1].
03802 
03803      Q <--> 1-P.
03804             Input range: (0, 1].
03805             P + Q = 1.0.
03806 
03807      S <--> The upper limit of cumulation of the binomial distribution.
03808             There are F or fewer failures before the XNth success.
03809             Input range: [0, +infinity).
03810             Search range: [0, 1E300]
03811 
03812      XN  <--> The number of successes.
03813               Input range: [0, +infinity).
03814               Search range: [0, 1E300]
03815 
03816      PR  <--> The probability of success in each binomial trial.
03817               Input range: [0,1].
03818               Search range: [0,1].
03819 
03820      OMPR  <--> 1-PR
03821               Input range: [0,1].
03822               Search range: [0,1]
03823               PR + OMPR = 1.0
03824 
03825      STATUS <-- 0 if calculation completed correctly
03826                -I if input parameter number I is out of range
03827                 1 if answer appears to be lower than lowest
03828                   search bound
03829                 2 if answer appears to be higher than greatest
03830                   search bound
03831                 3 if P + Q .ne. 1
03832                 4 if PR + OMPR .ne. 1
03833 
03834      BOUND <-- Undefined if STATUS is 0
03835 
03836                Bound exceeded by parameter number I if STATUS
03837                is negative.
03838 
03839                Lower search bound if STATUS is 1.
03840 
03841                Upper search bound if STATUS is 2.
03842 
03843 
03844                               Method
03845 
03846 
03847      Formula   26.5.26   of   Abramowitz  and  Stegun,  Handbook   of
03848      Mathematical Functions (1966) is used  to  reduce calculation of
03849      the cumulative distribution  function to that of  an  incomplete
03850      beta.
03851 
03852      Computation of other parameters involve a seach for a value that
03853      produces  the desired  value  of P.   The search relies  on  the
03854      monotinicity of P with the other parameter.
03855 
03856 **********************************************************************/
03857 {
03858 #define tol (1.0e-8)
03859 #define atol (1.0e-50)
03860 #define inf 1.0e300
03861 #define one 1.0e0
03862 static int K1 = 1;
03863 static double K2 = 0.0e0;
03864 static double K4 = 0.5e0;
03865 static double K5 = 5.0e0;
03866 static double K11 = 1.0e0;
03867 static double fx,xhi,xlo,pq,prompr,cum,ccum;
03868 static unsigned long qhi,qleft,qporq;
03869 static double T3,T6,T7,T8,T9,T10,T12,T13;
03870 /*
03871      ..
03872      .. Executable Statements ..
03873 */
03874 /*
03875      Check arguments
03876 */
03877     if(!(*which < 1 || *which > 4)) goto S30;
03878     if(!(*which < 1)) goto S10;
03879     *bound = 1.0e0;
03880     goto S20;
03881 S10:
03882     *bound = 4.0e0;
03883 S20:
03884     *status = -1;
03885     return;
03886 S30:
03887     if(*which == 1) goto S70;
03888 /*
03889      P
03890 */
03891     if(!(*p < 0.0e0 || *p > 1.0e0)) goto S60;
03892     if(!(*p < 0.0e0)) goto S40;
03893     *bound = 0.0e0;
03894     goto S50;
03895 S40:
03896     *bound = 1.0e0;
03897 S50:
03898     *status = -2;
03899     return;
03900 S70:
03901 S60:
03902     if(*which == 1) goto S110;
03903 /*
03904      Q
03905 */
03906     if(!(*q <= 0.0e0 || *q > 1.0e0)) goto S100;
03907     if(!(*q <= 0.0e0)) goto S80;
03908     *bound = 0.0e0;
03909     goto S90;
03910 S80:
03911     *bound = 1.0e0;
03912 S90:
03913     *status = -3;
03914     return;
03915 S110:
03916 S100:
03917     if(*which == 2) goto S130;
03918 /*
03919      S
03920 */
03921     if(!(*s < 0.0e0)) goto S120;
03922     *bound = 0.0e0;
03923     *status = -4;
03924     return;
03925 S130:
03926 S120:
03927     if(*which == 3) goto S150;
03928 /*
03929      XN
03930 */
03931     if(!(*xn < 0.0e0)) goto S140;
03932     *bound = 0.0e0;
03933     *status = -5;
03934     return;
03935 S150:
03936 S140:
03937     if(*which == 4) goto S190;
03938 /*
03939      PR
03940 */
03941     if(!(*pr < 0.0e0 || *pr > 1.0e0)) goto S180;
03942     if(!(*pr < 0.0e0)) goto S160;
03943     *bound = 0.0e0;
03944     goto S170;
03945 S160:
03946     *bound = 1.0e0;
03947 S170:
03948     *status = -6;
03949     return;
03950 S190:
03951 S180:
03952     if(*which == 4) goto S230;
03953 /*
03954      OMPR
03955 */
03956     if(!(*ompr < 0.0e0 || *ompr > 1.0e0)) goto S220;
03957     if(!(*ompr < 0.0e0)) goto S200;
03958     *bound = 0.0e0;
03959     goto S210;
03960 S200:
03961     *bound = 1.0e0;
03962 S210:
03963     *status = -7;
03964     return;
03965 S230:
03966 S220:
03967     if(*which == 1) goto S270;
03968 /*
03969      P + Q
03970 */
03971     pq = *p+*q;
03972     if(!(fabs(pq-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S260;
03973     if(!(pq < 0.0e0)) goto S240;
03974     *bound = 0.0e0;
03975     goto S250;
03976 S240:
03977     *bound = 1.0e0;
03978 S250:
03979     *status = 3;
03980     return;
03981 S270:
03982 S260:
03983     if(*which == 4) goto S310;
03984 /*
03985      PR + OMPR
03986 */
03987     prompr = *pr+*ompr;
03988     if(!(fabs(prompr-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S300;
03989     if(!(prompr < 0.0e0)) goto S280;
03990     *bound = 0.0e0;
03991     goto S290;
03992 S280:
03993     *bound = 1.0e0;
03994 S290:
03995     *status = 4;
03996     return;
03997 S310:
03998 S300:
03999     if(!(*which == 1)) qporq = *p <= *q;
04000 /*
04001      Select the minimum of P or Q
04002      Calculate ANSWERS
04003 */
04004     if(1 == *which) {
04005 /*
04006      Calculating P
04007 */
04008         cumnbn(s,xn,pr,ompr,p,q);
04009         *status = 0;
04010     }
04011     else if(2 == *which) {
04012 /*
04013      Calculating S
04014 */
04015         *s = 5.0e0;
04016         T3 = inf;
04017         T6 = atol;
04018         T7 = tol;
04019         dstinv(&K2,&T3,&K4,&K4,&K5,&T6,&T7);
04020         *status = 0;
04021         dinvr(status,s,&fx,&qleft,&qhi);
04022 S320:
04023         if(!(*status == 1)) goto S350;
04024         cumnbn(s,xn,pr,ompr,&cum,&ccum);
04025         if(!qporq) goto S330;
04026         fx = cum-*p;
04027         goto S340;
04028 S330:
04029         fx = ccum-*q;
04030 S340:
04031         dinvr(status,s,&fx,&qleft,&qhi);
04032         goto S320;
04033 S350:
04034         if(!(*status == -1)) goto S380;
04035         if(!qleft) goto S360;
04036         *status = 1;
04037         *bound = 0.0e0;
04038         goto S370;
04039 S360:
04040         *status = 2;
04041         *bound = inf;
04042 S380:
04043 S370:
04044         ;
04045     }
04046     else if(3 == *which) {
04047 /*
04048      Calculating XN
04049 */
04050         *xn = 5.0e0;
04051         T8 = inf;
04052         T9 = atol;
04053         T10 = tol;
04054         dstinv(&K2,&T8,&K4,&K4,&K5,&T9,&T10);
04055         *status = 0;
04056         dinvr(status,xn,&fx,&qleft,&qhi);
04057 S390:
04058         if(!(*status == 1)) goto S420;
04059         cumnbn(s,xn,pr,ompr,&cum,&ccum);
04060         if(!qporq) goto S400;
04061         fx = cum-*p;
04062         goto S410;
04063 S400:
04064         fx = ccum-*q;
04065 S410:
04066         dinvr(status,xn,&fx,&qleft,&qhi);
04067         goto S390;
04068 S420:
04069         if(!(*status == -1)) goto S450;
04070         if(!qleft) goto S430;
04071         *status = 1;
04072         *bound = 0.0e0;
04073         goto S440;
04074 S430:
04075         *status = 2;
04076         *bound = inf;
04077 S450:
04078 S440:
04079         ;
04080     }
04081     else if(4 == *which) {
04082 /*
04083      Calculating PR and OMPR
04084 */
04085         T12 = atol;
04086         T13 = tol;
04087         dstzr(&K2,&K11,&T12,&T13);
04088         if(!qporq) goto S480;
04089         *status = 0;
04090         dzror(status,pr,&fx,&xlo,&xhi,&qleft,&qhi);
04091         *ompr = one-*pr;
04092 S460:
04093         if(!(*status == 1)) goto S470;
04094         cumnbn(s,xn,pr,ompr,&cum,&ccum);
04095         fx = cum-*p;
04096         dzror(status,pr,&fx,&xlo,&xhi,&qleft,&qhi);
04097         *ompr = one-*pr;
04098         goto S460;
04099 S470:
04100         goto S510;
04101 S480:
04102         *status = 0;
04103         dzror(status,ompr,&fx,&xlo,&xhi,&qleft,&qhi);
04104         *pr = one-*ompr;
04105 S490:
04106         if(!(*status == 1)) goto S500;
04107         cumnbn(s,xn,pr,ompr,&cum,&ccum);
04108         fx = ccum-*q;
04109         dzror(status,ompr,&fx,&xlo,&xhi,&qleft,&qhi);
04110         *pr = one-*ompr;
04111         goto S490;
04112 S510:
04113 S500:
04114         if(!(*status == -1)) goto S540;
04115         if(!qleft) goto S520;
04116         *status = 1;
04117         *bound = 0.0e0;
04118         goto S530;
04119 S520:
04120         *status = 2;
04121         *bound = 1.0e0;
04122 S530:
04123         ;
04124     }
04125 S540:
04126     return;
04127 #undef tol
04128 #undef atol
04129 #undef inf
04130 #undef one
04131 } /* END */
04132 
04133 /***=====================================================================***/
04134 static void cdfnor(int *which,double *p,double *q,double *x,double *mean,
04135             double *sd,int *status,double *bound)
04136 /**********************************************************************
04137 
04138       void cdfnor(int *which,double *p,double *q,double *x,double *mean,
04139             double *sd,int *status,double *bound)
04140 
04141                Cumulative Distribution Function
04142                NORmal distribution
04143 
04144 
04145                               Function
04146 
04147 
04148      Calculates any one parameter of the normal
04149      distribution given values for the others.
04150 
04151 
04152                               Arguments
04153 
04154 
04155      WHICH  --> Integer indicating  which of the  next  parameter
04156      values is to be calculated using values  of the others.
04157      Legal range: 1..4
04158                iwhich = 1 : Calculate P and Q from X,MEAN and SD
04159                iwhich = 2 : Calculate X from P,Q,MEAN and SD
04160                iwhich = 3 : Calculate MEAN from P,Q,X and SD
04161                iwhich = 4 : Calculate SD from P,Q,X and MEAN
04162 
04163      P <--> The integral from -infinity to X of the normal density.
04164             Input range: (0,1].
04165 
04166      Q <--> 1-P.
04167             Input range: (0, 1].
04168             P + Q = 1.0.
04169 
04170      X < --> Upper limit of integration of the normal-density.
04171              Input range: ( -infinity, +infinity)
04172 
04173      MEAN <--> The mean of the normal density.
04174                Input range: (-infinity, +infinity)
04175 
04176      SD <--> Standard Deviation of the normal density.
04177              Input range: (0, +infinity).
04178 
04179      STATUS <-- 0 if calculation completed correctly
04180                -I if input parameter number I is out of range
04181                 1 if answer appears to be lower than lowest
04182                   search bound
04183                 2 if answer appears to be higher than greatest
04184                   search bound
04185                 3 if P + Q .ne. 1
04186 
04187      BOUND <-- Undefined if STATUS is 0
04188 
04189                Bound exceeded by parameter number I if STATUS
04190                is negative.
04191 
04192                Lower search bound if STATUS is 1.
04193 
04194                Upper search bound if STATUS is 2.
04195 
04196 
04197                               Method
04198 
04199 
04200 
04201 
04202      A slightly modified version of ANORM from
04203 
04204      Cody, W.D. (1993). "ALGORITHM 715: SPECFUN - A Portabel FORTRAN
04205      Package of Special Function Routines and Test Drivers"
04206      acm Transactions on Mathematical Software. 19, 22-32.
04207 
04208      is used to calulate the  cumulative standard normal distribution.
04209 
04210      The rational functions from pages  90-95  of Kennedy and Gentle,
04211      Statistical  Computing,  Marcel  Dekker, NY,  1980 are  used  as
04212      starting values to Newton's Iterations which compute the inverse
04213      standard normal.  Therefore no  searches  are necessary for  any
04214      parameter.
04215 
04216      For X < -15, the asymptotic expansion for the normal is used  as
04217      the starting value in finding the inverse standard normal.
04218      This is formula 26.2.12 of Abramowitz and Stegun.
04219 
04220 
04221                               Note
04222 
04223 
04224       The normal density is proportional to
04225       exp( - 0.5 * (( X - MEAN)/SD)**2)
04226 
04227 **********************************************************************/
04228 {
04229 static int K1 = 1;
04230 static double z,pq;
04231 /*
04232      ..
04233      .. Executable Statements ..
04234 */
04235 /*
04236      Check arguments
04237 */
04238     *status = 0;
04239     if(!(*which < 1 || *which > 4)) goto S30;
04240     if(!(*which < 1)) goto S10;
04241     *bound = 1.0e0;
04242     goto S20;
04243 S10:
04244     *bound = 4.0e0;
04245 S20:
04246     *status = -1;
04247     return;
04248 S30:
04249     if(*which == 1) goto S70;
04250 /*
04251      P
04252 */
04253     if(!(*p <= 0.0e0 || *p > 1.0e0)) goto S60;
04254     if(!(*p <= 0.0e0)) goto S40;
04255     *bound = 0.0e0;
04256     goto S50;
04257 S40:
04258     *bound = 1.0e0;
04259 S50:
04260     *status = -2;
04261     return;
04262 S70:
04263 S60:
04264     if(*which == 1) goto S110;
04265 /*
04266      Q
04267 */
04268     if(!(*q <= 0.0e0 || *q > 1.0e0)) goto S100;
04269     if(!(*q <= 0.0e0)) goto S80;
04270     *bound = 0.0e0;
04271     goto S90;
04272 S80:
04273     *bound = 1.0e0;
04274 S90:
04275     *status = -3;
04276     return;
04277 S110:
04278 S100:
04279     if(*which == 1) goto S150;
04280 /*
04281      P + Q
04282 */
04283     pq = *p+*q;
04284     if(!(fabs(pq-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S140;
04285     if(!(pq < 0.0e0)) goto S120;
04286     *bound = 0.0e0;
04287     goto S130;
04288 S120:
04289     *bound = 1.0e0;
04290 S130:
04291     *status = 3;
04292     return;
04293 S150:
04294 S140:
04295     if(*which == 4) goto S170;
04296 /*
04297      SD
04298 */
04299     if(!(*sd <= 0.0e0)) goto S160;
04300     *bound = 0.0e0;
04301     *status = -6;
04302     return;
04303 S170:
04304 S160:
04305 /*
04306      Calculate ANSWERS
04307 */
04308     if(1 == *which) {
04309 /*
04310      Computing P
04311 */
04312         z = (*x-*mean)/ *sd;
04313         cumnor(&z,p,q);
04314     }
04315     else if(2 == *which) {
04316 /*
04317      Computing X
04318 */
04319         z = dinvnr(p,q);
04320         *x = *sd*z+*mean;
04321     }
04322     else if(3 == *which) {
04323 /*
04324      Computing the MEAN
04325 */
04326         z = dinvnr(p,q);
04327         *mean = *x-*sd*z;
04328     }
04329     else if(4 == *which) {
04330 /*
04331      Computing SD
04332 */
04333         z = dinvnr(p,q);
04334         *sd = (*x-*mean)/z;
04335     }
04336     return;
04337 } /* END */
04338 
04339 /***=====================================================================***/
04340 static void cdfpoi(int *which,double *p,double *q,double *s,double *xlam,
04341             int *status,double *bound)
04342 /**********************************************************************
04343 
04344       void cdfpoi(int *which,double *p,double *q,double *s,double *xlam,
04345             int *status,double *bound)
04346 
04347                Cumulative Distribution Function
04348                POIsson distribution
04349 
04350 
04351                               Function
04352 
04353 
04354      Calculates any one parameter of the Poisson
04355      distribution given values for the others.
04356 
04357 
04358                               Arguments
04359 
04360 
04361      WHICH --> Integer indicating which  argument
04362                value is to be calculated from the others.
04363                Legal range: 1..3
04364                iwhich = 1 : Calculate P and Q from S and XLAM
04365                iwhich = 2 : Calculate A from P,Q and XLAM
04366                iwhich = 3 : Calculate XLAM from P,Q and S
04367 
04368         P <--> The cumulation from 0 to S of the poisson density.
04369                Input range: [0,1].
04370 
04371         Q <--> 1-P.
04372                Input range: (0, 1].
04373                P + Q = 1.0.
04374 
04375         S <--> Upper limit of cumulation of the Poisson.
04376                Input range: [0, +infinity).
04377                Search range: [0,1E300]
04378 
04379      XLAM <--> Mean of the Poisson distribution.
04380                Input range: [0, +infinity).
04381                Search range: [0,1E300]
04382 
04383      STATUS <-- 0 if calculation completed correctly
04384                -I if input parameter number I is out of range
04385                 1 if answer appears to be lower than lowest
04386                   search bound
04387                 2 if answer appears to be higher than greatest
04388                   search bound
04389                 3 if P + Q .ne. 1
04390 
04391      BOUND <-- Undefined if STATUS is 0
04392 
04393                Bound exceeded by parameter number I if STATUS
04394                is negative.
04395 
04396                Lower search bound if STATUS is 1.
04397 
04398                Upper search bound if STATUS is 2.
04399 
04400 
04401                               Method
04402 
04403 
04404      Formula   26.4.21  of   Abramowitz  and   Stegun,   Handbook  of
04405      Mathematical Functions (1966) is used  to reduce the computation
04406      of  the cumulative distribution function to that  of computing a
04407      chi-square, hence an incomplete gamma function.
04408 
04409      Cumulative  distribution function  (P) is  calculated  directly.
04410      Computation of other parameters involve a seach for a value that
04411      produces  the desired value of  P.   The  search relies  on  the
04412      monotinicity of P with the other parameter.
04413 
04414 **********************************************************************/
04415 {
04416 #define tol (1.0e-8)
04417 #define atol (1.0e-50)
04418 #define inf 1.0e300
04419 static int K1 = 1;
04420 static double K2 = 0.0e0;
04421 static double K4 = 0.5e0;
04422 static double K5 = 5.0e0;
04423 static double fx,cum,ccum,pq;
04424 static unsigned long qhi,qleft,qporq;
04425 static double T3,T6,T7,T8,T9,T10;
04426 /*
04427      ..
04428      .. Executable Statements ..
04429 */
04430 /*
04431      Check arguments
04432 */
04433     if(!(*which < 1 || *which > 3)) goto S30;
04434     if(!(*which < 1)) goto S10;
04435     *bound = 1.0e0;
04436     goto S20;
04437 S10:
04438     *bound = 3.0e0;
04439 S20:
04440     *status = -1;
04441     return;
04442 S30:
04443     if(*which == 1) goto S70;
04444 /*
04445      P
04446 */
04447     if(!(*p < 0.0e0 || *p > 1.0e0)) goto S60;
04448     if(!(*p < 0.0e0)) goto S40;
04449     *bound = 0.0e0;
04450     goto S50;
04451 S40:
04452     *bound = 1.0e0;
04453 S50:
04454     *status = -2;
04455     return;
04456 S70:
04457 S60:
04458     if(*which == 1) goto S110;
04459 /*
04460      Q
04461 */
04462     if(!(*q <= 0.0e0 || *q > 1.0e0)) goto S100;
04463     if(!(*q <= 0.0e0)) goto S80;
04464     *bound = 0.0e0;
04465     goto S90;
04466 S80:
04467     *bound = 1.0e0;
04468 S90:
04469     *status = -3;
04470     return;
04471 S110:
04472 S100:
04473     if(*which == 2) goto S130;
04474 /*
04475      S
04476 */
04477     if(!(*s < 0.0e0)) goto S120;
04478     *bound = 0.0e0;
04479     *status = -4;
04480     return;
04481 S130:
04482 S120:
04483     if(*which == 3) goto S150;
04484 /*
04485      XLAM
04486 */
04487     if(!(*xlam < 0.0e0)) goto S140;
04488     *bound = 0.0e0;
04489     *status = -5;
04490     return;
04491 S150:
04492 S140:
04493     if(*which == 1) goto S190;
04494 /*
04495      P + Q
04496 */
04497     pq = *p+*q;
04498     if(!(fabs(pq-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S180;
04499     if(!(pq < 0.0e0)) goto S160;
04500     *bound = 0.0e0;
04501     goto S170;
04502 S160:
04503     *bound = 1.0e0;
04504 S170:
04505     *status = 3;
04506     return;
04507 S190:
04508 S180:
04509     if(!(*which == 1)) qporq = *p <= *q;
04510 /*
04511      Select the minimum of P or Q
04512      Calculate ANSWERS
04513 */
04514     if(1 == *which) {
04515 /*
04516      Calculating P
04517 */
04518         cumpoi(s,xlam,p,q);
04519         *status = 0;
04520     }
04521     else if(2 == *which) {
04522 /*
04523      Calculating S
04524 */
04525         *s = 5.0e0;
04526         T3 = inf;
04527         T6 = atol;
04528         T7 = tol;
04529         dstinv(&K2,&T3,&K4,&K4,&K5,&T6,&T7);
04530         *status = 0;
04531         dinvr(status,s,&fx,&qleft,&qhi);
04532 S200:
04533         if(!(*status == 1)) goto S230;
04534         cumpoi(s,xlam,&cum,&ccum);
04535         if(!qporq) goto S210;
04536         fx = cum-*p;
04537         goto S220;
04538 S210:
04539         fx = ccum-*q;
04540 S220:
04541         dinvr(status,s,&fx,&qleft,&qhi);
04542         goto S200;
04543 S230:
04544         if(!(*status == -1)) goto S260;
04545         if(!qleft) goto S240;
04546         *status = 1;
04547         *bound = 0.0e0;
04548         goto S250;
04549 S240:
04550         *status = 2;
04551         *bound = inf;
04552 S260:
04553 S250:
04554         ;
04555     }
04556     else if(3 == *which) {
04557 /*
04558      Calculating XLAM
04559 */
04560         *xlam = 5.0e0;
04561         T8 = inf;
04562         T9 = atol;
04563         T10 = tol;
04564         dstinv(&K2,&T8,&K4,&K4,&K5,&T9,&T10);
04565         *status = 0;
04566         dinvr(status,xlam,&fx,&qleft,&qhi);
04567 S270:
04568         if(!(*status == 1)) goto S300;
04569         cumpoi(s,xlam,&cum,&ccum);
04570         if(!qporq) goto S280;
04571         fx = cum-*p;
04572         goto S290;
04573 S280:
04574         fx = ccum-*q;
04575 S290:
04576         dinvr(status,xlam,&fx,&qleft,&qhi);
04577         goto S270;
04578 S300:
04579         if(!(*status == -1)) goto S330;
04580         if(!qleft) goto S310;
04581         *status = 1;
04582         *bound = 0.0e0;
04583         goto S320;
04584 S310:
04585         *status = 2;
04586         *bound = inf;
04587 S320:
04588         ;
04589     }
04590 S330:
04591     return;
04592 #undef tol
04593 #undef atol
04594 #undef inf
04595 } /* END */
04596 
04597 /***=====================================================================***/
04598 static void cdft(int *which,double *p,double *q,double *t,double *df,
04599           int *status,double *bound)
04600 /**********************************************************************
04601 
04602       void cdft(int *which,double *p,double *q,double *t,double *df,
04603           int *status,double *bound)
04604 
04605                Cumulative Distribution Function
04606                          T distribution
04607 
04608 
04609                               Function
04610 
04611 
04612      Calculates any one parameter of the t distribution given
04613      values for the others.
04614 
04615 
04616                               Arguments
04617 
04618 
04619      WHICH --> Integer indicating which  argument
04620                values is to be calculated from the others.
04621                Legal range: 1..3
04622                iwhich = 1 : Calculate P and Q from T and DF
04623                iwhich = 2 : Calculate T from P,Q and DF
04624                iwhich = 3 : Calculate DF from P,Q and T
04625 
04626         P <--> The integral from -infinity to t of the t-density.
04627                Input range: (0,1].
04628 
04629         Q <--> 1-P.
04630                Input range: (0, 1].
04631                P + Q = 1.0.
04632 
04633         T <--> Upper limit of integration of the t-density.
04634                Input range: ( -infinity, +infinity).
04635                Search range: [ -1E300, 1E300 ]
04636 
04637         DF <--> Degrees of freedom of the t-distribution.
04638                 Input range: (0 , +infinity).
04639                 Search range: [1e-300, 1E10]
04640 
04641      STATUS <-- 0 if calculation completed correctly
04642                -I if input parameter number I is out of range
04643                 1 if answer appears to be lower than lowest
04644                   search bound
04645                 2 if answer appears to be higher than greatest
04646                   search bound
04647                 3 if P + Q .ne. 1
04648 
04649      BOUND <-- Undefined if STATUS is 0
04650 
04651                Bound exceeded by parameter number I if STATUS
04652                is negative.
04653 
04654                Lower search bound if STATUS is 1.
04655 
04656                Upper search bound if STATUS is 2.
04657 
04658 
04659                               Method
04660 
04661 
04662      Formula  26.5.27  of   Abramowitz   and  Stegun,   Handbook   of
04663      Mathematical Functions  (1966) is used to reduce the computation
04664      of the cumulative distribution function to that of an incomplete
04665      beta.
04666 
04667      Computation of other parameters involve a seach for a value that
04668      produces  the desired  value  of P.   The search relies  on  the
04669      monotinicity of P with the other parameter.
04670 
04671 **********************************************************************/
04672 {
04673 #define tol (1.0e-8)
04674 #define atol (1.0e-50)
04675 #define zero (1.0e-300)
04676 #define inf 1.0e300
04677 #define maxdf 1.0e10
04678 static int K1 = 1;
04679 static double K4 = 0.5e0;
04680 static double K5 = 5.0e0;
04681 static double fx,cum,ccum,pq;
04682 static unsigned long qhi,qleft,qporq;
04683 static double T2,T3,T6,T7,T8,T9,T10,T11;
04684 /*
04685      ..
04686      .. Executable Statements ..
04687 */
04688 /*
04689      Check arguments
04690 */
04691     if(!(*which < 1 || *which > 3)) goto S30;
04692     if(!(*which < 1)) goto S10;
04693     *bound = 1.0e0;
04694     goto S20;
04695 S10:
04696     *bound = 3.0e0;
04697 S20:
04698     *status = -1;
04699     return;
04700 S30:
04701     if(*which == 1) goto S70;
04702 /*
04703      P
04704 */
04705     if(!(*p <= 0.0e0 || *p > 1.0e0)) goto S60;
04706     if(!(*p <= 0.0e0)) goto S40;
04707     *bound = 0.0e0;
04708     goto S50;
04709 S40:
04710     *bound = 1.0e0;
04711 S50:
04712     *status = -2;
04713     return;
04714 S70:
04715 S60:
04716     if(*which == 1) goto S110;
04717 /*
04718      Q
04719 */
04720     if(!(*q <= 0.0e0 || *q > 1.0e0)) goto S100;
04721     if(!(*q <= 0.0e0)) goto S80;
04722     *bound = 0.0e0;
04723     goto S90;
04724 S80:
04725     *bound = 1.0e0;
04726 S90:
04727     *status = -3;
04728     return;
04729 S110:
04730 S100:
04731     if(*which == 3) goto S130;
04732 /*
04733      DF
04734 */
04735     if(!(*df <= 0.0e0)) goto S120;
04736     *bound = 0.0e0;
04737     *status = -5;
04738     return;
04739 S130:
04740 S120:
04741     if(*which == 1) goto S170;
04742 /*
04743      P + Q
04744 */
04745     pq = *p+*q;
04746     if(!(fabs(pq-0.5e0-0.5e0) > 3.0e0*spmpar(&K1))) goto S160;
04747     if(!(pq < 0.0e0)) goto S140;
04748     *bound = 0.0e0;
04749     goto S150;
04750 S140:
04751     *bound = 1.0e0;
04752 S150:
04753     *status = 3;
04754     return;
04755 S170:
04756 S160:
04757     if(!(*which == 1)) qporq = *p <= *q;
04758 /*
04759      Select the minimum of P or Q
04760      Calculate ANSWERS
04761 */
04762     if(1 == *which) {
04763 /*
04764      Computing P and Q
04765 */
04766         cumt(t,df,p,q);
04767         *status = 0;
04768     }
04769     else if(2 == *which) {
04770 /*
04771      Computing T
04772      .. Get initial approximation for T
04773 */
04774         *t = dt1(p,q,df);
04775         T2 = -inf;
04776         T3 = inf;
04777         T6 = atol;
04778         T7 = tol;
04779         dstinv(&T2,&T3,&K4,&K4,&K5,&T6,&T7);
04780         *status = 0;
04781         dinvr(status,t,&fx,&qleft,&qhi);
04782 S180:
04783         if(!(*status == 1)) goto S210;
04784         cumt(t,df,&cum,&ccum);
04785         if(!qporq) goto S190;
04786         fx = cum-*p;
04787         goto S200;
04788 S190:
04789         fx = ccum-*q;
04790 S200:
04791         dinvr(status,t,&fx,&qleft,&qhi);
04792         goto S180;
04793 S210:
04794         if(!(*status == -1)) goto S240;
04795         if(!qleft) goto S220;
04796         *status = 1;
04797         *bound = -inf;
04798         goto S230;
04799 S220:
04800         *status = 2;
04801         *bound = inf;
04802 S240:
04803 S230:
04804         ;
04805     }
04806     else if(3 == *which) {
04807 /*
04808      Computing DF
04809 */
04810         *df = 5.0e0;
04811         T8 = zero;
04812         T9 = maxdf;
04813         T10 = atol;
04814         T11 = tol;
04815         dstinv(&T8,&T9,&K4,&K4,&K5,&T10,&T11);
04816         *status = 0;
04817         dinvr(status,df,&fx,&qleft,&qhi);
04818 S250:
04819         if(!(*status == 1)) goto S280;
04820         cumt(t,df,&cum,&ccum);
04821         if(!qporq) goto S260;
04822         fx = cum-*p;
04823         goto S270;
04824 S260:
04825         fx = ccum-*q;
04826 S270:
04827         dinvr(status,df,&fx,&qleft,&qhi);
04828         goto S250;
04829 S280:
04830         if(!(*status == -1)) goto S310;
04831         if(!qleft) goto S290;
04832         *status = 1;
04833         *bound = zero;
04834         goto S300;
04835 S290:
04836         *status = 2;
04837         *bound = maxdf;
04838 S300:
04839         ;
04840     }
04841 S310:
04842     return;
04843 #undef tol
04844 #undef atol
04845 #undef zero
04846 #undef inf
04847 #undef maxdf
04848 } /* END */
04849 
04850 /***=====================================================================***/
04851 static void cumbet(double *x,double *y,double *a,double *b,double *cum,
04852             double *ccum)
04853 /*
04854 **********************************************************************
04855 
04856      void cumbet(double *x,double *y,double *a,double *b,double *cum,
04857             double *ccum)
04858 
04859           Double precision cUMulative incomplete BETa distribution
04860 
04861 
04862                               Function
04863 
04864 
04865      Calculates the cdf to X of the incomplete beta distribution
04866      with parameters a and b.  This is the integral from 0 to x
04867      of (1/B(a,b))*f(t)) where f(t) = t**(a-1) * (1-t)**(b-1)
04868 
04869 
04870                               Arguments
04871 
04872 
04873      X --> Upper limit of integration.
04874                                         X is DOUBLE PRECISION
04875 
04876      Y --> 1 - X.
04877                                         Y is DOUBLE PRECISION
04878 
04879      A --> First parameter of the beta distribution.
04880                                         A is DOUBLE PRECISION
04881 
04882      B --> Second parameter of the beta distribution.
04883                                         B is DOUBLE PRECISION
04884 
04885      CUM <-- Cumulative incomplete beta distribution.
04886                                         CUM is DOUBLE PRECISION
04887 
04888      CCUM <-- Compliment of Cumulative incomplete beta distribution.
04889                                         CCUM is DOUBLE PRECISION
04890 
04891 
04892                               Method
04893 
04894 
04895      Calls the routine BRATIO.
04896 
04897                                    References
04898 
04899      Didonato, Armido R. and Morris, Alfred H. Jr. (1992) Algorithim
04900      708 Significant Digit Computation of the Incomplete Beta Function
04901      Ratios. ACM ToMS, Vol.18, No. 3, Sept. 1992, 360-373.
04902 
04903 **********************************************************************
04904 */
04905 {
04906 static int ierr;
04907 /*
04908      ..
04909      .. Executable Statements ..
04910 */
04911     if(!(*x <= 0.0e0)) goto S10;
04912     *cum = 0.0e0;
04913     *ccum = 1.0e0;
04914     return;
04915 S10:
04916     if(!(*y <= 0.0e0)) goto S20;
04917     *cum = 1.0e0;
04918     *ccum = 0.0e0;
04919     return;
04920 S20:
04921     bratio(a,b,x,y,cum,ccum,&ierr);
04922 /*
04923      Call bratio routine
04924 */
04925     return;
04926 } /* END */
04927 
04928 /***=====================================================================***/
04929 static void cumbin(double *s,double *xn,double *pr,double *ompr,
04930             double *cum,double *ccum)
04931 /*
04932 **********************************************************************
04933 
04934      void cumbin(double *s,double *xn,double *pr,double *ompr,
04935             double *cum,double *ccum)
04936 
04937                     CUmulative BINomial distribution
04938 
04939 
04940                               Function
04941 
04942 
04943      Returns the probability   of 0  to  S  successes in  XN   binomial
04944      trials, each of which has a probability of success, PBIN.
04945 
04946 
04947                               Arguments
04948 
04949 
04950      S --> The upper limit of cumulation of the binomial distribution.
04951                                                   S is DOUBLE PRECISION
04952 
04953      XN --> The number of binomial trials.
04954                                                   XN is DOUBLE PRECISIO
04955 
04956      PBIN --> The probability of success in each binomial trial.
04957                                                   PBIN is DOUBLE PRECIS
04958 
04959      OMPR --> 1 - PBIN
04960                                                   OMPR is DOUBLE PRECIS
04961 
04962      CUM <-- Cumulative binomial distribution.
04963                                                   CUM is DOUBLE PRECISI
04964 
04965      CCUM <-- Compliment of Cumulative binomial distribution.
04966                                                   CCUM is DOUBLE PRECIS
04967 
04968 
04969                               Method
04970 
04971 
04972      Formula  26.5.24    of   Abramowitz  and    Stegun,  Handbook   of
04973      Mathematical   Functions (1966) is   used  to reduce the  binomial
04974      distribution  to  the  cumulative    beta distribution.
04975 
04976 **********************************************************************
04977 */
04978 {
04979 static double T1,T2;
04980 /*
04981      ..
04982      .. Executable Statements ..
04983 */
04984     if(!(*s < *xn)) goto S10;
04985     T1 = *s+1.0e0;
04986     T2 = *xn-*s;
04987     cumbet(pr,ompr,&T1,&T2,ccum,cum);
04988     goto S20;
04989 S10:
04990     *cum = 1.0e0;
04991     *ccum = 0.0e0;
04992 S20:
04993     return;
04994 } /* END */
04995 
04996 /***=====================================================================***/
04997 static void cumchi(double *x,double *df,double *cum,double *ccum)
04998 /*
04999 **********************************************************************
05000 
05001      void cumchi(double *x,double *df,double *cum,double *ccum)
05002              CUMulative of the CHi-square distribution
05003 
05004 
05005                               Function
05006 
05007 
05008      Calculates the cumulative chi-square distribution.
05009 
05010 
05011                               Arguments
05012 
05013 
05014      X       --> Upper limit of integration of the
05015                  chi-square distribution.
05016                                                  X is DOUBLE PRECISION
05017 
05018      DF      --> Degrees of freedom of the
05019                  chi-square distribution.
05020                                                  DF is DOUBLE PRECISION
05021 
05022      CUM <-- Cumulative chi-square distribution.
05023                                                  CUM is DOUBLE PRECISIO
05024 
05025      CCUM <-- Compliment of Cumulative chi-square distribution.
05026                                                  CCUM is DOUBLE PRECISI
05027 
05028 
05029                               Method
05030 
05031 
05032      Calls incomplete gamma function (CUMGAM)
05033 
05034 **********************************************************************
05035 */
05036 {
05037 static double a,xx;
05038 /*
05039      ..
05040      .. Executable Statements ..
05041 */
05042     a = *df*0.5e0;
05043     xx = *x*0.5e0;
05044     cumgam(&xx,&a,cum,ccum);
05045     return;
05046 } /* END */
05047 
05048 /***=====================================================================***/
05049 static void cumchn(double *x,double *df,double *pnonc,double *cum,
05050             double *ccum)
05051 /*
05052 **********************************************************************
05053 
05054      void cumchn(double *x,double *df,double *pnonc,double *cum,
05055             double *ccum)
05056 
05057              CUMulative of the Non-central CHi-square distribution
05058 
05059 
05060                               Function
05061 
05062 
05063      Calculates     the       cumulative      non-central    chi-square
05064      distribution, i.e.,  the probability   that  a   random   variable
05065      which    follows  the  non-central chi-square  distribution,  with
05066      non-centrality  parameter    PNONC  and   continuous  degrees   of
05067      freedom DF, is less than or equal to X.
05068 
05069 
05070                               Arguments
05071 
05072 
05073      X       --> Upper limit of integration of the non-central
05074                  chi-square distribution.
05075                                                  X is DOUBLE PRECISION
05076 
05077      DF      --> Degrees of freedom of the non-central
05078                  chi-square distribution.
05079                                                  DF is DOUBLE PRECISION
05080 
05081      PNONC   --> Non-centrality parameter of the non-central
05082                  chi-square distribution.
05083                                                  PNONC is DOUBLE PRECIS
05084 
05085      CUM <-- Cumulative non-central chi-square distribution.
05086                                                  CUM is DOUBLE PRECISIO
05087 
05088      CCUM <-- Compliment of Cumulative non-central chi-square distribut
05089                                                  CCUM is DOUBLE PRECISI
05090 
05091 
05092                               Method
05093 
05094 
05095      Uses  formula  26.4.25   of  Abramowitz  and  Stegun, Handbook  of
05096      Mathematical    Functions,  US   NBS   (1966)    to calculate  the
05097      non-central chi-square.
05098 
05099 
05100                               Variables
05101 
05102 
05103      EPS     --- Convergence criterion.  The sum stops when a
05104                  term is less than EPS*SUM.
05105                                                  EPS is DOUBLE PRECISIO
05106 
05107      NTIRED  --- Maximum number of terms to be evaluated
05108                  in each sum.
05109                                                  NTIRED is INTEGER
05110 
05111      QCONV   --- .TRUE. if convergence achieved -
05112                  i.e., program did not stop on NTIRED criterion.
05113                                                  QCONV is LOGICAL
05114 
05115      CCUM <-- Compliment of Cumulative non-central
05116               chi-square distribution.
05117                                                  CCUM is DOUBLE PRECISI
05118 
05119 **********************************************************************
05120 */
05121 {
05122 #define dg(i) (*df+2.0e0*(double)(i))
05123 #define qsmall(xx) (int)(sum < 1.0e-20 || (xx) < eps*sum)
05124 #define qtired(i) (int)((i) > ntired)
05125 static double eps = 1.0e-5;
05126 static int ntired = 1000;
05127 static double adj,centaj,centwt,chid2,dfd2,lcntaj,lcntwt,lfact,pcent,pterm,sum,
05128     sumadj,term,wt,xnonc;
05129 static int i,icent,iterb,iterf;
05130 static double T1,T2,T3;
05131 /*
05132      ..
05133      .. Executable Statements ..
05134 */
05135     if(!(*x <= 0.0e0)) goto S10;
05136     *cum = 0.0e0;
05137     *ccum = 1.0e0;
05138     return;
05139 S10:
05140     if(!(*pnonc <= 1.0e-10)) goto S20;
05141 /*
05142      When non-centrality parameter is (essentially) zero,
05143      use cumulative chi-square distribution
05144 */
05145     cumchi(x,df,cum,ccum);
05146     return;
05147 S20:
05148     xnonc = *pnonc/2.0e0;
05149 /*
05150 **********************************************************************
05151      The following code calcualtes the weight, chi-square, and
05152      adjustment term for the central term in the infinite series.
05153      The central term is the one in which the poisson weight is
05154      greatest.  The adjustment term is the amount that must
05155      be subtracted from the chi-square to move up two degrees
05156      of freedom.
05157 **********************************************************************
05158 */
05159     icent = fifidint(xnonc);
05160     if(icent == 0) icent = 1;
05161     chid2 = *x/2.0e0;
05162 /*
05163      Calculate central weight term
05164 */
05165     T1 = (double)(icent+1);
05166     lfact = alngam(&T1);
05167     lcntwt = -xnonc+(double)icent*log(xnonc)-lfact;
05168     centwt = exp(lcntwt);
05169 /*
05170      Calculate central chi-square
05171 */
05172     T2 = dg(icent);
05173     cumchi(x,&T2,&pcent,ccum);
05174 /*
05175      Calculate central adjustment term
05176 */
05177     dfd2 = dg(icent)/2.0e0;
05178     T3 = 1.0e0+dfd2;
05179     lfact = alngam(&T3);
05180     lcntaj = dfd2*log(chid2)-chid2-lfact;
05181     centaj = exp(lcntaj);
05182     sum = centwt*pcent;
05183 /*
05184 **********************************************************************
05185      Sum backwards from the central term towards zero.
05186      Quit whenever either
05187      (1) the zero term is reached, or
05188      (2) the term gets small relative to the sum, or
05189      (3) More than NTIRED terms are totaled.
05190 **********************************************************************
05191 */
05192     iterb = 0;
05193     sumadj = 0.0e0;
05194     adj = centaj;
05195     wt = centwt;
05196     i = icent;
05197     goto S40;
05198 S30:
05199     if(qtired(iterb) || qsmall(term) || i == 0) goto S50;
05200 S40:
05201     dfd2 = dg(i)/2.0e0;
05202 /*
05203      Adjust chi-square for two fewer degrees of freedom.
05204      The adjusted value ends up in PTERM.
05205 */
05206     adj = adj*dfd2/chid2;
05207     sumadj += adj;
05208     pterm = pcent+sumadj;
05209 /*
05210      Adjust poisson weight for J decreased by one
05211 */
05212     wt *= ((double)i/xnonc);
05213     term = wt*pterm;
05214     sum += term;
05215     i -= 1;
05216     iterb += 1;
05217     goto S30;
05218 S50:
05219     iterf = 0;
05220 /*
05221 **********************************************************************
05222      Now sum forward from the central term towards infinity.
05223      Quit when either
05224      (1) the term gets small relative to the sum, or
05225      (2) More than NTIRED terms are totaled.
05226 **********************************************************************
05227 */
05228     sumadj = adj = centaj;
05229     wt = centwt;
05230     i = icent;
05231     goto S70;
05232 S60:
05233     if(qtired(iterf) || qsmall(term)) goto S80;
05234 S70:
05235 /*
05236      Update weights for next higher J
05237 */
05238     wt *= (xnonc/(double)(i+1));
05239 /*
05240      Calculate PTERM and add term to sum
05241 */
05242     pterm = pcent-sumadj;
05243     term = wt*pterm;
05244     sum += term;
05245 /*
05246      Update adjustment term for DF for next iteration
05247 */
05248     i += 1;
05249     dfd2 = dg(i)/2.0e0;
05250     adj = adj*chid2/dfd2;
05251     sumadj += adj;
05252     iterf += 1;
05253     goto S60;
05254 S80:
05255     *cum = sum;
05256     *ccum = 0.5e0+(0.5e0-*cum);
05257     return;
05258 #undef dg
05259 #undef qsmall
05260 #undef qtired
05261 } /* END */
05262 
05263 /***=====================================================================***/
05264 static void cumf(double *f,double *dfn,double *dfd,double *cum,double *ccum)
05265 /*
05266 **********************************************************************
05267 
05268      void cumf(double *f,double *dfn,double *dfd,double *cum,double *ccum)
05269                     CUMulative F distribution
05270 
05271 
05272                               Function
05273 
05274 
05275      Computes  the  integral from  0  to  F of  the f-density  with DFN
05276      and DFD degrees of freedom.
05277 
05278 
05279                               Arguments
05280 
05281 
05282      F --> Upper limit of integration of the f-density.
05283                                                   F is DOUBLE PRECISION
05284 
05285      DFN --> Degrees of freedom of the numerator sum of squares.
05286                                                   DFN is DOUBLE PRECISI
05287 
05288      DFD --> Degrees of freedom of the denominator sum of squares.
05289                                                   DFD is DOUBLE PRECISI
05290 
05291      CUM <-- Cumulative f distribution.
05292                                                   CUM is DOUBLE PRECISI
05293 
05294      CCUM <-- Compliment of Cumulative f distribution.
05295                                                   CCUM is DOUBLE PRECIS
05296 
05297 
05298                               Method
05299 
05300 
05301      Formula  26.5.28 of  Abramowitz and   Stegun   is  used to  reduce
05302      the cumulative F to a cumulative beta distribution.
05303 
05304 
05305                               Note
05306 
05307 
05308      If F is less than or equal to 0, 0 is returned.
05309 
05310 **********************************************************************
05311 */
05312 {
05313 #define half 0.5e0
05314 #define done 1.0e0
05315 static double dsum,prod,xx,yy;
05316 static int ierr;
05317 static double T1,T2;
05318 /*
05319      ..
05320      .. Executable Statements ..
05321 */
05322     if(!(*f <= 0.0e0)) goto S10;
05323     *cum = 0.0e0;
05324     *ccum = 1.0e0;
05325     return;
05326 S10:
05327     prod = *dfn**f;
05328 /*
05329      XX is such that the incomplete beta with parameters
05330      DFD/2 and DFN/2 evaluated at XX is 1 - CUM or CCUM
05331      YY is 1 - XX
05332      Calculate the smaller of XX and YY accurately
05333 */
05334     dsum = *dfd+prod;
05335     xx = *dfd/dsum;
05336     if(xx > half) {
05337         yy = prod/dsum;
05338         xx = done-yy;
05339     }
05340     else  yy = done-xx;
05341     T1 = *dfd*half;
05342     T2 = *dfn*half;
05343     bratio(&T1,&T2,&xx,&yy,ccum,cum,&ierr);
05344     return;
05345 #undef half
05346 #undef done
05347 } /* END */
05348 
05349 /***=====================================================================***/
05350 static void cumfnc(double *f,double *dfn,double *dfd,double *pnonc,
05351             double *cum,double *ccum)
05352 /*
05353 **********************************************************************
05354 
05355                F -NON- -C-ENTRAL F DISTRIBUTION
05356 
05357 
05358 
05359                               Function
05360 
05361 
05362      COMPUTES NONCENTRAL F DISTRIBUTION WITH DFN AND DFD
05363      DEGREES OF FREEDOM AND NONCENTRALITY PARAMETER PNONC
05364 
05365 
05366                               Arguments
05367 
05368 
05369      X --> UPPER LIMIT OF INTEGRATION OF NONCENTRAL F IN EQUATION
05370 
05371      DFN --> DEGREES OF FREEDOM OF NUMERATOR
05372 
05373      DFD -->  DEGREES OF FREEDOM OF DENOMINATOR
05374 
05375      PNONC --> NONCENTRALITY PARAMETER.
05376 
05377      CUM <-- CUMULATIVE NONCENTRAL F DISTRIBUTION
05378 
05379      CCUM <-- COMPLIMENT OF CUMMULATIVE
05380 
05381 
05382                               Method
05383 
05384 
05385      USES FORMULA 26.6.20 OF REFERENCE FOR INFINITE SERIES.
05386      SERIES IS CALCULATED BACKWARD AND FORWARD FROM J = LAMBDA/2
05387      (THIS IS THE TERM WITH THE LARGEST POISSON WEIGHT) UNTIL
05388      THE CONVERGENCE CRITERION IS MET.
05389 
05390      FOR SPEED, THE INCOMPLETE BETA FUNCTIONS ARE EVALUATED
05391      BY FORMULA 26.5.16.
05392 
05393 
05394                REFERENCE
05395 
05396 
05397      HANDBOOD OF MATHEMATICAL FUNCTIONS
05398      EDITED BY MILTON ABRAMOWITZ AND IRENE A. STEGUN
05399      NATIONAL BUREAU OF STANDARDS APPLIED MATEMATICS SERIES - 55
05400      MARCH 1965
05401      P 947, EQUATIONS 26.6.17, 26.6.18
05402 
05403 
05404                               Note
05405 
05406 
05407      THE SUM CONTINUES UNTIL A SUCCEEDING TERM IS LESS THAN EPS
05408      TIMES THE SUM (OR THE SUM IS LESS THAN 1.0E-20).  EPS IS
05409      SET TO 1.0E-4 IN A DATA STATEMENT WHICH CAN BE CHANGED.
05410 
05411 **********************************************************************
05412 */
05413 {
05414 #define qsmall(x) (int)(sum < 1.0e-20 || (x) < eps*sum)
05415 #define half 0.5e0
05416 #define done 1.0e0
05417 static double eps = 1.0e-4;
05418 static double dsum,dummy,prod,xx,yy,adn,aup,b,betdn,betup,centwt,dnterm,sum,
05419     upterm,xmult,xnonc;
05420 static int i,icent,ierr;
05421 static double T1,T2,T3,T4,T5,T6;
05422 /*
05423      ..
05424      .. Executable Statements ..
05425 */
05426     if(!(*f <= 0.0e0)) goto S10;
05427     *cum = 0.0e0;
05428     *ccum = 1.0e0;
05429     return;
05430 S10:
05431     if(!(*pnonc < 1.0e-10)) goto S20;
05432 /*
05433      Handle case in which the non-centrality parameter is
05434      (essentially) zero.
05435 */
05436     cumf(f,dfn,dfd,cum,ccum);
05437     return;
05438 S20:
05439     xnonc = *pnonc/2.0e0;
05440 /*
05441      Calculate the central term of the poisson weighting factor.
05442 */
05443     icent = xnonc;
05444     if(icent == 0) icent = 1;
05445 /*
05446      Compute central weight term
05447 */
05448     T1 = (double)(icent+1);
05449     centwt = exp(-xnonc+(double)icent*log(xnonc)-alngam(&T1));
05450 /*
05451      Compute central incomplete beta term
05452      Assure that minimum of arg to beta and 1 - arg is computed
05453           accurately.
05454 */
05455     prod = *dfn**f;
05456     dsum = *dfd+prod;
05457     yy = *dfd/dsum;
05458     if(yy > half) {
05459         xx = prod/dsum;
05460         yy = done-xx;
05461     }
05462     else  xx = done-yy;
05463     T2 = *dfn*half+(double)icent;
05464     T3 = *dfd*half;
05465     bratio(&T2,&T3,&xx,&yy,&betdn,&dummy,&ierr);
05466     adn = *dfn/2.0e0+(double)icent;
05467     aup = adn;
05468     b = *dfd/2.0e0;
05469     betup = betdn;
05470     sum = centwt*betdn;
05471 /*
05472      Now sum terms backward from icent until convergence or all done
05473 */
05474     xmult = centwt;
05475     i = icent;
05476     T4 = adn+b;
05477     T5 = adn+1.0e0;
05478     dnterm = exp(alngam(&T4)-alngam(&T5)-alngam(&b)+adn*log(xx)+b*log(yy));
05479 S30:
05480     if(qsmall(xmult*betdn) || i <= 0) goto S40;
05481     xmult *= ((double)i/xnonc);
05482     i -= 1;
05483     adn -= 1.0;
05484     dnterm = (adn+1.0)/((adn+b)*xx)*dnterm;
05485     betdn += dnterm;
05486     sum += (xmult*betdn);
05487     goto S30;
05488 S40:
05489     i = icent+1;
05490 /*
05491      Now sum forwards until convergence
05492 */
05493     xmult = centwt;
05494     if(aup-1.0+b == 0) upterm = exp(-alngam(&aup)-alngam(&b)+(aup-1.0)*log(xx)+
05495       b*log(yy));
05496     else  {
05497         T6 = aup-1.0+b;
05498         upterm = exp(alngam(&T6)-alngam(&aup)-alngam(&b)+(aup-1.0)*log(xx)+b*
05499           log(yy));
05500     }
05501     goto S60;
05502 S50:
05503     if(qsmall(xmult*betup)) goto S70;
05504 S60:
05505     xmult *= (xnonc/(double)i);
05506     i += 1;
05507     aup += 1.0;
05508     upterm = (aup+b-2.0e0)*xx/(aup-1.0)*upterm;
05509     betup -= upterm;
05510     sum += (xmult*betup);
05511     goto S50;
05512 S70:
05513     *cum = sum;
05514     *ccum = 0.5e0+(0.5e0-*cum);
05515     return;
05516 #undef qsmall
05517 #undef half
05518 #undef done
05519 } /* END */
05520 
05521 /***=====================================================================***/
05522 static void cumgam(double *x,double *a,double *cum,double *ccum)
05523 /*
05524 **********************************************************************
05525 
05526      void cumgam(double *x,double *a,double *cum,double *ccum)
05527            Double precision cUMulative incomplete GAMma distribution
05528 
05529 
05530                               Function
05531 
05532 
05533      Computes   the  cumulative        of    the     incomplete   gamma
05534      distribution, i.e., the integral from 0 to X of
05535           (1/GAM(A))*EXP(-T)*T**(A-1) DT
05536      where GAM(A) is the complete gamma function of A, i.e.,
05537           GAM(A) = integral from 0 to infinity of
05538                     EXP(-T)*T**(A-1) DT
05539 
05540 
05541                               Arguments
05542 
05543 
05544      X --> The upper limit of integration of the incomplete gamma.
05545                                                 X is DOUBLE PRECISION
05546 
05547      A --> The shape parameter of the incomplete gamma.
05548                                                 A is DOUBLE PRECISION
05549 
05550      CUM <-- Cumulative incomplete gamma distribution.
05551                                         CUM is DOUBLE PRECISION
05552 
05553      CCUM <-- Compliment of Cumulative incomplete gamma distribution.
05554                                                 CCUM is DOUBLE PRECISIO
05555 
05556 
05557                               Method
05558 
05559 
05560      Calls the routine GRATIO.
05561 
05562 **********************************************************************
05563 */
05564 {
05565 static int K1 = 0;
05566 /*
05567      ..
05568      .. Executable Statements ..
05569 */
05570     if(!(*x <= 0.0e0)) goto S10;
05571     *cum = 0.0e0;
05572     *ccum = 1.0e0;
05573     return;
05574 S10:
05575     gratio(a,x,cum,ccum,&K1);
05576 /*
05577      Call gratio routine
05578 */
05579     return;
05580 } /* END */
05581 
05582 /***=====================================================================***/
05583 static void cumnbn(double *s,double *xn,double *pr,double *ompr,
05584             double *cum,double *ccum)
05585 /*
05586 **********************************************************************
05587 
05588      void cumnbn(double *s,double *xn,double *pr,double *ompr,
05589             double *cum,double *ccum)
05590 
05591                     CUmulative Negative BINomial distribution
05592 
05593 
05594                               Function
05595 
05596 
05597      Returns the probability that it there will be S or fewer failures
05598      before there are XN successes, with each binomial trial having
05599      a probability of success PR.
05600 
05601      Prob(# failures = S | XN successes, PR)  =
05602                         ( XN + S - 1 )
05603                         (            ) * PR^XN * (1-PR)^S
05604                         (      S     )
05605 
05606 
05607                               Arguments
05608 
05609 
05610      S --> The number of failures
05611                                                   S is DOUBLE PRECISION
05612 
05613      XN --> The number of successes
05614                                                   XN is DOUBLE PRECISIO
05615 
05616      PR --> The probability of success in each binomial trial.
05617                                                   PR is DOUBLE PRECISIO
05618 
05619      OMPR --> 1 - PR
05620                                                   OMPR is DOUBLE PRECIS
05621 
05622      CUM <-- Cumulative negative binomial distribution.
05623                                                   CUM is DOUBLE PRECISI
05624 
05625      CCUM <-- Compliment of Cumulative negative binomial distribution.
05626                                                   CCUM is DOUBLE PRECIS
05627 
05628 
05629                               Method
05630 
05631 
05632      Formula  26.5.26    of   Abramowitz  and    Stegun,  Handbook   of
05633      Mathematical   Functions (1966) is   used  to reduce the  negative
05634      binomial distribution to the cumulative beta distribution.
05635 
05636 **********************************************************************
05637 */
05638 {
05639 static double T1;
05640 /*
05641      ..
05642      .. Executable Statements ..
05643 */
05644     T1 = *s+1.e0;
05645     cumbet(pr,ompr,xn,&T1,cum,ccum);
05646     return;
05647 } /* END */
05648 
05649 /***=====================================================================***/
05650 static void cumnor(double *arg,double *result,double *ccum)
05651 /*
05652 **********************************************************************
05653 
05654      void cumnor(double *arg,double *result,double *ccum)
05655 
05656 
05657                               Function
05658 
05659 
05660      Computes the cumulative  of    the  normal   distribution,   i.e.,
05661      the integral from -infinity to x of
05662           (1/sqrt(2*pi)) exp(-u*u/2) du
05663 
05664      X --> Upper limit of integration.
05665                                         X is DOUBLE PRECISION
05666 
05667      RESULT <-- Cumulative normal distribution.
05668                                         RESULT is DOUBLE PRECISION
05669 
05670      CCUM <-- Compliment of Cumulative normal distribution.
05671                                         CCUM is DOUBLE PRECISION
05672 
05673      Renaming of function ANORM from:
05674 
05675      Cody, W.D. (1993). "ALGORITHM 715: SPECFUN - A Portabel FORTRAN
05676      Package of Special Function Routines and Test Drivers"
05677      acm Transactions on Mathematical Software. 19, 22-32.
05678 
05679      with slight modifications to return ccum and to deal with
05680      machine constants.
05681 
05682 **********************************************************************
05683   Original Comments:
05684 ------------------------------------------------------------------
05685 
05686  This function evaluates the normal distribution function:
05687 
05688                               / x
05689                      1       |       -t*t/2
05690           P(x) = ----------- |      e       dt
05691                  sqrt(2 pi)  |
05692                              /-oo
05693 
05694    The main computation evaluates near-minimax approximations
05695    derived from those in "Rational Chebyshev approximations for
05696    the error function" by W. J. Cody, Math. Comp., 1969, 631-637.
05697    This transportable program uses rational functions that
05698    theoretically approximate the normal distribution function to
05699    at least 18 significant decimal digits.  The accuracy achieved
05700    depends on the arithmetic system, the compiler, the intrinsic
05701    functions, and proper selection of the machine-dependent
05702    constants.
05703 
05704 *******************************************************************
05705 *******************************************************************
05706 
05707  Explanation of machine-dependent constants.
05708 
05709    MIN   = smallest machine representable number.
05710 
05711    EPS   = argument below which anorm(x) may be represented by
05712            0.5  and above which  x*x  will not underflow.
05713            A conservative value is the largest machine number X
05714            such that   1.0 + X = 1.0   to machine precision.
05715 *******************************************************************
05716 *******************************************************************
05717 
05718  Error returns
05719 
05720   The program returns  ANORM = 0     for  ARG .LE. XLOW.
05721 
05722 
05723  Intrinsic functions required are:
05724 
05725      ABS, AINT, EXP
05726 
05727 
05728   Author: W. J. Cody
05729           Mathematics and Computer Science Division
05730           Argonne National Laboratory
05731           Argonne, IL 60439
05732 
05733   Latest modification: March 15, 1992
05734 
05735 ------------------------------------------------------------------
05736 */
05737 {
05738 static double a[5] = {
05739     2.2352520354606839287e00,1.6102823106855587881e02,1.0676894854603709582e03,
05740     1.8154981253343561249e04,6.5682337918207449113e-2
05741 };
05742 static double b[4] = {
05743     4.7202581904688241870e01,9.7609855173777669322e02,1.0260932208618978205e04,
05744     4.5507789335026729956e04
05745 };
05746 static double c[9] = {
05747     3.9894151208813466764e-1,8.8831497943883759412e00,9.3506656132177855979e01,
05748     5.9727027639480026226e02,2.4945375852903726711e03,6.8481904505362823326e03,
05749     1.1602651437647350124e04,9.8427148383839780218e03,1.0765576773720192317e-8
05750 };
05751 static double d[8] = {
05752     2.2266688044328115691e01,2.3538790178262499861e02,1.5193775994075548050e03,
05753     6.4855582982667607550e03,1.8615571640885098091e04,3.4900952721145977266e04,
05754     3.8912003286093271411e04,1.9685429676859990727e04
05755 };
05756 static double half = 0.5e0;
05757 static double p[6] = {
05758     2.1589853405795699e-1,1.274011611602473639e-1,2.2235277870649807e-2,
05759     1.421619193227893466e-3,2.9112874951168792e-5,2.307344176494017303e-2
05760 };
05761 static double one = 1.0e0;
05762 static double q[5] = {
05763     1.28426009614491121e00,4.68238212480865118e-1,6.59881378689285515e-2,
05764     3.78239633202758244e-3,7.29751555083966205e-5
05765 };
05766 static double sixten = 1.60e0;
05767 static double sqrpi = 3.9894228040143267794e-1;
05768 static double thrsh = 0.66291e0;
05769 static double root32 = 5.656854248e0;
05770 static double zero = 0.0e0;
05771 static int K1 = 1;
05772 static int K2 = 2;
05773 static int i;
05774 static double del,eps,temp,x,xden,xnum,y,xsq,min;
05775 /*
05776 ------------------------------------------------------------------
05777   Machine dependent constants
05778 ------------------------------------------------------------------
05779 */
05780     eps = spmpar(&K1)*0.5e0;
05781     min = spmpar(&K2);
05782     x = *arg;
05783     y = fabs(x);
05784     if(y <= thrsh) {
05785 /*
05786 ------------------------------------------------------------------
05787   Evaluate  anorm  for  |X| <= 0.66291
05788 ------------------------------------------------------------------
05789 */
05790         xsq = zero;
05791         if(y > eps) xsq = x*x;
05792         xnum = a[4]*xsq;
05793         xden = xsq;
05794         for(i=0; i<3; i++) {
05795             xnum = (xnum+a[i])*xsq;
05796             xden = (xden+b[i])*xsq;
05797         }
05798         *result = x*(xnum+a[3])/(xden+b[3]);
05799         temp = *result;
05800         *result = half+temp;
05801         *ccum = half-temp;
05802     }
05803 /*
05804 ------------------------------------------------------------------
05805   Evaluate  anorm  for 0.66291 <= |X| <= sqrt(32)
05806 ------------------------------------------------------------------
05807 */
05808     else if(y <= root32) {
05809         xnum = c[8]*y;
05810         xden = y;
05811         for(i=0; i<7; i++) {
05812             xnum = (xnum+c[i])*y;
05813             xden = (xden+d[i])*y;
05814         }
05815         *result = (xnum+c[7])/(xden+d[7]);
05816         xsq = fifdint(y*sixten)/sixten;
05817         del = (y-xsq)*(y+xsq);
05818         *result = exp(-(xsq*xsq*half))*exp(-(del*half))**result;
05819         *ccum = one-*result;
05820         if(x > zero) {
05821             temp = *result;
05822             *result = *ccum;
05823             *ccum = temp;
05824         }
05825     }
05826 /*
05827 ------------------------------------------------------------------
05828   Evaluate  anorm  for |X| > sqrt(32)
05829 ------------------------------------------------------------------
05830 */
05831     else  {
05832         *result = zero;
05833         xsq = one/(x*x);
05834         xnum = p[5]*xsq;
05835         xden = xsq;
05836         for(i=0; i<4; i++) {
05837             xnum = (xnum+p[i])*xsq;
05838             xden = (xden+q[i])*xsq;
05839         }
05840         *result = xsq*(xnum+p[4])/(xden+q[4]);
05841         *result = (sqrpi-*result)/y;
05842         xsq = fifdint(x*sixten)/sixten;
05843         del = (x-xsq)*(x+xsq);
05844         *result = exp(-(xsq*xsq*half))*exp(-(del*half))**result;
05845         *ccum = one-*result;
05846         if(x > zero) {
05847             temp = *result;
05848             *result = *ccum;
05849             *ccum = temp;
05850         }
05851     }
05852     if(*result < min) *result = 0.0e0;
05853 /*
05854 ------------------------------------------------------------------
05855   Fix up for negative argument, erf, etc.
05856 ------------------------------------------------------------------
05857 ----------Last card of ANORM ----------
05858 */
05859     if(*ccum < min) *ccum = 0.0e0;
05860 } /* END */
05861 
05862 /***=====================================================================***/
05863 static void cumpoi(double *s,double *xlam,double *cum,double *ccum)
05864 /*
05865 **********************************************************************
05866 
05867      void cumpoi(double *s,double *xlam,double *cum,double *ccum)
05868                     CUMulative POIsson distribution
05869 
05870 
05871                               Function
05872 
05873 
05874      Returns the  probability  of  S   or  fewer events in  a   Poisson
05875      distribution with mean XLAM.
05876 
05877 
05878                               Arguments
05879 
05880 
05881      S --> Upper limit of cumulation of the Poisson.
05882                                                   S is DOUBLE PRECISION
05883 
05884      XLAM --> Mean of the Poisson distribution.
05885                                                   XLAM is DOUBLE PRECIS
05886 
05887      CUM <-- Cumulative poisson distribution.
05888                                         CUM is DOUBLE PRECISION
05889 
05890      CCUM <-- Compliment of Cumulative poisson distribution.
05891                                                   CCUM is DOUBLE PRECIS
05892 
05893 
05894                               Method
05895 
05896 
05897      Uses formula  26.4.21   of   Abramowitz and  Stegun,  Handbook  of
05898      Mathematical   Functions  to reduce   the   cumulative Poisson  to
05899      the cumulative chi-square distribution.
05900 
05901 **********************************************************************
05902 */
05903 {
05904 static double chi,df;
05905 /*
05906      ..
05907      .. Executable Statements ..
05908 */
05909     df = 2.0e0*(*s+1.0e0);
05910     chi = 2.0e0**xlam;
05911     cumchi(&chi,&df,ccum,cum);
05912     return;
05913 } /* END */
05914 
05915 /***=====================================================================***/
05916 static void cumt(double *t,double *df,double *cum,double *ccum)
05917 /*
05918 **********************************************************************
05919 
05920      void cumt(double *t,double *df,double *cum,double *ccum)
05921                     CUMulative T-distribution
05922 
05923 
05924                               Function
05925 
05926 
05927      Computes the integral from -infinity to T of the t-density.
05928 
05929 
05930                               Arguments
05931 
05932 
05933      T --> Upper limit of integration of the t-density.
05934                                                   T is DOUBLE PRECISION
05935 
05936      DF --> Degrees of freedom of the t-distribution.
05937                                                   DF is DOUBLE PRECISIO
05938 
05939      CUM <-- Cumulative t-distribution.
05940                                                   CCUM is DOUBLE PRECIS
05941 
05942      CCUM <-- Compliment of Cumulative t-distribution.
05943                                                   CCUM is DOUBLE PRECIS
05944 
05945 
05946                               Method
05947 
05948 
05949      Formula 26.5.27   of     Abramowitz  and   Stegun,    Handbook  of
05950      Mathematical Functions  is   used   to  reduce the  t-distribution
05951      to an incomplete beta.
05952 
05953 **********************************************************************
05954 */
05955 {
05956 static double K2 = 0.5e0;
05957 static double xx,a,oma,tt,yy,dfptt,T1;
05958 /*
05959      ..
05960      .. Executable Statements ..
05961 */
05962     tt = *t**t;
05963     dfptt = *df+tt;
05964     xx = *df/dfptt;
05965     yy = tt/dfptt;
05966     T1 = 0.5e0**df;
05967     cumbet(&xx,&yy,&T1,&K2,&a,&oma);
05968     if(!(*t <= 0.0e0)) goto S10;
05969     *cum = 0.5e0*a;
05970     *ccum = oma+*cum;
05971     goto S20;
05972 S10:
05973     *ccum = 0.5e0*a;
05974     *cum = oma+*ccum;
05975 S20:
05976     return;
05977 } /* END */
05978 
05979 /***=====================================================================***/
05980 static double dbetrm(double *a,double *b)
05981 /*
05982 **********************************************************************
05983 
05984      double dbetrm(double *a,double *b)
05985           Double Precision Sterling Remainder for Complete
05986                     Beta Function
05987 
05988 
05989                               Function
05990 
05991 
05992      Log(Beta(A,B)) = Lgamma(A) + Lgamma(B) - Lgamma(A+B)
05993      where Lgamma is the log of the (complete) gamma function
05994 
05995      Let ZZ be approximation obtained if each log gamma is approximated
05996      by Sterling's formula, i.e.,
05997      Sterling(Z) = LOG( SQRT( 2*PI ) ) + ( Z-0.5 ) * LOG( Z ) - Z
05998 
05999      Returns Log(Beta(A,B)) - ZZ
06000 
06001 
06002                               Arguments
06003 
06004 
06005      A --> One argument of the Beta
06006                     DOUBLE PRECISION A
06007 
06008      B --> The other argument of the Beta
06009                     DOUBLE PRECISION B
06010 
06011 **********************************************************************
06012 */
06013 {
06014 static double dbetrm,T1,T2,T3;
06015 /*
06016      ..
06017      .. Executable Statements ..
06018 */
06019 /*
06020      Try to sum from smallest to largest
06021 */
06022     T1 = *a+*b;
06023     dbetrm = -dstrem(&T1);
06024     T2 = fifdmax1(*a,*b);
06025     dbetrm += dstrem(&T2);
06026     T3 = fifdmin1(*a,*b);
06027     dbetrm += dstrem(&T3);
06028     return dbetrm;
06029 } /* END */
06030 
06031 /***=====================================================================***/
06032 static double devlpl(double a[],int *n,double *x)
06033 /*
06034 **********************************************************************
06035 
06036      double devlpl(double a[],int *n,double *x)
06037               Double precision EVALuate a PoLynomial at X
06038 
06039 
06040                               Function
06041 
06042 
06043      returns
06044           A(1) + A(2)*X + ... + A(N)*X**(N-1)
06045 
06046 
06047                               Arguments
06048 
06049 
06050      A --> Array of coefficients of the polynomial.
06051                                         A is DOUBLE PRECISION(N)
06052 
06053      N --> Length of A, also degree of polynomial - 1.
06054                                         N is INTEGER
06055 
06056      X --> Point at which the polynomial is to be evaluated.
06057                                         X is DOUBLE PRECISION
06058 
06059 **********************************************************************
06060 */
06061 {
06062 static double devlpl,term;
06063 static int i;
06064 /*
06065      ..
06066      .. Executable Statements ..
06067 */
06068     term = a[*n-1];
06069     for(i= *n-1-1; i>=0; i--) term = a[i]+term**x;
06070     devlpl = term;
06071     return devlpl;
06072 } /* END */
06073 
06074 /***=====================================================================***/
06075 static double dexpm1(double *x)
06076 /*
06077 **********************************************************************
06078 
06079      double dexpm1(double *x)
06080             Evaluation of the function EXP(X) - 1
06081 
06082 
06083                               Arguments
06084 
06085 
06086      X --> Argument at which exp(x)-1 desired
06087                     DOUBLE PRECISION X
06088 
06089 
06090                               Method
06091 
06092 
06093      Renaming of function rexp from code of:
06094 
06095      DiDinato, A. R. and Morris,  A.   H.  Algorithm 708: Significant
06096      Digit Computation of the Incomplete  Beta  Function Ratios.  ACM
06097      Trans. Math.  Softw. 18 (1993), 360-373.
06098 
06099 **********************************************************************
06100 */
06101 {
06102 static double p1 = .914041914819518e-09;
06103 static double p2 = .238082361044469e-01;
06104 static double q1 = -.499999999085958e+00;
06105 static double q2 = .107141568980644e+00;
06106 static double q3 = -.119041179760821e-01;
06107 static double q4 = .595130811860248e-03;
06108 static double dexpm1,w;
06109 /*
06110      ..
06111      .. Executable Statements ..
06112 */
06113     if(fabs(*x) > 0.15e0) goto S10;
06114     dexpm1 = *x*(((p2**x+p1)**x+1.0e0)/((((q4**x+q3)**x+q2)**x+q1)**x+1.0e0));
06115     return dexpm1;
06116 S10:
06117     w = exp(*x);
06118     if(*x > 0.0e0) goto S20;
06119     dexpm1 = w-0.5e0-0.5e0;
06120     return dexpm1;
06121 S20:
06122     dexpm1 = w*(0.5e0+(0.5e0-1.0e0/w));
06123     return dexpm1;
06124 } /* END */
06125 
06126 /***=====================================================================***/
06127 static double dinvnr(double *p,double *q)
06128 /*
06129 **********************************************************************
06130 
06131      double dinvnr(double *p,double *q)
06132      Double precision NoRmal distribution INVerse
06133 
06134 
06135                               Function
06136 
06137 
06138      Returns X  such that CUMNOR(X)  =   P,  i.e., the  integral from -
06139      infinity to X of (1/SQRT(2*PI)) EXP(-U*U/2) dU is P
06140 
06141 
06142                               Arguments
06143 
06144 
06145      P --> The probability whose normal deviate is sought.
06146                     P is DOUBLE PRECISION
06147 
06148      Q --> 1-P
06149                     P is DOUBLE PRECISION
06150 
06151 
06152                               Method
06153 
06154 
06155      The  rational   function   on  page 95    of Kennedy  and  Gentle,
06156      Statistical Computing, Marcel Dekker, NY , 1980 is used as a start
06157      value for the Newton method of finding roots.
06158 
06159 
06160                               Note
06161 
06162 
06163      If P or Q .lt. machine EPS returns +/- DINVNR(EPS)
06164 
06165 **********************************************************************
06166 */
06167 {
06168 #define maxit 100
06169 #define eps (1.0e-13)
06170 #define r2pi 0.3989422804014326e0
06171 #define nhalf (-0.5e0)
06172 #define dennor(x) (r2pi*exp(nhalf*(x)*(x)))
06173 static double dinvnr,strtx,xcur,cum,ccum,pp,dx;
06174 static int i;
06175 static unsigned long qporq;
06176 /*
06177      ..
06178      .. Executable Statements ..
06179 */
06180 /*
06181      FIND MINIMUM OF P AND Q
06182 */
06183     qporq = *p <= *q;
06184     if(!qporq) goto S10;
06185     pp = *p;
06186     goto S20;
06187 S10:
06188     pp = *q;
06189 S20:
06190 /*
06191      INITIALIZATION STEP
06192 */
06193     strtx = stvaln(&pp);
06194     xcur = strtx;
06195 /*
06196      NEWTON INTERATIONS
06197 */
06198     for(i=1; i<=maxit; i++) {
06199         cumnor(&xcur,&cum,&ccum);
06200         dx = (cum-pp)/dennor(xcur);
06201         xcur -= dx;
06202         if(fabs(dx/xcur) < eps) goto S40;
06203     }
06204     dinvnr = strtx;
06205 /*
06206      IF WE GET HERE, NEWTON HAS FAILED
06207 */
06208     if(!qporq) dinvnr = -dinvnr;
06209     return dinvnr;
06210 S40:
06211 /*
06212      IF WE GET HERE, NEWTON HAS SUCCEDED
06213 */
06214     dinvnr = xcur;
06215     if(!qporq) dinvnr = -dinvnr;
06216     return dinvnr;
06217 #undef maxit
06218 #undef eps
06219 #undef r2pi
06220 #undef nhalf
06221 #undef dennor
06222 } /* END */
06223 
06224 /***=====================================================================***/
06225 static void E0000(int IENTRY,int *status,double *x,double *fx,
06226                   unsigned long *qleft,unsigned long *qhi,double *zabsst,
06227                   double *zabsto,double *zbig,double *zrelst,
06228                   double *zrelto,double *zsmall,double *zstpmu)
06229 {
06230 #define qxmon(zx,zy,zz) (int)((zx) <= (zy) && (zy) <= (zz))
06231 static double absstp,abstol,big,fbig,fsmall,relstp,reltol,small,step,stpmul,xhi,
06232     xlb,xlo,xsave,xub,yy;
06233 static int i99999;
06234 static unsigned long qbdd,qcond,qdum1,qdum2,qincr,qlim,qok,qup;
06235     switch(IENTRY){case 0: goto DINVR; case 1: goto DSTINV;}
06236 DINVR:
06237     if(*status > 0) goto S310;
06238     qcond = !qxmon(small,*x,big);
06239     if(qcond){ ftnstop("SMALL,X,BIG nonmonotone in E0000"); *status=-1; return;}
06240     xsave = *x;
06241 /*
06242      See that SMALL and BIG bound the zero and set QINCR
06243 */
06244     *x = small;
06245 /*
06246      GET-FUNCTION-VALUE
06247 */
06248     i99999 = 1;
06249     goto S300;
06250 S10:
06251     fsmall = *fx;
06252     *x = big;
06253 /*
06254      GET-FUNCTION-VALUE
06255 */
06256     i99999 = 2;
06257     goto S300;
06258 S20:
06259     fbig = *fx;
06260     qincr = fbig > fsmall;
06261     if(!qincr) goto S50;
06262     if(fsmall <= 0.0e0) goto S30;
06263     *status = -1;
06264     *qleft = *qhi = 1;
06265     return;
06266 S30:
06267     if(fbig >= 0.0e0) goto S40;
06268     *status = -1;
06269     *qleft = *qhi = 0;
06270     return;
06271 S40:
06272     goto S80;
06273 S50:
06274     if(fsmall >= 0.0e0) goto S60;
06275     *status = -1;
06276     *qleft = 1;
06277     *qhi = 0;
06278     return;
06279 S60:
06280     if(fbig <= 0.0e0) goto S70;
06281     *status = -1;
06282     *qleft = 0;
06283     *qhi = 1;
06284     return;
06285 S80:
06286 S70:
06287     *x = xsave;
06288     step = fifdmax1(absstp,relstp*fabs(*x));
06289 /*
06290       YY = F(X) - Y
06291      GET-FUNCTION-VALUE
06292 */
06293     i99999 = 3;
06294     goto S300;
06295 S90:
06296     yy = *fx;
06297     if(!(yy == 0.0e0)) goto S100;
06298     *status = 0;
06299     qok = 1;
06300     return;
06301 S100:
06302     qup = qincr && yy < 0.0e0 || !qincr && yy > 0.0e0;
06303 /*
06304 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
06305      HANDLE CASE IN WHICH WE MUST STEP HIGHER
06306 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
06307 */
06308     if(!qup) goto S170;
06309     xlb = xsave;
06310     xub = fifdmin1(xlb+step,big);
06311     goto S120;
06312 S110:
06313     if(qcond) goto S150;
06314 S120:
06315 /*
06316       YY = F(XUB) - Y
06317 */
06318     *x = xub;
06319 /*
06320      GET-FUNCTION-VALUE
06321 */
06322     i99999 = 4;
06323     goto S300;
06324 S130:
06325     yy = *fx;
06326     qbdd = qincr && yy >= 0.0e0 || !qincr && yy <= 0.0e0;
06327     qlim = xub >= big;
06328     qcond = qbdd || qlim;
06329     if(qcond) goto S140;
06330     step = stpmul*step;
06331     xlb = xub;
06332     xub = fifdmin1(xlb+step,big);
06333 S140:
06334     goto S110;
06335 S150:
06336     if(!(qlim && !qbdd)) goto S160;
06337     *status = -1;
06338     *qleft = 0;
06339     *qhi = !qincr;
06340     *x = big;
06341     return;
06342 S160:
06343     goto S240;
06344 S170:
06345 /*
06346 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
06347      HANDLE CASE IN WHICH WE MUST STEP LOWER
06348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
06349 */
06350     xub = xsave;
06351     xlb = fifdmax1(xub-step,small);
06352     goto S190;
06353 S180:
06354     if(qcond) goto S220;
06355 S190:
06356 /*
06357       YY = F(XLB) - Y
06358 */
06359     *x = xlb;
06360 /*
06361      GET-FUNCTION-VALUE
06362 */
06363     i99999 = 5;
06364     goto S300;
06365 S200:
06366     yy = *fx;
06367     qbdd = qincr && yy <= 0.0e0 || !qincr && yy >= 0.0e0;
06368     qlim = xlb <= small;
06369     qcond = qbdd || qlim;
06370     if(qcond) goto S210;
06371     step = stpmul*step;
06372     xub = xlb;
06373     xlb = fifdmax1(xub-step,small);
06374 S210:
06375     goto S180;
06376 S220:
06377     if(!(qlim && !qbdd)) goto S230;
06378     *status = -1;
06379     *qleft = 1;
06380     *qhi = qincr;
06381     *x = small;
06382     return;
06383 S240:
06384 S230:
06385     dstzr(&xlb,&xub,&abstol,&reltol);
06386 /*
06387 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
06388      IF WE REACH HERE, XLB AND XUB BOUND THE ZERO OF F.
06389 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
06390 */
06391     *status = 0;
06392     goto S260;
06393 S250:
06394     if(!(*status == 1)) goto S290;
06395 S260:
06396     dzror(status,x,fx,&xlo,&xhi,&qdum1,&qdum2);
06397     if(!(*status == 1)) goto S280;
06398 /*
06399      GET-FUNCTION-VALUE
06400 */
06401     i99999 = 6;
06402     goto S300;
06403 S280:
06404 S270:
06405     goto S250;
06406 S290:
06407     *x = xlo;
06408     *status = 0;
06409     return;
06410 DSTINV:
06411     small = *zsmall;
06412     big = *zbig;
06413     absstp = *zabsst;
06414     relstp = *zrelst;
06415     stpmul = *zstpmu;
06416     abstol = *zabsto;
06417     reltol = *zrelto;
06418     return;
06419 S300:
06420 /*
06421      TO GET-FUNCTION-VALUE
06422 */
06423     *status = 1;
06424     return;
06425 S310:
06426     switch((int)i99999){case 1: goto S10;case 2: goto S20;case 3: goto S90;case
06427       4: goto S130;case 5: goto S200;case 6: goto S270;default: break;}
06428 #undef qxmon
06429 } /* END */
06430 
06431 /***=====================================================================***/
06432 static void dinvr(int *status,double *x,double *fx,
06433            unsigned long *qleft,unsigned long *qhi)
06434 /*
06435 **********************************************************************
06436 
06437      void dinvr(int *status,double *x,double *fx,
06438            unsigned long *qleft,unsigned long *qhi)
06439 
06440           Double precision
06441           bounds the zero of the function and invokes zror
06442                     Reverse Communication
06443 
06444 
06445                               Function
06446 
06447 
06448      Bounds the    function  and  invokes  ZROR   to perform the   zero
06449      finding.  STINVR  must  have   been  called  before this   routine
06450      in order to set its parameters.
06451 
06452 
06453                               Arguments
06454 
06455 
06456      STATUS <--> At the beginning of a zero finding problem, STATUS
06457                  should be set to 0 and INVR invoked.  (The value
06458                  of parameters other than X will be ignored on this cal
06459 
06460                  When INVR needs the function evaluated, it will set
06461                  STATUS to 1 and return.  The value of the function
06462                  should be set in FX and INVR again called without
06463                  changing any of its other parameters.
06464 
06465                  When INVR has finished without error, it will return
06466                  with STATUS 0.  In that case X is approximately a root
06467                  of F(X).
06468 
06469                  If INVR cannot bound the function, it returns status
06470                  -1 and sets QLEFT and QHI.
06471                          INTEGER STATUS
06472 
06473      X <-- The value of X at which F(X) is to be evaluated.
06474                          DOUBLE PRECISION X
06475 
06476      FX --> The value of F(X) calculated when INVR returns with
06477             STATUS = 1.
06478                          DOUBLE PRECISION FX
06479 
06480      QLEFT <-- Defined only if QMFINV returns .FALSE.  In that
06481           case it is .TRUE. If the stepping search terminated
06482           unsucessfully at SMALL.  If it is .FALSE. the search
06483           terminated unsucessfully at BIG.
06484                     QLEFT is LOGICAL
06485 
06486      QHI <-- Defined only if QMFINV returns .FALSE.  In that
06487           case it is .TRUE. if F(X) .GT. Y at the termination
06488           of the search and .FALSE. if F(X) .LT. Y at the
06489           termination of the search.
06490                     QHI is LOGICAL
06491 
06492 **********************************************************************
06493 */
06494 {
06495     E0000(0,status,x,fx,qleft,qhi,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
06496 } /* END */
06497 
06498 /***=====================================================================***/
06499 static void dstinv(double *zsmall,double *zbig,double *zabsst,
06500             double *zrelst,double *zstpmu,double *zabsto,
06501             double *zrelto)
06502 /*
06503 **********************************************************************
06504       void dstinv(double *zsmall,double *zbig,double *zabsst,
06505             double *zrelst,double *zstpmu,double *zabsto,
06506             double *zrelto)
06507 
06508       Double Precision - SeT INverse finder - Reverse Communication
06509                               Function
06510      Concise Description - Given a monotone function F finds X
06511      such that F(X) = Y.  Uses Reverse communication -- see invr.
06512      This routine sets quantities needed by INVR.
06513           More Precise Description of INVR -
06514      F must be a monotone function, the results of QMFINV are
06515      otherwise undefined.  QINCR must be .TRUE. if F is non-
06516      decreasing and .FALSE. if F is non-increasing.
06517      QMFINV will return .TRUE. if and only if F(SMALL) and
06518      F(BIG) bracket Y, i. e.,
06519           QINCR is .TRUE. and F(SMALL).LE.Y.LE.F(BIG) or
06520           QINCR is .FALSE. and F(BIG).LE.Y.LE.F(SMALL)
06521      if QMFINV returns .TRUE., then the X returned satisfies
06522      the following condition.  let
06523                TOL(X) = MAX(ABSTOL,RELTOL*ABS(X))
06524      then if QINCR is .TRUE.,
06525           F(X-TOL(X)) .LE. Y .LE. F(X+TOL(X))
06526      and if QINCR is .FALSE.
06527           F(X-TOL(X)) .GE. Y .GE. F(X+TOL(X))
06528                               Arguments
06529      SMALL --> The left endpoint of the interval to be
06530           searched for a solution.
06531                     SMALL is DOUBLE PRECISION
06532      BIG --> The right endpoint of the interval to be
06533           searched for a solution.
06534                     BIG is DOUBLE PRECISION
06535      ABSSTP, RELSTP --> The initial step size in the search
06536           is MAX(ABSSTP,RELSTP*ABS(X)). See algorithm.
06537                     ABSSTP is DOUBLE PRECISION
06538                     RELSTP is DOUBLE PRECISION
06539      STPMUL --> When a step doesn't bound the zero, the step
06540                 size is multiplied by STPMUL and another step
06541                 taken.  A popular value is 2.0
06542                     DOUBLE PRECISION STPMUL
06543      ABSTOL, RELTOL --> Two numbers that determine the accuracy
06544           of the solution.  See function for a precise definition.
06545                     ABSTOL is DOUBLE PRECISION
06546                     RELTOL is DOUBLE PRECISION
06547                               Method
06548      Compares F(X) with Y for the input value of X then uses QINCR
06549      to determine whether to step left or right to bound the
06550      desired x.  the initial step size is
06551           MAX(ABSSTP,RELSTP*ABS(S)) for the input value of X.
06552      Iteratively steps right or left until it bounds X.
06553      At each step which doesn't bound X, the step size is doubled.
06554      The routine is careful never to step beyond SMALL or BIG.  If
06555      it hasn't bounded X at SMALL or BIG, QMFINV returns .FALSE.
06556      after setting QLEFT and QHI.
06557      If X is successfully bounded then Algorithm R of the paper
06558      'Two Efficient Algorithms with Guaranteed Convergence for
06559      Finding a Zero of a Function' by J. C. P. Bus and
06560      T. J. Dekker in ACM Transactions on Mathematical
06561      Software, Volume 1, No. 4 page 330 (DEC. '75) is employed
06562      to find the zero of the function F(X)-Y. This is routine
06563      QRZERO.
06564 **********************************************************************
06565 */
06566 {
06567     E0000(1,NULL,NULL,NULL,NULL,NULL,zabsst,zabsto,zbig,zrelst,zrelto,zsmall,
06568     zstpmu);
06569 } /* END */
06570 
06571 /***=====================================================================***/
06572 static double dlanor(double *x)
06573 /*
06574 **********************************************************************
06575 
06576      double dlanor(double *x)
06577            Double precision Logarith of the Asymptotic Normal
06578 
06579 
06580                               Function
06581 
06582 
06583       Computes the logarithm of the cumulative normal distribution
06584       from abs( x ) to infinity for abs( x ) >= 5.
06585 
06586 
06587                               Arguments
06588 
06589 
06590       X --> Value at which cumulative normal to be evaluated
06591                      DOUBLE PRECISION X
06592 
06593 
06594                               Method
06595 
06596 
06597       23 term expansion of formula 26.2.12 of Abramowitz and Stegun.
06598       The relative error at X = 5 is about 0.5E-5.
06599 
06600 
06601                               Note
06602 
06603 
06604       ABS(X) must be >= 5 else there is an error stop.
06605 
06606 **********************************************************************
06607 */
06608 {
06609 #define dlsqpi 0.91893853320467274177e0
06610 static double coef[12] = {
06611     -1.0e0,3.0e0,-15.0e0,105.0e0,-945.0e0,10395.0e0,-135135.0e0,2027025.0e0,
06612     -34459425.0e0,654729075.0e0,-13749310575.e0,316234143225.0e0
06613 };
06614 static int K1 = 12;
06615 static double dlanor,approx,correc,xx,xx2,T2;
06616 /*
06617      ..
06618      .. Executable Statements ..
06619 */
06620     xx = fabs(*x);
06621     if(xx < 5.0e0){ ftnstop("Argument too small in DLANOR"); return 66.6; }
06622     approx = -dlsqpi-0.5e0*xx*xx-log(xx);
06623     xx2 = xx*xx;
06624     T2 = 1.0e0/xx2;
06625     correc = devlpl(coef,&K1,&T2)/xx2;
06626     correc = dln1px(&correc);
06627     dlanor = approx+correc;
06628     return dlanor;
06629 #undef dlsqpi
06630 } /* END */
06631 
06632 /***=====================================================================***/
06633 static double dln1mx(double *x)
06634 /*
06635 **********************************************************************
06636 
06637      double dln1mx(double *x)
06638                Double precision LN(1-X)
06639 
06640 
06641                               Function
06642 
06643 
06644      Returns ln(1-x) for small x (good accuracy if x .le. 0.1).
06645      Note that the obvious code of
06646                LOG(1.0-X)
06647      won't work for small X because 1.0-X loses accuracy
06648 
06649 
06650                               Arguments
06651 
06652 
06653      X --> Value for which ln(1-x) is desired.
06654                                         X is DOUBLE PRECISION
06655 
06656 
06657                               Method
06658 
06659 
06660      If X > 0.1, the obvious code above is used ELSE
06661      The Taylor series for 1-x is expanded to 20 terms.
06662 
06663 **********************************************************************
06664 */
06665 {
06666 static double dln1mx,T1;
06667 /*
06668      ..
06669      .. Executable Statements ..
06670 */
06671     T1 = -*x;
06672     dln1mx = dln1px(&T1);
06673     return dln1mx;
06674 } /* END */
06675 
06676 /***=====================================================================***/
06677 static double dln1px(double *a)
06678 /*
06679 **********************************************************************
06680 
06681      double dln1px(double *a)
06682                Double precision LN(1+X)
06683 
06684 
06685                               Function
06686 
06687 
06688      Returns ln(1+x)
06689      Note that the obvious code of
06690                LOG(1.0+X)
06691      won't work for small X because 1.0+X loses accuracy
06692 
06693 
06694                               Arguments
06695 
06696 
06697      X --> Value for which ln(1-x) is desired.
06698                                         X is DOUBLE PRECISION
06699 
06700 
06701                               Method
06702 
06703 
06704      Renames ALNREL from:
06705      DiDinato, A. R. and Morris,  A.   H.  Algorithm 708: Significant
06706      Digit Computation of the Incomplete  Beta  Function Ratios.  ACM
06707      Trans. Math.  Softw. 18 (1993), 360-373.
06708 
06709 **********************************************************************
06710 -----------------------------------------------------------------------
06711             EVALUATION OF THE FUNCTION LN(1 + A)
06712 -----------------------------------------------------------------------
06713 */
06714 {
06715 static double p1 = -.129418923021993e+01;
06716 static double p2 = .405303492862024e+00;
06717 static double p3 = -.178874546012214e-01;
06718 static double q1 = -.162752256355323e+01;
06719 static double q2 = .747811014037616e+00;
06720 static double q3 = -.845104217945565e-01;
06721 static double dln1px,t,t2,w,x;
06722 /*
06723      ..
06724      .. Executable Statements ..
06725 */
06726     if(fabs(*a) > 0.375e0) goto S10;
06727     t = *a/(*a+2.0e0);
06728     t2 = t*t;
06729     w = (((p3*t2+p2)*t2+p1)*t2+1.0e0)/(((q3*t2+q2)*t2+q1)*t2+1.0e0);
06730     dln1px = 2.0e0*t*w;
06731     return dln1px;
06732 S10:
06733     x = 1.e0+*a;
06734     dln1px = log(x);
06735     return dln1px;
06736 } /* END */
06737 
06738 /***=====================================================================***/
06739 static double dlnbet(double *a0,double *b0)
06740 /*
06741 **********************************************************************
06742 
06743      double dlnbet(a0,b0)
06744           Double precision LN of the complete BETa
06745 
06746 
06747                               Function
06748 
06749 
06750      Returns the natural log of the complete beta function,
06751      i.e.,
06752 
06753                   ln( Gamma(a)*Gamma(b) / Gamma(a+b)
06754 
06755 
06756                               Arguments
06757 
06758 
06759    A,B --> The (symmetric) arguments to the complete beta
06760                   DOUBLE PRECISION A, B
06761 
06762 
06763                               Method
06764 
06765 
06766      Renames BETALN from:
06767      DiDinato, A. R. and Morris,  A.   H.  Algorithm 708: Significant
06768      Digit Computation of the Incomplete  Beta  Function Ratios.  ACM
06769      Trans. Math.  Softw. 18 (1993), 360-373.
06770 
06771 **********************************************************************
06772 -----------------------------------------------------------------------
06773      EVALUATION OF THE LOGARITHM OF THE BETA FUNCTION
06774 -----------------------------------------------------------------------
06775      E = 0.5*LN(2*PI)
06776 --------------------------
06777 */
06778 {
06779 static double e = .918938533204673e0;
06780 static double dlnbet,a,b,c,h,u,v,w,z;
06781 static int i,n;
06782 static double T1;
06783 /*
06784      ..
06785      .. Executable Statements ..
06786 */
06787     a = fifdmin1(*a0,*b0);
06788     b = fifdmax1(*a0,*b0);
06789     if(a >= 8.0e0) goto S100;
06790     if(a >= 1.0e0) goto S20;
06791 /*
06792 -----------------------------------------------------------------------
06793                    PROCEDURE WHEN A .LT. 1
06794 -----------------------------------------------------------------------
06795 */
06796     if(b >= 8.0e0) goto S10;
06797     T1 = a+b;
06798     dlnbet = gamln(&a)+(gamln(&b)-gamln(&T1));
06799     return dlnbet;
06800 S10:
06801     dlnbet = gamln(&a)+algdiv(&a,&b);
06802     return dlnbet;
06803 S20:
06804 /*
06805 -----------------------------------------------------------------------
06806                 PROCEDURE WHEN 1 .LE. A .LT. 8
06807 -----------------------------------------------------------------------
06808 */
06809     if(a > 2.0e0) goto S40;
06810     if(b > 2.0e0) goto S30;
06811     dlnbet = gamln(&a)+gamln(&b)-gsumln(&a,&b);
06812     return dlnbet;
06813 S30:
06814     w = 0.0e0;
06815     if(b < 8.0e0) goto S60;
06816     dlnbet = gamln(&a)+algdiv(&a,&b);
06817     return dlnbet;
06818 S40:
06819 /*
06820                 REDUCTION OF A WHEN B .LE. 1000
06821 */
06822     if(b > 1000.0e0) goto S80;
06823     n = a-1.0e0;
06824     w = 1.0e0;
06825     for(i=1; i<=n; i++) {
06826         a -= 1.0e0;
06827         h = a/b;
06828         w *= (h/(1.0e0+h));
06829     }
06830     w = log(w);
06831     if(b < 8.0e0) goto S60;
06832     dlnbet = w+gamln(&a)+algdiv(&a,&b);
06833     return dlnbet;
06834 S60:
06835 /*
06836                  REDUCTION OF B WHEN B .LT. 8
06837 */
06838     n = b-1.0e0;
06839     z = 1.0e0;
06840     for(i=1; i<=n; i++) {
06841         b -= 1.0e0;
06842         z *= (b/(a+b));
06843     }
06844     dlnbet = w+log(z)+(gamln(&a)+(gamln(&b)-gsumln(&a,&b)));
06845     return dlnbet;
06846 S80:
06847 /*
06848                 REDUCTION OF A WHEN B .GT. 1000
06849 */
06850     n = a-1.0e0;
06851     w = 1.0e0;
06852     for(i=1; i<=n; i++) {
06853         a -= 1.0e0;
06854         w *= (a/(1.0e0+a/b));
06855     }
06856     dlnbet = log(w)-(double)n*log(b)+(gamln(&a)+algdiv(&a,&b));
06857     return dlnbet;
06858 S100:
06859 /*
06860 -----------------------------------------------------------------------
06861                    PROCEDURE WHEN A .GE. 8
06862 -----------------------------------------------------------------------
06863 */
06864     w = bcorr(&a,&b);
06865     h = a/b;
06866     c = h/(1.0e0+h);
06867     u = -((a-0.5e0)*log(c));
06868     v = b*alnrel(&h);
06869     if(u <= v) goto S110;
06870     dlnbet = -(0.5e0*log(b))+e+w-v-u;
06871     return dlnbet;
06872 S110:
06873     dlnbet = -(0.5e0*log(b))+e+w-u-v;
06874     return dlnbet;
06875 } /* END */
06876 
06877 /***=====================================================================***/
06878 static double dlngam(double *a)
06879 /*
06880 **********************************************************************
06881 
06882      double dlngam(double *a)
06883                  Double precision LN of the GAMma function
06884 
06885 
06886                               Function
06887 
06888 
06889      Returns the natural logarithm of GAMMA(X).
06890 
06891 
06892                               Arguments
06893 
06894 
06895      X --> value at which scaled log gamma is to be returned
06896                     X is DOUBLE PRECISION
06897 
06898 
06899                               Method
06900 
06901 
06902      Renames GAMLN from:
06903      DiDinato, A. R. and Morris,  A.   H.  Algorithm 708: Significant
06904      Digit Computation of the Incomplete  Beta  Function Ratios.  ACM
06905      Trans. Math.  Softw. 18 (1993), 360-373.
06906 
06907 **********************************************************************
06908 -----------------------------------------------------------------------
06909             EVALUATION OF LN(GAMMA(A)) FOR POSITIVE A
06910 -----------------------------------------------------------------------
06911      WRITTEN BY ALFRED H. MORRIS
06912           NAVAL SURFACE WARFARE CENTER
06913           DAHLGREN, VIRGINIA
06914 --------------------------
06915      D = 0.5*(LN(2*PI) - 1)
06916 --------------------------
06917 */
06918 {
06919 static double c0 = .833333333333333e-01;
06920 static double c1 = -.277777777760991e-02;
06921 static double c2 = .793650666825390e-03;
06922 static double c3 = -.595202931351870e-03;
06923 static double c4 = .837308034031215e-03;
06924 static double c5 = -.165322962780713e-02;
06925 static double d = .418938533204673e0;
06926 static double dlngam,t,w;
06927 static int i,n;
06928 static double T1;
06929 /*
06930      ..
06931      .. Executable Statements ..
06932 */
06933     if(*a > 0.8e0) goto S10;
06934     dlngam = gamln1(a)-log(*a);
06935     return dlngam;
06936 S10:
06937     if(*a > 2.25e0) goto S20;
06938     t = *a-0.5e0-0.5e0;
06939     dlngam = gamln1(&t);
06940     return dlngam;
06941 S20:
06942     if(*a >= 10.0e0) goto S40;
06943     n = *a-1.25e0;
06944     t = *a;
06945     w = 1.0e0;
06946     for(i=1; i<=n; i++) {
06947         t -= 1.0e0;
06948         w = t*w;
06949     }
06950     T1 = t-1.0e0;
06951     dlngam = gamln1(&T1)+log(w);
06952     return dlngam;
06953 S40:
06954     t = pow(1.0e0/ *a,2.0);
06955     w = (((((c5*t+c4)*t+c3)*t+c2)*t+c1)*t+c0)/ *a;
06956     dlngam = d+w+(*a-0.5e0)*(log(*a)-1.0e0);
06957     return dlngam;
06958 } /* END */
06959 
06960 /***=====================================================================***/
06961 static double dstrem(double *z)
06962 {
06963 /*
06964 **********************************************************************
06965      double dstrem(double *z)
06966              Double precision Sterling Remainder
06967                               Function
06968      Returns   Log(Gamma(Z))  -  Sterling(Z)  where   Sterling(Z)  is
06969      Sterling's Approximation to Log(Gamma(Z))
06970      Sterling(Z) = LOG( SQRT( 2*PI ) ) + ( Z-0.5 ) * LOG( Z ) - Z
06971                               Arguments
06972      Z --> Value at which Sterling remainder calculated
06973            Must be positive.
06974                   DOUBLE PRECISION Z
06975                               Method
06976      If Z >= 6 uses 9 terms of series in Bernoulli numbers
06977      (Values calculated using Maple)
06978      Otherwise computes difference explicitly
06979 **********************************************************************
06980 */
06981 #define hln2pi 0.91893853320467274178e0
06982 #define ncoef 10
06983 static double coef[ncoef] = {
06984     0.0e0,0.0833333333333333333333333333333e0,
06985     -0.00277777777777777777777777777778e0,0.000793650793650793650793650793651e0,
06986     -0.000595238095238095238095238095238e0,
06987     0.000841750841750841750841750841751e0,-0.00191752691752691752691752691753e0,
06988     0.00641025641025641025641025641026e0,-0.0295506535947712418300653594771e0,
06989     0.179644372368830573164938490016e0
06990 };
06991 static int K1 = 10;
06992 static double dstrem,sterl,T2;
06993 /*
06994      ..
06995      .. Executable Statements ..
06996 */
06997 /*
06998     For information, here are the next 11 coefficients of the
06999     remainder term in Sterling's formula
07000             -1.39243221690590111642743221691
07001             13.4028640441683919944789510007
07002             -156.848284626002017306365132452
07003             2193.10333333333333333333333333
07004             -36108.7712537249893571732652192
07005             691472.268851313067108395250776
07006             -0.152382215394074161922833649589D8
07007             0.382900751391414141414141414141D9
07008             -0.108822660357843910890151491655D11
07009             0.347320283765002252252252252252D12
07010             -0.123696021422692744542517103493D14
07011 */
07012     if(*z <= 0.0e0){ ftnstop("nonpositive argument in DSTREM"); return 66.6; }
07013     if(!(*z > 6.0e0)) goto S10;
07014     T2 = 1.0e0/pow(*z,2.0);
07015     dstrem = devlpl(coef,&K1,&T2)**z;
07016     goto S20;
07017 S10:
07018     sterl = hln2pi+(*z-0.5e0)*log(*z)-*z;
07019     dstrem = dlngam(z)-sterl;
07020 S20:
07021     return dstrem;
07022 #undef hln2pi
07023 #undef ncoef
07024 } /* END */
07025 
07026 /***=====================================================================***/
07027 static double dt1(double *p,double *q,double *df)
07028 /*
07029 **********************************************************************
07030 
07031      double dt1(double *p,double *q,double *df)
07032      Double precision Initalize Approximation to
07033            INVerse of the cumulative T distribution
07034 
07035 
07036                               Function
07037 
07038 
07039      Returns  the  inverse   of  the T   distribution   function, i.e.,
07040      the integral from 0 to INVT of the T density is P. This is an
07041      initial approximation
07042 
07043 
07044                               Arguments
07045 
07046 
07047      P --> The p-value whose inverse from the T distribution is
07048           desired.
07049                     P is DOUBLE PRECISION
07050 
07051      Q --> 1-P.
07052                     Q is DOUBLE PRECISION
07053 
07054      DF --> Degrees of freedom of the T distribution.
07055                     DF is DOUBLE PRECISION
07056 
07057 **********************************************************************
07058 */
07059 {
07060 static double coef[4][5] = {
07061     1.0e0,1.0e0,0.0e0,0.0e0,0.0e0,3.0e0,16.0e0,5.0e0,0.0e0,0.0e0,-15.0e0,17.0e0,
07062     19.0e0,3.0e0,0.0e0,-945.0e0,-1920.0e0,1482.0e0,776.0e0,79.0e0
07063 };
07064 static double denom[4] = {
07065     4.0e0,96.0e0,384.0e0,92160.0e0
07066 };
07067 static int ideg[4] = {
07068     2,3,4,5
07069 };
07070 static double dt1,denpow,sum,term,x,xp,xx;
07071 static int i;
07072 /*
07073      ..
07074      .. Executable Statements ..
07075 */
07076     x = fabs(dinvnr(p,q));
07077     xx = x*x;
07078     sum = x;
07079     denpow = 1.0e0;
07080     for(i=0; i<4; i++) {
07081         term = devlpl(&coef[i][0],&ideg[i],&xx)*x;
07082         denpow *= *df;
07083         sum += (term/(denpow*denom[i]));
07084     }
07085     if(!(*p >= 0.5e0)) goto S20;
07086     xp = sum;
07087     goto S30;
07088 S20:
07089     xp = -sum;
07090 S30:
07091     dt1 = xp;
07092     return dt1;
07093 } /* END */
07094 
07095 /***=====================================================================***/
07096 static void E0001(int IENTRY,int *status,double *x,double *fx,
07097                   double *xlo,double *xhi,unsigned long *qleft,
07098                   unsigned long *qhi,double *zabstl,double *zreltl,
07099                   double *zxhi,double *zxlo)
07100 {
07101 #define ftol(zx) (0.5e0*fifdmax1(abstol,reltol*fabs((zx))))
07102 static double a,abstol,b,c,d,fa,fb,fc,fd,fda,fdb,m,mb,p,q,reltol,tol,w,xxhi,xxlo;
07103 static int ext,i99999;
07104 static unsigned long first,qrzero;
07105     switch(IENTRY){case 0: goto DZROR; case 1: goto DSTZR;}
07106 DZROR:
07107     if(*status > 0) goto S280;
07108     *xlo = xxlo;
07109     *xhi = xxhi;
07110     b = *x = *xlo;
07111 /*
07112      GET-FUNCTION-VALUE
07113 */
07114     i99999 = 1;
07115     goto S270;
07116 S10:
07117     fb = *fx;
07118     *xlo = *xhi;
07119     a = *x = *xlo;
07120 /*
07121      GET-FUNCTION-VALUE
07122 */
07123     i99999 = 2;
07124     goto S270;
07125 S20:
07126 /*
07127      Check that F(ZXLO) < 0 < F(ZXHI)  or
07128                 F(ZXLO) > 0 > F(ZXHI)
07129 */
07130     if(!(fb < 0.0e0)) goto S40;
07131     if(!(*fx < 0.0e0)) goto S30;
07132     *status = -1;
07133     *qleft = *fx < fb;
07134     *qhi = 0;
07135     return;
07136 S40:
07137 S30:
07138     if(!(fb > 0.0e0)) goto S60;
07139     if(!(*fx > 0.0e0)) goto S50;
07140     *status = -1;
07141     *qleft = *fx > fb;
07142     *qhi = 1;
07143     return;
07144 S60:
07145 S50:
07146     fa = *fx;
07147     first = 1;
07148 S70:
07149     c = a;
07150     fc = fa;
07151     ext = 0;
07152 S80:
07153     if(!(fabs(fc) < fabs(fb))) goto S100;
07154     if(!(c != a)) goto S90;
07155     d = a;
07156     fd = fa;
07157 S90:
07158     a = b;
07159     fa = fb;
07160     *xlo = c;
07161     b = *xlo;
07162     fb = fc;
07163     c = a;
07164     fc = fa;
07165 S100:
07166     tol = ftol(*xlo);
07167     m = (c+b)*.5e0;
07168     mb = m-b;
07169     if(!(fabs(mb) > tol)) goto S240;
07170     if(!(ext > 3)) goto S110;
07171     w = mb;
07172     goto S190;
07173 S110:
07174     tol = fifdsign(tol,mb);
07175     p = (b-a)*fb;
07176     if(!first) goto S120;
07177     q = fa-fb;
07178     first = 0;
07179     goto S130;
07180 S120:
07181     fdb = (fd-fb)/(d-b);
07182     fda = (fd-fa)/(d-a);
07183     p = fda*p;
07184     q = fdb*fa-fda*fb;
07185 S130:
07186     if(!(p < 0.0e0)) goto S140;
07187     p = -p;
07188     q = -q;
07189 S140:
07190     if(ext == 3) p *= 2.0e0;
07191     if(!(p*1.0e0 == 0.0e0 || p <= q*tol)) goto S150;
07192     w = tol;
07193     goto S180;
07194 S150:
07195     if(!(p < mb*q)) goto S160;
07196     w = p/q;
07197     goto S170;
07198 S160:
07199     w = mb;
07200 S190:
07201 S180:
07202 S170:
07203     d = a;
07204     fd = fa;
07205     a = b;
07206     fa = fb;
07207     b += w;
07208     *xlo = b;
07209     *x = *xlo;
07210 /*
07211      GET-FUNCTION-VALUE
07212 */
07213     i99999 = 3;
07214     goto S270;
07215 S200:
07216     fb = *fx;
07217     if(!(fc*fb >= 0.0e0)) goto S210;
07218     goto S70;
07219 S210:
07220     if(!(w == mb)) goto S220;
07221     ext = 0;
07222     goto S230;
07223 S220:
07224     ext += 1;
07225 S230:
07226     goto S80;
07227 S240:
07228     *xhi = c;
07229     qrzero = fc >= 0.0e0 && fb <= 0.0e0 || fc < 0.0e0 && fb >= 0.0e0;
07230     if(!qrzero) goto S250;
07231     *status = 0;
07232     goto S260;
07233 S250:
07234     *status = -1;
07235 S260:
07236     return;
07237 DSTZR:
07238     xxlo = *zxlo;
07239     xxhi = *zxhi;
07240     abstol = *zabstl;
07241     reltol = *zreltl;
07242     return;
07243 S270:
07244 /*
07245      TO GET-FUNCTION-VALUE
07246 */
07247     *status = 1;
07248     return;
07249 S280:
07250     switch((int)i99999){case 1: goto S10;case 2: goto S20;case 3: goto S200;
07251       default: break;}
07252 #undef ftol
07253 } /* END */
07254 
07255 /***=====================================================================***/
07256 static void dzror(int *status,double *x,double *fx,double *xlo,
07257            double *xhi,unsigned long *qleft,unsigned long *qhi)
07258 /*
07259 **********************************************************************
07260 
07261      void dzror(int *status,double *x,double *fx,double *xlo,
07262            double *xhi,unsigned long *qleft,unsigned long *qhi)
07263 
07264      Double precision ZeRo of a function -- Reverse Communication
07265 
07266 
07267                               Function
07268 
07269 
07270      Performs the zero finding.  STZROR must have been called before
07271      this routine in order to set its parameters.
07272 
07273 
07274                               Arguments
07275 
07276 
07277      STATUS <--> At the beginning of a zero finding problem, STATUS
07278                  should be set to 0 and ZROR invoked.  (The value
07279                  of other parameters will be ignored on this call.)
07280 
07281                  When ZROR needs the function evaluated, it will set
07282                  STATUS to 1 and return.  The value of the function
07283                  should be set in FX and ZROR again called without
07284                  changing any of its other parameters.
07285 
07286                  When ZROR has finished without error, it will return
07287                  with STATUS 0.  In that case (XLO,XHI) bound the answe
07288 
07289                  If ZROR finds an error (which implies that F(XLO)-Y an
07290                  F(XHI)-Y have the same sign, it returns STATUS -1.  In
07291                  this case, XLO and XHI are undefined.
07292                          INTEGER STATUS
07293 
07294      X <-- The value of X at which F(X) is to be evaluated.
07295                          DOUBLE PRECISION X
07296 
07297      FX --> The value of F(X) calculated when ZROR returns with
07298             STATUS = 1.
07299                          DOUBLE PRECISION FX
07300 
07301      XLO <-- When ZROR returns with STATUS = 0, XLO bounds the
07302              inverval in X containing the solution below.
07303                          DOUBLE PRECISION XLO
07304 
07305      XHI <-- When ZROR returns with STATUS = 0, XHI bounds the
07306              inverval in X containing the solution above.
07307                          DOUBLE PRECISION XHI
07308 
07309      QLEFT <-- .TRUE. if the stepping search terminated unsucessfully
07310                 at XLO.  If it is .FALSE. the search terminated
07311                 unsucessfully at XHI.
07312                     QLEFT is LOGICAL
07313 
07314      QHI <-- .TRUE. if F(X) .GT. Y at the termination of the
07315               search and .FALSE. if F(X) .LT. Y at the
07316               termination of the search.
07317                     QHI is LOGICAL
07318 
07319 **********************************************************************
07320 */
07321 {
07322     E0001(0,status,x,fx,xlo,xhi,qleft,qhi,NULL,NULL,NULL,NULL);
07323 } /* END */
07324 
07325 /***=====================================================================***/
07326 static void dstzr(double *zxlo,double *zxhi,double *zabstl,double *zreltl)
07327 /*
07328 **********************************************************************
07329      void dstzr(double *zxlo,double *zxhi,double *zabstl,double *zreltl)
07330      Double precision SeT ZeRo finder - Reverse communication version
07331                               Function
07332      Sets quantities needed by ZROR.  The function of ZROR
07333      and the quantities set is given here.
07334      Concise Description - Given a function F
07335      find XLO such that F(XLO) = 0.
07336           More Precise Description -
07337      Input condition. F is a double precision function of a single
07338      double precision argument and XLO and XHI are such that
07339           F(XLO)*F(XHI)  .LE.  0.0
07340      If the input condition is met, QRZERO returns .TRUE.
07341      and output values of XLO and XHI satisfy the following
07342           F(XLO)*F(XHI)  .LE. 0.
07343           ABS(F(XLO)  .LE. ABS(F(XHI)
07344           ABS(XLO-XHI)  .LE. TOL(X)
07345      where
07346           TOL(X) = MAX(ABSTOL,RELTOL*ABS(X))
07347      If this algorithm does not find XLO and XHI satisfying
07348      these conditions then QRZERO returns .FALSE.  This
07349      implies that the input condition was not met.
07350                               Arguments
07351      XLO --> The left endpoint of the interval to be
07352            searched for a solution.
07353                     XLO is DOUBLE PRECISION
07354      XHI --> The right endpoint of the interval to be
07355            for a solution.
07356                     XHI is DOUBLE PRECISION
07357      ABSTOL, RELTOL --> Two numbers that determine the accuracy
07358                       of the solution.  See function for a
07359                       precise definition.
07360                     ABSTOL is DOUBLE PRECISION
07361                     RELTOL is DOUBLE PRECISION
07362                               Method
07363      Algorithm R of the paper 'Two Efficient Algorithms with
07364      Guaranteed Convergence for Finding a Zero of a Function'
07365      by J. C. P. Bus and T. J. Dekker in ACM Transactions on
07366      Mathematical Software, Volume 1, no. 4 page 330
07367      (Dec. '75) is employed to find the zero of F(X)-Y.
07368 **********************************************************************
07369 */
07370 {
07371     E0001(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,zabstl,zreltl,zxhi,zxlo);
07372 } /* END */
07373 
07374 /***=====================================================================***/
07375 static double erf1(double *x)
07376 /*
07377 -----------------------------------------------------------------------
07378              EVALUATION OF THE REAL ERROR FUNCTION
07379 -----------------------------------------------------------------------
07380 */
07381 {
07382 static double c = .564189583547756e0;
07383 static double a[5] = {
07384     .771058495001320e-04,-.133733772997339e-02,.323076579225834e-01,
07385     .479137145607681e-01,.128379167095513e+00
07386 };
07387 static double b[3] = {
07388     .301048631703895e-02,.538971687740286e-01,.375795757275549e+00
07389 };
07390 static double p[8] = {
07391     -1.36864857382717e-07,5.64195517478974e-01,7.21175825088309e+00,
07392     4.31622272220567e+01,1.52989285046940e+02,3.39320816734344e+02,
07393     4.51918953711873e+02,3.00459261020162e+02
07394 };
07395 static double q[8] = {
07396     1.00000000000000e+00,1.27827273196294e+01,7.70001529352295e+01,
07397     2.77585444743988e+02,6.38980264465631e+02,9.31354094850610e+02,
07398     7.90950925327898e+02,3.00459260956983e+02
07399 };
07400 static double r[5] = {
07401     2.10144126479064e+00,2.62370141675169e+01,2.13688200555087e+01,
07402     4.65807828718470e+00,2.82094791773523e-01
07403 };
07404 static double s[4] = {
07405     9.41537750555460e+01,1.87114811799590e+02,9.90191814623914e+01,
07406     1.80124575948747e+01
07407 };
07408 static double erf1,ax,bot,t,top,x2;
07409 /*
07410      ..
07411      .. Executable Statements ..
07412 */
07413     ax = fabs(*x);
07414     if(ax > 0.5e0) goto S10;
07415     t = *x**x;
07416     top = (((a[0]*t+a[1])*t+a[2])*t+a[3])*t+a[4]+1.0e0;
07417     bot = ((b[0]*t+b[1])*t+b[2])*t+1.0e0;
07418     erf1 = *x*(top/bot);
07419     return erf1;
07420 S10:
07421     if(ax > 4.0e0) goto S20;
07422     top = ((((((p[0]*ax+p[1])*ax+p[2])*ax+p[3])*ax+p[4])*ax+p[5])*ax+p[6])*ax+p[
07423       7];
07424     bot = ((((((q[0]*ax+q[1])*ax+q[2])*ax+q[3])*ax+q[4])*ax+q[5])*ax+q[6])*ax+q[
07425       7];
07426     erf1 = 0.5e0+(0.5e0-exp(-(*x**x))*top/bot);
07427     if(*x < 0.0e0) erf1 = -erf1;
07428     return erf1;
07429 S20:
07430     if(ax >= 5.8e0) goto S30;
07431     x2 = *x**x;
07432     t = 1.0e0/x2;
07433     top = (((r[0]*t+r[1])*t+r[2])*t+r[3])*t+r[4];
07434     bot = (((s[0]*t+s[1])*t+s[2])*t+s[3])*t+1.0e0;
07435     erf1 = (c-top/(x2*bot))/ax;
07436     erf1 = 0.5e0+(0.5e0-exp(-x2)*erf1);
07437     if(*x < 0.0e0) erf1 = -erf1;
07438     return erf1;
07439 S30:
07440     erf1 = fifdsign(1.0e0,*x);
07441     return erf1;
07442 } /* END */
07443 
07444 /***=====================================================================***/
07445 static double erfc1(int *ind,double *x)
07446 /*
07447 -----------------------------------------------------------------------
07448          EVALUATION OF THE COMPLEMENTARY ERROR FUNCTION
07449 
07450           ERFC1(IND,X) = ERFC(X)            IF IND = 0
07451           ERFC1(IND,X) = EXP(X*X)*ERFC(X)   OTHERWISE
07452 -----------------------------------------------------------------------
07453 */
07454 {
07455 static double c = .564189583547756e0;
07456 static double a[5] = {
07457     .771058495001320e-04,-.133733772997339e-02,.323076579225834e-01,
07458     .479137145607681e-01,.128379167095513e+00
07459 };
07460 static double b[3] = {
07461     .301048631703895e-02,.538971687740286e-01,.375795757275549e+00
07462 };
07463 static double p[8] = {
07464     -1.36864857382717e-07,5.64195517478974e-01,7.21175825088309e+00,
07465     4.31622272220567e+01,1.52989285046940e+02,3.39320816734344e+02,
07466     4.51918953711873e+02,3.00459261020162e+02
07467 };
07468 static double q[8] = {
07469     1.00000000000000e+00,1.27827273196294e+01,7.70001529352295e+01,
07470     2.77585444743988e+02,6.38980264465631e+02,9.31354094850610e+02,
07471     7.90950925327898e+02,3.00459260956983e+02
07472 };
07473 static double r[5] = {
07474     2.10144126479064e+00,2.62370141675169e+01,2.13688200555087e+01,
07475     4.65807828718470e+00,2.82094791773523e-01
07476 };
07477 static double s[4] = {
07478     9.41537750555460e+01,1.87114811799590e+02,9.90191814623914e+01,
07479     1.80124575948747e+01
07480 };
07481 static int K1 = 1;
07482 static double erfc1,ax,bot,e,t,top,w;
07483 /*
07484      ..
07485      .. Executable Statements ..
07486 */
07487 /*
07488                      ABS(X) .LE. 0.5
07489 */
07490     ax = fabs(*x);
07491     if(ax > 0.5e0) goto S10;
07492     t = *x**x;
07493     top = (((a[0]*t+a[1])*t+a[2])*t+a[3])*t+a[4]+1.0e0;
07494     bot = ((b[0]*t+b[1])*t+b[2])*t+1.0e0;
07495     erfc1 = 0.5e0+(0.5e0-*x*(top/bot));
07496     if(*ind != 0) erfc1 = exp(t)*erfc1;
07497     return erfc1;
07498 S10:
07499 /*
07500                   0.5 .LT. ABS(X) .LE. 4
07501 */
07502     if(ax > 4.0e0) goto S20;
07503     top = ((((((p[0]*ax+p[1])*ax+p[2])*ax+p[3])*ax+p[4])*ax+p[5])*ax+p[6])*ax+p[
07504       7];
07505     bot = ((((((q[0]*ax+q[1])*ax+q[2])*ax+q[3])*ax+q[4])*ax+q[5])*ax+q[6])*ax+q[
07506       7];
07507     erfc1 = top/bot;
07508     goto S40;
07509 S20:
07510 /*
07511                       ABS(X) .GT. 4
07512 */
07513     if(*x <= -5.6e0) goto S60;
07514     if(*ind != 0) goto S30;
07515     if(*x > 100.0e0) goto S70;
07516     if(*x**x > -exparg(&K1)) goto S70;
07517 S30:
07518     t = pow(1.0e0/ *x,2.0);
07519     top = (((r[0]*t+r[1])*t+r[2])*t+r[3])*t+r[4];
07520     bot = (((s[0]*t+s[1])*t+s[2])*t+s[3])*t+1.0e0;
07521     erfc1 = (c-t*top/bot)/ax;
07522 S40:
07523 /*
07524                       FINAL ASSEMBLY
07525 */
07526     if(*ind == 0) goto S50;
07527     if(*x < 0.0e0) erfc1 = 2.0e0*exp(*x**x)-erfc1;
07528     return erfc1;
07529 S50:
07530     w = *x**x;
07531     t = w;
07532     e = w-t;
07533     erfc1 = (0.5e0+(0.5e0-e))*exp(-t)*erfc1;
07534     if(*x < 0.0e0) erfc1 = 2.0e0-erfc1;
07535     return erfc1;
07536 S60:
07537 /*
07538              LIMIT VALUE FOR LARGE NEGATIVE X
07539 */
07540     erfc1 = 2.0e0;
07541     if(*ind != 0) erfc1 = 2.0e0*exp(*x**x);
07542     return erfc1;
07543 S70:
07544 /*
07545              LIMIT VALUE FOR LARGE POSITIVE X
07546                        WHEN IND = 0
07547 */
07548     erfc1 = 0.0e0;
07549     return erfc1;
07550 } /* END */
07551 
07552 /***=====================================================================***/
07553 static double esum(int *mu,double *x)
07554 /*
07555 -----------------------------------------------------------------------
07556                     EVALUATION OF EXP(MU + X)
07557 -----------------------------------------------------------------------
07558 */
07559 {
07560 static double esum,w;
07561 /*
07562      ..
07563      .. Executable Statements ..
07564 */
07565     if(*x > 0.0e0) goto S10;
07566     if(*mu < 0) goto S20;
07567     w = (double)*mu+*x;
07568     if(w > 0.0e0) goto S20;
07569     esum = exp(w);
07570     return esum;
07571 S10:
07572     if(*mu > 0) goto S20;
07573     w = (double)*mu+*x;
07574     if(w < 0.0e0) goto S20;
07575     esum = exp(w);
07576     return esum;
07577 S20:
07578     w = *mu;
07579     esum = exp(w)*exp(*x);
07580     return esum;
07581 } /* END */
07582 
07583 /***=====================================================================***/
07584 static double exparg(int *l)
07585 /*
07586 --------------------------------------------------------------------
07587      IF L = 0 THEN  EXPARG(L) = THE LARGEST POSITIVE W FOR WHICH
07588      EXP(W) CAN BE COMPUTED.
07589 
07590      IF L IS NONZERO THEN  EXPARG(L) = THE LARGEST NEGATIVE W FOR
07591      WHICH THE COMPUTED VALUE OF EXP(W) IS NONZERO.
07592 
07593      NOTE... ONLY AN APPROXIMATE VALUE FOR EXPARG(L) IS NEEDED.
07594 --------------------------------------------------------------------
07595 */
07596 {
07597 static int K1 = 4;
07598 static int K2 = 9;
07599 static int K3 = 10;
07600 static double exparg,lnb;
07601 static int b,m;
07602 /*
07603      ..
07604      .. Executable Statements ..
07605 */
07606     b = ipmpar(&K1);
07607     if(b != 2) goto S10;
07608     lnb = .69314718055995e0;
07609     goto S40;
07610 S10:
07611     if(b != 8) goto S20;
07612     lnb = 2.0794415416798e0;
07613     goto S40;
07614 S20:
07615     if(b != 16) goto S30;
07616     lnb = 2.7725887222398e0;
07617     goto S40;
07618 S30:
07619     lnb = log((double)b);
07620 S40:
07621     if(*l == 0) goto S50;
07622     m = ipmpar(&K2)-1;
07623     exparg = 0.99999e0*((double)m*lnb);
07624     return exparg;
07625 S50:
07626     m = ipmpar(&K3);
07627     exparg = 0.99999e0*((double)m*lnb);
07628     return exparg;
07629 } /* END */
07630 
07631 /***=====================================================================***/
07632 static double fpser(double *a,double *b,double *x,double *eps)
07633 /*
07634 -----------------------------------------------------------------------
07635 
07636                  EVALUATION OF I (A,B)
07637                                 X
07638 
07639           FOR B .LT. MIN(EPS,EPS*A) AND X .LE. 0.5.
07640 
07641 -----------------------------------------------------------------------
07642 
07643                   SET  FPSER = X**A
07644 */
07645 {
07646 static int K1 = 1;
07647 static double fpser,an,c,s,t,tol;
07648 /*
07649      ..
07650      .. Executable Statements ..
07651 */
07652     fpser = 1.0e0;
07653     if(*a <= 1.e-3**eps) goto S10;
07654     fpser = 0.0e0;
07655     t = *a*log(*x);
07656     if(t < exparg(&K1)) return fpser;
07657     fpser = exp(t);
07658 S10:
07659 /*
07660                 NOTE THAT 1/B(A,B) = B
07661 */
07662     fpser = *b/ *a*fpser;
07663     tol = *eps/ *a;
07664     an = *a+1.0e0;
07665     t = *x;
07666     s = t/an;
07667 S20:
07668     an += 1.0e0;
07669     t = *x*t;
07670     c = t/an;
07671     s += c;
07672     if(fabs(c) > tol) goto S20;
07673     fpser *= (1.0e0+*a*s);
07674     return fpser;
07675 } /* END */
07676 
07677 /***=====================================================================***/
07678 static double gam1(double *a)
07679 /*
07680      ------------------------------------------------------------------
07681      COMPUTATION OF 1/GAMMA(A+1) - 1  FOR -0.5 .LE. A .LE. 1.5
07682      ------------------------------------------------------------------
07683 */
07684 {
07685 static double s1 = .273076135303957e+00;
07686 static double s2 = .559398236957378e-01;
07687 static double p[7] = {
07688     .577215664901533e+00,-.409078193005776e+00,-.230975380857675e+00,
07689     .597275330452234e-01,.766968181649490e-02,-.514889771323592e-02,
07690     .589597428611429e-03
07691 };
07692 static double q[5] = {
07693     .100000000000000e+01,.427569613095214e+00,.158451672430138e+00,
07694     .261132021441447e-01,.423244297896961e-02
07695 };
07696 static double r[9] = {
07697     -.422784335098468e+00,-.771330383816272e+00,-.244757765222226e+00,
07698     .118378989872749e+00,.930357293360349e-03,-.118290993445146e-01,
07699     .223047661158249e-02,.266505979058923e-03,-.132674909766242e-03
07700 };
07701 static double gam1,bot,d,t,top,w,T1;
07702 /*
07703      ..
07704      .. Executable Statements ..
07705 */
07706     t = *a;
07707     d = *a-0.5e0;
07708     if(d > 0.0e0) t = d-0.5e0;
07709     T1 = t;
07710     if(T1 < 0) goto S40;
07711     else if(T1 == 0) goto S10;
07712     else  goto S20;
07713 S10:
07714     gam1 = 0.0e0;
07715     return gam1;
07716 S20:
07717     top = (((((p[6]*t+p[5])*t+p[4])*t+p[3])*t+p[2])*t+p[1])*t+p[0];
07718     bot = (((q[4]*t+q[3])*t+q[2])*t+q[1])*t+1.0e0;
07719     w = top/bot;
07720     if(d > 0.0e0) goto S30;
07721     gam1 = *a*w;
07722     return gam1;
07723 S30:
07724     gam1 = t/ *a*(w-0.5e0-0.5e0);
07725     return gam1;
07726 S40:
07727     top = (((((((r[8]*t+r[7])*t+r[6])*t+r[5])*t+r[4])*t+r[3])*t+r[2])*t+r[1])*t+
07728       r[0];
07729     bot = (s2*t+s1)*t+1.0e0;
07730     w = top/bot;
07731     if(d > 0.0e0) goto S50;
07732     gam1 = *a*(w+0.5e0+0.5e0);
07733     return gam1;
07734 S50:
07735     gam1 = t*w/ *a;
07736     return gam1;
07737 } /* END */
07738 
07739 /***=====================================================================***/
07740 static void gaminv(double *a,double *x,double *x0,double *p,double *q,
07741             int *ierr)
07742 /*
07743  ----------------------------------------------------------------------
07744             INVERSE INCOMPLETE GAMMA RATIO FUNCTION
07745 
07746      GIVEN POSITIVE A, AND NONEGATIVE P AND Q WHERE P + Q = 1.
07747      THEN X IS COMPUTED WHERE P(A,X) = P AND Q(A,X) = Q. SCHRODER
07748      ITERATION IS EMPLOYED. THE ROUTINE ATTEMPTS TO COMPUTE X
07749      TO 10 SIGNIFICANT DIGITS IF THIS IS POSSIBLE FOR THE
07750      PARTICULAR COMPUTER ARITHMETIC BEING USED.
07751 
07752                       ------------
07753 
07754      X IS A VARIABLE. IF P = 0 THEN X IS ASSIGNED THE VALUE 0,
07755      AND IF Q = 0 THEN X IS SET TO THE LARGEST FLOATING POINT
07756      NUMBER AVAILABLE. OTHERWISE, GAMINV ATTEMPTS TO OBTAIN
07757      A SOLUTION FOR P(A,X) = P AND Q(A,X) = Q. IF THE ROUTINE
07758      IS SUCCESSFUL THEN THE SOLUTION IS STORED IN X.
07759 
07760      X0 IS AN OPTIONAL INITIAL APPROXIMATION FOR X. IF THE USER
07761      DOES NOT WISH TO SUPPLY AN INITIAL APPROXIMATION, THEN SET
07762      X0 .LE. 0.
07763 
07764      IERR IS A VARIABLE THAT REPORTS THE STATUS OF THE RESULTS.
07765      WHEN THE ROUTINE TERMINATES, IERR HAS ONE OF THE FOLLOWING
07766      VALUES ...
07767 
07768        IERR =  0    THE SOLUTION WAS OBTAINED. ITERATION WAS
07769                     NOT USED.
07770        IERR.GT.0    THE SOLUTION WAS OBTAINED. IERR ITERATIONS
07771                     WERE PERFORMED.
07772        IERR = -2    (INPUT ERROR) A .LE. 0
07773        IERR = -3    NO SOLUTION WAS OBTAINED. THE RATIO Q/A
07774                     IS TOO LARGE.
07775        IERR = -4    (INPUT ERROR) P + Q .NE. 1
07776        IERR = -6    20 ITERATIONS WERE PERFORMED. THE MOST
07777                     RECENT VALUE OBTAINED FOR X IS GIVEN.
07778                     THIS CANNOT OCCUR IF X0 .LE. 0.
07779        IERR = -7    ITERATION FAILED. NO VALUE IS GIVEN FOR X.
07780                     THIS MAY OCCUR WHEN X IS APPROXIMATELY 0.
07781        IERR = -8    A VALUE FOR X HAS BEEN OBTAINED, BUT THE
07782                     ROUTINE IS NOT CERTAIN OF ITS ACCURACY.
07783                     ITERATION CANNOT BE PERFORMED IN THIS
07784                     CASE. IF X0 .LE. 0, THIS CAN OCCUR ONLY
07785                     WHEN P OR Q IS APPROXIMATELY 0. IF X0 IS
07786                     POSITIVE THEN THIS CAN OCCUR WHEN A IS
07787                     EXCEEDINGLY CLOSE TO X AND A IS EXTREMELY
07788                     LARGE (SAY A .GE. 1.E20).
07789  ----------------------------------------------------------------------
07790      WRITTEN BY ALFRED H. MORRIS, JR.
07791         NAVAL SURFACE WEAPONS CENTER
07792         DAHLGREN, VIRGINIA
07793      -------------------
07794 */
07795 {
07796 static double a0 = 3.31125922108741e0;
07797 static double a1 = 11.6616720288968e0;
07798 static double a2 = 4.28342155967104e0;
07799 static double a3 = .213623493715853e0;
07800 static double b1 = 6.61053765625462e0;
07801 static double b2 = 6.40691597760039e0;
07802 static double b3 = 1.27364489782223e0;
07803 static double b4 = .036117081018842e0;
07804 static double c = .577215664901533e0;
07805 static double ln10 = 2.302585e0;
07806 static double tol = 1.e-5;
07807 static double amin[2] = {
07808     500.0e0,100.0e0
07809 };
07810 static double bmin[2] = {
07811     1.e-28,1.e-13
07812 };
07813 static double dmin[2] = {
07814     1.e-06,1.e-04
07815 };
07816 static double emin[2] = {
07817     2.e-03,6.e-03
07818 };
07819 static double eps0[2] = {
07820     1.e-10,1.e-08
07821 };
07822 static int K1 = 1;
07823 static int K2 = 2;
07824 static int K3 = 3;
07825 static int K8 = 0;
07826 static double am1,amax,ap1,ap2,ap3,apn,b,c1,c2,c3,c4,c5,d,e,e2,eps,g,h,pn,qg,qn,
07827     r,rta,s,s2,sum,t,u,w,xmax,xmin,xn,y,z;
07828 static int iop;
07829 static double T4,T5,T6,T7,T9;
07830 /*
07831      ..
07832      .. Executable Statements ..
07833 */
07834 /*
07835      ****** E, XMIN, AND XMAX ARE MACHINE DEPENDENT CONSTANTS.
07836             E IS THE SMALLEST NUMBER FOR WHICH 1.0 + E .GT. 1.0.
07837             XMIN IS THE SMALLEST POSITIVE NUMBER AND XMAX IS THE
07838             LARGEST POSITIVE NUMBER.
07839 */
07840     e = spmpar(&K1);
07841     xmin = spmpar(&K2);
07842     xmax = spmpar(&K3);
07843     *x = 0.0e0;
07844     if(*a <= 0.0e0) goto S300;
07845     t = *p+*q-1.e0;
07846     if(fabs(t) > e) goto S320;
07847     *ierr = 0;
07848     if(*p == 0.0e0) return;
07849     if(*q == 0.0e0) goto S270;
07850     if(*a == 1.0e0) goto S280;
07851     e2 = 2.0e0*e;
07852     amax = 0.4e-10/(e*e);
07853     iop = 1;
07854     if(e > 1.e-10) iop = 2;
07855     eps = eps0[iop-1];
07856     xn = *x0;
07857     if(*x0 > 0.0e0) goto S160;
07858 /*
07859         SELECTION OF THE INITIAL APPROXIMATION XN OF X
07860                        WHEN A .LT. 1
07861 */
07862     if(*a > 1.0e0) goto S80;
07863     T4 = *a+1.0e0;
07864     g = Xgamm(&T4);
07865     qg = *q*g;
07866     if(qg == 0.0e0) goto S360;
07867     b = qg/ *a;
07868     if(qg > 0.6e0**a) goto S40;
07869     if(*a >= 0.30e0 || b < 0.35e0) goto S10;
07870     t = exp(-(b+c));
07871     u = t*exp(t);
07872     xn = t*exp(u);
07873     goto S160;
07874 S10:
07875     if(b >= 0.45e0) goto S40;
07876     if(b == 0.0e0) goto S360;
07877     y = -log(b);
07878     s = 0.5e0+(0.5e0-*a);
07879     z = log(y);
07880     t = y-s*z;
07881     if(b < 0.15e0) goto S20;
07882     xn = y-s*log(t)-log(1.0e0+s/(t+1.0e0));
07883     goto S220;
07884 S20:
07885     if(b <= 0.01e0) goto S30;
07886     u = ((t+2.0e0*(3.0e0-*a))*t+(2.0e0-*a)*(3.0e0-*a))/((t+(5.0e0-*a))*t+2.0e0);
07887     xn = y-s*log(t)-log(u);
07888     goto S220;
07889 S30:
07890     c1 = -(s*z);
07891     c2 = -(s*(1.0e0+c1));
07892     c3 = s*((0.5e0*c1+(2.0e0-*a))*c1+(2.5e0-1.5e0**a));
07893     c4 = -(s*(((c1/3.0e0+(2.5e0-1.5e0**a))*c1+((*a-6.0e0)**a+7.0e0))*c1+(
07894       (11.0e0**a-46.0)**a+47.0e0)/6.0e0));
07895     c5 = -(s*((((-(c1/4.0e0)+(11.0e0**a-17.0e0)/6.0e0)*c1+((-(3.0e0**a)+13.0e0)*
07896       *a-13.0e0))*c1+0.5e0*(((2.0e0**a-25.0e0)**a+72.0e0)**a-61.0e0))*c1+((
07897       (25.0e0**a-195.0e0)**a+477.0e0)**a-379.0e0)/12.0e0));
07898     xn = (((c5/y+c4)/y+c3)/y+c2)/y+c1+y;
07899     if(*a > 1.0e0) goto S220;
07900     if(b > bmin[iop-1]) goto S220;
07901     *x = xn;
07902     return;
07903 S40:
07904     if(b**q > 1.e-8) goto S50;
07905     xn = exp(-(*q/ *a+c));
07906     goto S70;
07907 S50:
07908     if(*p <= 0.9e0) goto S60;
07909     T5 = -*q;
07910     xn = exp((alnrel(&T5)+gamln1(a))/ *a);
07911     goto S70;
07912 S60:
07913     xn = exp(log(*p*g)/ *a);
07914 S70:
07915     if(xn == 0.0e0) goto S310;
07916     t = 0.5e0+(0.5e0-xn/(*a+1.0e0));
07917     xn /= t;
07918     goto S160;
07919 S80:
07920 /*
07921         SELECTION OF THE INITIAL APPROXIMATION XN OF X
07922                        WHEN A .GT. 1
07923 */
07924     if(*q <= 0.5e0) goto S90;
07925     w = log(*p);
07926     goto S100;
07927 S90:
07928     w = log(*q);
07929 S100:
07930     t = sqrt(-(2.0e0*w));
07931     s = t-(((a3*t+a2)*t+a1)*t+a0)/((((b4*t+b3)*t+b2)*t+b1)*t+1.0e0);
07932     if(*q > 0.5e0) s = -s;
07933     rta = sqrt(*a);
07934     s2 = s*s;
07935     xn = *a+s*rta+(s2-1.0e0)/3.0e0+s*(s2-7.0e0)/(36.0e0*rta)-((3.0e0*s2+7.0e0)*
07936       s2-16.0e0)/(810.0e0**a)+s*((9.0e0*s2+256.0e0)*s2-433.0e0)/(38880.0e0**a*
07937       rta);
07938     xn = fifdmax1(xn,0.0e0);
07939     if(*a < amin[iop-1]) goto S110;
07940     *x = xn;
07941     d = 0.5e0+(0.5e0-*x/ *a);
07942     if(fabs(d) <= dmin[iop-1]) return;
07943 S110:
07944     if(*p <= 0.5e0) goto S130;
07945     if(xn < 3.0e0**a) goto S220;
07946     y = -(w+gamln(a));
07947     d = fifdmax1(2.0e0,*a*(*a-1.0e0));
07948     if(y < ln10*d) goto S120;
07949     s = 1.0e0-*a;
07950     z = log(y);
07951     goto S30;
07952 S120:
07953     t = *a-1.0e0;
07954     T6 = -(t/(xn+1.0e0));
07955     xn = y+t*log(xn)-alnrel(&T6);
07956     T7 = -(t/(xn+1.0e0));
07957     xn = y+t*log(xn)-alnrel(&T7);
07958     goto S220;
07959 S130:
07960     ap1 = *a+1.0e0;
07961     if(xn > 0.70e0*ap1) goto S170;
07962     w += gamln(&ap1);
07963     if(xn > 0.15e0*ap1) goto S140;
07964     ap2 = *a+2.0e0;
07965     ap3 = *a+3.0e0;
07966     *x = exp((w+*x)/ *a);
07967     *x = exp((w+*x-log(1.0e0+*x/ap1*(1.0e0+*x/ap2)))/ *a);
07968     *x = exp((w+*x-log(1.0e0+*x/ap1*(1.0e0+*x/ap2)))/ *a);
07969     *x = exp((w+*x-log(1.0e0+*x/ap1*(1.0e0+*x/ap2*(1.0e0+*x/ap3))))/ *a);
07970     xn = *x;
07971     if(xn > 1.e-2*ap1) goto S140;
07972     if(xn <= emin[iop-1]*ap1) return;
07973     goto S170;
07974 S140:
07975     apn = ap1;
07976     t = xn/apn;
07977     sum = 1.0e0+t;
07978 S150:
07979     apn += 1.0e0;
07980     t *= (xn/apn);
07981     sum += t;
07982     if(t > 1.e-4) goto S150;
07983     t = w-log(sum);
07984     xn = exp((xn+t)/ *a);
07985     xn *= (1.0e0-(*a*log(xn)-xn-t)/(*a-xn));
07986     goto S170;
07987 S160:
07988 /*
07989                  SCHRODER ITERATION USING P
07990 */
07991     if(*p > 0.5e0) goto S220;
07992 S170:
07993     if(*p <= 1.e10*xmin) goto S350;
07994     am1 = *a-0.5e0-0.5e0;
07995 S180:
07996     if(*a <= amax) goto S190;
07997     d = 0.5e0+(0.5e0-xn/ *a);
07998     if(fabs(d) <= e2) goto S350;
07999 S190:
08000     if(*ierr >= 20) goto S330;
08001     *ierr += 1;
08002     gratio(a,&xn,&pn,&qn,&K8);
08003     if(pn == 0.0e0 || qn == 0.0e0) goto S350;
08004     r = rcomp(a,&xn);
08005     if(r == 0.0e0) goto S350;
08006     t = (pn-*p)/r;
08007     w = 0.5e0*(am1-xn);
08008     if(fabs(t) <= 0.1e0 && fabs(w*t) <= 0.1e0) goto S200;
08009     *x = xn*(1.0e0-t);
08010     if(*x <= 0.0e0) goto S340;
08011     d = fabs(t);
08012     goto S210;
08013 S200:
08014     h = t*(1.0e0+w*t);
08015     *x = xn*(1.0e0-h);
08016     if(*x <= 0.0e0) goto S340;
08017     if(fabs(w) >= 1.0e0 && fabs(w)*t*t <= eps) return;
08018     d = fabs(h);
08019 S210:
08020     xn = *x;
08021     if(d > tol) goto S180;
08022     if(d <= eps) return;
08023     if(fabs(*p-pn) <= tol**p) return;
08024     goto S180;
08025 S220:
08026 /*
08027                  SCHRODER ITERATION USING Q
08028 */
08029     if(*q <= 1.e10*xmin) goto S350;
08030     am1 = *a-0.5e0-0.5e0;
08031 S230:
08032     if(*a <= amax) goto S240;
08033     d = 0.5e0+(0.5e0-xn/ *a);
08034     if(fabs(d) <= e2) goto S350;
08035 S240:
08036     if(*ierr >= 20) goto S330;
08037     *ierr += 1;
08038     gratio(a,&xn,&pn,&qn,&K8);
08039     if(pn == 0.0e0 || qn == 0.0e0) goto S350;
08040     r = rcomp(a,&xn);
08041     if(r == 0.0e0) goto S350;
08042     t = (*q-qn)/r;
08043     w = 0.5e0*(am1-xn);
08044     if(fabs(t) <= 0.1e0 && fabs(w*t) <= 0.1e0) goto S250;
08045     *x = xn*(1.0e0-t);
08046     if(*x <= 0.0e0) goto S340;
08047     d = fabs(t);
08048     goto S260;
08049 S250:
08050     h = t*(1.0e0+w*t);
08051     *x = xn*(1.0e0-h);
08052     if(*x <= 0.0e0) goto S340;
08053     if(fabs(w) >= 1.0e0 && fabs(w)*t*t <= eps) return;
08054     d = fabs(h);
08055 S260:
08056     xn = *x;
08057     if(d > tol) goto S230;
08058     if(d <= eps) return;
08059     if(fabs(*q-qn) <= tol**q) return;
08060     goto S230;
08061 S270:
08062 /*
08063                        SPECIAL CASES
08064 */
08065     *x = xmax;
08066     return;
08067 S280:
08068     if(*q < 0.9e0) goto S290;
08069     T9 = -*p;
08070     *x = -alnrel(&T9);
08071     return;
08072 S290:
08073     *x = -log(*q);
08074     return;
08075 S300:
08076 /*
08077                        ERROR RETURN
08078 */
08079     *ierr = -2;
08080     return;
08081 S310:
08082     *ierr = -3;
08083     return;
08084 S320:
08085     *ierr = -4;
08086     return;
08087 S330:
08088     *ierr = -6;
08089     return;
08090 S340:
08091     *ierr = -7;
08092     return;
08093 S350:
08094     *x = xn;
08095     *ierr = -8;
08096     return;
08097 S360:
08098     *x = xmax;
08099     *ierr = -8;
08100     return;
08101 } /* END */
08102 
08103 /***=====================================================================***/
08104 static double gamln(double *a)
08105 /*
08106 -----------------------------------------------------------------------
08107             EVALUATION OF LN(GAMMA(A)) FOR POSITIVE A
08108 -----------------------------------------------------------------------
08109      WRITTEN BY ALFRED H. MORRIS
08110           NAVAL SURFACE WARFARE CENTER
08111           DAHLGREN, VIRGINIA
08112 --------------------------
08113      D = 0.5*(LN(2*PI) - 1)
08114 --------------------------
08115 */
08116 {
08117 static double c0 = .833333333333333e-01;
08118 static double c1 = -.277777777760991e-02;
08119 static double c2 = .793650666825390e-03;
08120 static double c3 = -.595202931351870e-03;
08121 static double c4 = .837308034031215e-03;
08122 static double c5 = -.165322962780713e-02;
08123 static double d = .418938533204673e0;
08124 static double gamln,t,w;
08125 static int i,n;
08126 static double T1;
08127 /*
08128      ..
08129      .. Executable Statements ..
08130 */
08131     if(*a > 0.8e0) goto S10;
08132     gamln = gamln1(a)-log(*a);
08133     return gamln;
08134 S10:
08135     if(*a > 2.25e0) goto S20;
08136     t = *a-0.5e0-0.5e0;
08137     gamln = gamln1(&t);
08138     return gamln;
08139 S20:
08140     if(*a >= 10.0e0) goto S40;
08141     n = *a-1.25e0;
08142     t = *a;
08143     w = 1.0e0;
08144     for(i=1; i<=n; i++) {
08145         t -= 1.0e0;
08146         w = t*w;
08147     }
08148     T1 = t-1.0e0;
08149     gamln = gamln1(&T1)+log(w);
08150     return gamln;
08151 S40:
08152     t = pow(1.0e0/ *a,2.0);
08153     w = (((((c5*t+c4)*t+c3)*t+c2)*t+c1)*t+c0)/ *a;
08154     gamln = d+w+(*a-0.5e0)*(log(*a)-1.0e0);
08155     return gamln;
08156 } /* END */
08157 
08158 /***=====================================================================***/
08159 static double gamln1(double *a)
08160 /*
08161 -----------------------------------------------------------------------
08162      EVALUATION OF LN(GAMMA(1 + A)) FOR -0.2 .LE. A .LE. 1.25
08163 -----------------------------------------------------------------------
08164 */
08165 {
08166 static double p0 = .577215664901533e+00;
08167 static double p1 = .844203922187225e+00;
08168 static double p2 = -.168860593646662e+00;
08169 static double p3 = -.780427615533591e+00;
08170 static double p4 = -.402055799310489e+00;
08171 static double p5 = -.673562214325671e-01;
08172 static double p6 = -.271935708322958e-02;
08173 static double q1 = .288743195473681e+01;
08174 static double q2 = .312755088914843e+01;
08175 static double q3 = .156875193295039e+01;
08176 static double q4 = .361951990101499e+00;
08177 static double q5 = .325038868253937e-01;
08178 static double q6 = .667465618796164e-03;
08179 static double r0 = .422784335098467e+00;
08180 static double r1 = .848044614534529e+00;
08181 static double r2 = .565221050691933e+00;
08182 static double r3 = .156513060486551e+00;
08183 static double r4 = .170502484022650e-01;
08184 static double r5 = .497958207639485e-03;
08185 static double s1 = .124313399877507e+01;
08186 static double s2 = .548042109832463e+00;
08187 static double s3 = .101552187439830e+00;
08188 static double s4 = .713309612391000e-02;
08189 static double s5 = .116165475989616e-03;
08190 static double gamln1,w,x;
08191 /*
08192      ..
08193      .. Executable Statements ..
08194 */
08195     if(*a >= 0.6e0) goto S10;
08196     w = ((((((p6**a+p5)**a+p4)**a+p3)**a+p2)**a+p1)**a+p0)/((((((q6**a+q5)**a+
08197       q4)**a+q3)**a+q2)**a+q1)**a+1.0e0);
08198     gamln1 = -(*a*w);
08199     return gamln1;
08200 S10:
08201     x = *a-0.5e0-0.5e0;
08202     w = (((((r5*x+r4)*x+r3)*x+r2)*x+r1)*x+r0)/(((((s5*x+s4)*x+s3)*x+s2)*x+s1)*x
08203       +1.0e0);
08204     gamln1 = x*w;
08205     return gamln1;
08206 } /* END */
08207 
08208 /***=====================================================================***/
08209 static double Xgamm(double *a)
08210 /*
08211 -----------------------------------------------------------------------
08212 
08213          EVALUATION OF THE GAMMA FUNCTION FOR REAL ARGUMENTS
08214 
08215                            -----------
08216 
08217      GAMMA(A) IS ASSIGNED THE VALUE 0 WHEN THE GAMMA FUNCTION CANNOT
08218      BE COMPUTED.
08219 
08220 -----------------------------------------------------------------------
08221      WRITTEN BY ALFRED H. MORRIS, JR.
08222           NAVAL SURFACE WEAPONS CENTER
08223           DAHLGREN, VIRGINIA
08224 -----------------------------------------------------------------------
08225 */
08226 {
08227 static double d = .41893853320467274178e0;
08228 static double pi = 3.1415926535898e0;
08229 static double r1 = .820756370353826e-03;
08230 static double r2 = -.595156336428591e-03;
08231 static double r3 = .793650663183693e-03;
08232 static double r4 = -.277777777770481e-02;
08233 static double r5 = .833333333333333e-01;
08234 static double p[7] = {
08235     .539637273585445e-03,.261939260042690e-02,.204493667594920e-01,
08236     .730981088720487e-01,.279648642639792e+00,.553413866010467e+00,1.0e0
08237 };
08238 static double q[7] = {
08239     -.832979206704073e-03,.470059485860584e-02,.225211131035340e-01,
08240     -.170458969313360e+00,-.567902761974940e-01,.113062953091122e+01,1.0e0
08241 };
08242 static int K2 = 3;
08243 static int K3 = 0;
08244 static double Xgamm,bot,g,lnx,s,t,top,w,x,z;
08245 static int i,j,m,n,T1;
08246 /*
08247      ..
08248      .. Executable Statements ..
08249 */
08250     Xgamm = 0.0e0;
08251     x = *a;
08252     if(fabs(*a) >= 15.0e0) goto S110;
08253 /*
08254 -----------------------------------------------------------------------
08255             EVALUATION OF GAMMA(A) FOR ABS(A) .LT. 15
08256 -----------------------------------------------------------------------
08257 */
08258     t = 1.0e0;
08259     m = fifidint(*a)-1;
08260 /*
08261      LET T BE THE PRODUCT OF A-J WHEN A .GE. 2
08262 */
08263     T1 = m;
08264     if(T1 < 0) goto S40;
08265     else if(T1 == 0) goto S30;
08266     else  goto S10;
08267 S10:
08268     for(j=1; j<=m; j++) {
08269         x -= 1.0e0;
08270         t = x*t;
08271     }
08272 S30:
08273     x -= 1.0e0;
08274     goto S80;
08275 S40:
08276 /*
08277      LET T BE THE PRODUCT OF A+J WHEN A .LT. 1
08278 */
08279     t = *a;
08280     if(*a > 0.0e0) goto S70;
08281     m = -m-1;
08282     if(m == 0) goto S60;
08283     for(j=1; j<=m; j++) {
08284         x += 1.0e0;
08285         t = x*t;
08286     }
08287 S60:
08288     x += (0.5e0+0.5e0);
08289     t = x*t;
08290     if(t == 0.0e0) return Xgamm;
08291 S70:
08292 /*
08293      THE FOLLOWING CODE CHECKS IF 1/T CAN OVERFLOW. THIS
08294      CODE MAY BE OMITTED IF DESIRED.
08295 */
08296     if(fabs(t) >= 1.e-30) goto S80;
08297     if(fabs(t)*spmpar(&K2) <= 1.0001e0) return Xgamm;
08298     Xgamm = 1.0e0/t;
08299     return Xgamm;
08300 S80:
08301 /*
08302      COMPUTE GAMMA(1 + X) FOR  0 .LE. X .LT. 1
08303 */
08304     top = p[0];
08305     bot = q[0];
08306     for(i=1; i<7; i++) {
08307         top = p[i]+x*top;
08308         bot = q[i]+x*bot;
08309     }
08310     Xgamm = top/bot;
08311 /*
08312      TERMINATION
08313 */
08314     if(*a < 1.0e0) goto S100;
08315     Xgamm *= t;
08316     return Xgamm;
08317 S100:
08318     Xgamm /= t;
08319     return Xgamm;
08320 S110:
08321 /*
08322 -----------------------------------------------------------------------
08323             EVALUATION OF GAMMA(A) FOR ABS(A) .GE. 15
08324 -----------------------------------------------------------------------
08325 */
08326     if(fabs(*a) >= 1.e3) return Xgamm;
08327     if(*a > 0.0e0) goto S120;
08328     x = -*a;
08329     n = x;
08330     t = x-(double)n;
08331     if(t > 0.9e0) t = 1.0e0-t;
08332     s = sin(pi*t)/pi;
08333     if(fifmod(n,2) == 0) s = -s;
08334     if(s == 0.0e0) return Xgamm;
08335 S120:
08336 /*
08337      COMPUTE THE MODIFIED ASYMPTOTIC SUM
08338 */
08339     t = 1.0e0/(x*x);
08340     g = ((((r1*t+r2)*t+r3)*t+r4)*t+r5)/x;
08341 /*
08342      ONE MAY REPLACE THE NEXT STATEMENT WITH  LNX = ALOG(X)
08343      BUT LESS ACCURACY WILL NORMALLY BE OBTAINED.
08344 */
08345     lnx = log(x);
08346 /*
08347      FINAL ASSEMBLY
08348 */
08349     z = x;
08350     g = d+g+(z-0.5e0)*(lnx-1.e0);
08351     w = g;
08352     t = g-w;
08353     if(w > 0.99999e0*exparg(&K3)) return Xgamm;
08354     Xgamm = exp(w)*(1.0e0+t);
08355     if(*a < 0.0e0) Xgamm = 1.0e0/(Xgamm*s)/x;
08356     return Xgamm;
08357 } /* END */
08358 
08359 /***=====================================================================***/
08360 static void grat1(double *a,double *x,double *r,double *p,double *q,
08361            double *eps)
08362 {
08363 static int K2 = 0;
08364 static double a2n,a2nm1,am0,an,an0,b2n,b2nm1,c,cma,g,h,j,l,sum,t,tol,w,z,T1,T3;
08365 /*
08366      ..
08367      .. Executable Statements ..
08368 */
08369 /*
08370 -----------------------------------------------------------------------
08371         EVALUATION OF THE INCOMPLETE GAMMA RATIO FUNCTIONS
08372                       P(A,X) AND Q(A,X)
08373      IT IS ASSUMED THAT A .LE. 1.  EPS IS THE TOLERANCE TO BE USED.
08374      THE INPUT ARGUMENT R HAS THE VALUE E**(-X)*X**A/GAMMA(A).
08375 -----------------------------------------------------------------------
08376 */
08377     if(*a**x == 0.0e0) goto S120;
08378     if(*a == 0.5e0) goto S100;
08379     if(*x < 1.1e0) goto S10;
08380     goto S60;
08381 S10:
08382 /*
08383              TAYLOR SERIES FOR P(A,X)/X**A
08384 */
08385     an = 3.0e0;
08386     c = *x;
08387     sum = *x/(*a+3.0e0);
08388     tol = 0.1e0**eps/(*a+1.0e0);
08389 S20:
08390     an += 1.0e0;
08391     c = -(c*(*x/an));
08392     t = c/(*a+an);
08393     sum += t;
08394     if(fabs(t) > tol) goto S20;
08395     j = *a**x*((sum/6.0e0-0.5e0/(*a+2.0e0))**x+1.0e0/(*a+1.0e0));
08396     z = *a*log(*x);
08397     h = gam1(a);
08398     g = 1.0e0+h;
08399     if(*x < 0.25e0) goto S30;
08400     if(*a < *x/2.59e0) goto S50;
08401     goto S40;
08402 S30:
08403     if(z > -.13394e0) goto S50;
08404 S40:
08405     w = exp(z);
08406     *p = w*g*(0.5e0+(0.5e0-j));
08407     *q = 0.5e0+(0.5e0-*p);
08408     return;
08409 S50:
08410     l = rexp(&z);
08411     w = 0.5e0+(0.5e0+l);
08412     *q = (w*j-l)*g-h;
08413     if(*q < 0.0e0) goto S90;
08414     *p = 0.5e0+(0.5e0-*q);
08415     return;
08416 S60:
08417 /*
08418               CONTINUED FRACTION EXPANSION
08419 */
08420     a2nm1 = a2n = 1.0e0;
08421     b2nm1 = *x;
08422     b2n = *x+(1.0e0-*a);
08423     c = 1.0e0;
08424 S70:
08425     a2nm1 = *x*a2n+c*a2nm1;
08426     b2nm1 = *x*b2n+c*b2nm1;
08427     am0 = a2nm1/b2nm1;
08428     c += 1.0e0;
08429     cma = c-*a;
08430     a2n = a2nm1+cma*a2n;
08431     b2n = b2nm1+cma*b2n;
08432     an0 = a2n/b2n;
08433     if(fabs(an0-am0) >= *eps*an0) goto S70;
08434     *q = *r*an0;
08435     *p = 0.5e0+(0.5e0-*q);
08436     return;
08437 S80:
08438 /*
08439                 SPECIAL CASES
08440 */
08441     *p = 0.0e0;
08442     *q = 1.0e0;
08443     return;
08444 S90:
08445     *p = 1.0e0;
08446     *q = 0.0e0;
08447     return;
08448 S100:
08449     if(*x >= 0.25e0) goto S110;
08450     T1 = sqrt(*x);
08451     *p = erf1(&T1);
08452     *q = 0.5e0+(0.5e0-*p);
08453     return;
08454 S110:
08455     T3 = sqrt(*x);
08456     *q = erfc1(&K2,&T3);
08457     *p = 0.5e0+(0.5e0-*q);
08458     return;
08459 S120:
08460     if(*x <= *a) goto S80;
08461     goto S90;
08462 } /* END */
08463 
08464 /***=====================================================================***/
08465 static void gratio(double *a,double *x,double *ans,double *qans,int *ind)
08466 /*
08467  ----------------------------------------------------------------------
08468         EVALUATION OF THE INCOMPLETE GAMMA RATIO FUNCTIONS
08469                       P(A,X) AND Q(A,X)
08470 
08471                         ----------
08472 
08473      IT IS ASSUMED THAT A AND X ARE NONNEGATIVE, WHERE A AND X
08474      ARE NOT BOTH 0.
08475 
08476      ANS AND QANS ARE VARIABLES. GRATIO ASSIGNS ANS THE VALUE
08477      P(A,X) AND QANS THE VALUE Q(A,X). IND MAY BE ANY INTEGER.
08478      IF IND = 0 THEN THE USER IS REQUESTING AS MUCH ACCURACY AS
08479      POSSIBLE (UP TO 14 SIGNIFICANT DIGITS). OTHERWISE, IF
08480      IND = 1 THEN ACCURACY IS REQUESTED TO WITHIN 1 UNIT OF THE
08481      6-TH SIGNIFICANT DIGIT, AND IF IND .NE. 0,1 THEN ACCURACY
08482      IS REQUESTED TO WITHIN 1 UNIT OF THE 3RD SIGNIFICANT DIGIT.
08483 
08484      ERROR RETURN ...
08485         ANS IS ASSIGNED THE VALUE 2 WHEN A OR X IS NEGATIVE,
08486      WHEN A*X = 0, OR WHEN P(A,X) AND Q(A,X) ARE INDETERMINANT.
08487      P(A,X) AND Q(A,X) ARE COMPUTATIONALLY INDETERMINANT WHEN
08488      X IS EXCEEDINGLY CLOSE TO A AND A IS EXTREMELY LARGE.
08489  ----------------------------------------------------------------------
08490      WRITTEN BY ALFRED H. MORRIS, JR.
08491         NAVAL SURFACE WEAPONS CENTER
08492         DAHLGREN, VIRGINIA
08493      --------------------
08494 */
08495 {
08496 static double alog10 = 2.30258509299405e0;
08497 static double d10 = -.185185185185185e-02;
08498 static double d20 = .413359788359788e-02;
08499 static double d30 = .649434156378601e-03;
08500 static double d40 = -.861888290916712e-03;
08501 static double d50 = -.336798553366358e-03;
08502 static double d60 = .531307936463992e-03;
08503 static double d70 = .344367606892378e-03;
08504 static double rt2pin = .398942280401433e0;
08505 static double rtpi = 1.77245385090552e0;
08506 static double third = .333333333333333e0;
08507 static double acc0[3] = {
08508     5.e-15,5.e-7,5.e-4
08509 };
08510 static double big[3] = {
08511     20.0e0,14.0e0,10.0e0
08512 };
08513 static double d0[13] = {
08514     .833333333333333e-01,-.148148148148148e-01,.115740740740741e-02,
08515     .352733686067019e-03,-.178755144032922e-03,.391926317852244e-04,
08516     -.218544851067999e-05,-.185406221071516e-05,.829671134095309e-06,
08517     -.176659527368261e-06,.670785354340150e-08,.102618097842403e-07,
08518     -.438203601845335e-08
08519 };
08520 static double d1[12] = {
08521     -.347222222222222e-02,.264550264550265e-02,-.990226337448560e-03,
08522     .205761316872428e-03,-.401877572016461e-06,-.180985503344900e-04,
08523     .764916091608111e-05,-.161209008945634e-05,.464712780280743e-08,
08524     .137863344691572e-06,-.575254560351770e-07,.119516285997781e-07
08525 };
08526 static double d2[10] = {
08527     -.268132716049383e-02,.771604938271605e-03,.200938786008230e-05,
08528     -.107366532263652e-03,.529234488291201e-04,-.127606351886187e-04,
08529     .342357873409614e-07,.137219573090629e-05,-.629899213838006e-06,
08530     .142806142060642e-06
08531 };
08532 static double d3[8] = {
08533     .229472093621399e-03,-.469189494395256e-03,.267720632062839e-03,
08534     -.756180167188398e-04,-.239650511386730e-06,.110826541153473e-04,
08535     -.567495282699160e-05,.142309007324359e-05
08536 };
08537 static double d4[6] = {
08538     .784039221720067e-03,-.299072480303190e-03,-.146384525788434e-05,
08539     .664149821546512e-04,-.396836504717943e-04,.113757269706784e-04
08540 };
08541 static double d5[4] = {
08542     -.697281375836586e-04,.277275324495939e-03,-.199325705161888e-03,
08543     .679778047793721e-04
08544 };
08545 static double d6[2] = {
08546     -.592166437353694e-03,.270878209671804e-03
08547 };
08548 static double e00[3] = {
08549     .25e-3,.25e-1,.14e0
08550 };
08551 static double x00[3] = {
08552     31.0e0,17.0e0,9.7e0
08553 };
08554 static int K1 = 1;
08555 static int K2 = 0;
08556 static double a2n,a2nm1,acc,am0,amn,an,an0,apn,b2n,b2nm1,c,c0,c1,c2,c3,c4,c5,c6,
08557     cma,e,e0,g,h,j,l,r,rta,rtx,s,sum,t,t1,tol,twoa,u,w,x0,y,z;
08558 static int i,iop,m,max,n;
08559 static double wk[20],T3;
08560 static int T4,T5;
08561 static double T6,T7;
08562 /*
08563      ..
08564      .. Executable Statements ..
08565 */
08566 /*
08567      --------------------
08568      ****** E IS A MACHINE DEPENDENT CONSTANT. E IS THE SMALLEST
08569             FLOATING POINT NUMBER FOR WHICH 1.0 + E .GT. 1.0 .
08570 */
08571     e = spmpar(&K1);
08572     if(*a < 0.0e0 || *x < 0.0e0) goto S430;
08573     if(*a == 0.0e0 && *x == 0.0e0) goto S430;
08574     if(*a**x == 0.0e0) goto S420;
08575     iop = *ind+1;
08576     if(iop != 1 && iop != 2) iop = 3;
08577     acc = fifdmax1(acc0[iop-1],e);
08578     e0 = e00[iop-1];
08579     x0 = x00[iop-1];
08580 /*
08581             SELECT THE APPROPRIATE ALGORITHM
08582 */
08583     if(*a >= 1.0e0) goto S10;
08584     if(*a == 0.5e0) goto S390;
08585     if(*x < 1.1e0) goto S160;
08586     t1 = *a*log(*x)-*x;
08587     u = *a*exp(t1);
08588     if(u == 0.0e0) goto S380;
08589     r = u*(1.0e0+gam1(a));
08590     goto S250;
08591 S10:
08592     if(*a >= big[iop-1]) goto S30;
08593     if(*a > *x || *x >= x0) goto S20;
08594     twoa = *a+*a;
08595     m = fifidint(twoa);
08596     if(twoa != (double)m) goto S20;
08597     i = m/2;
08598     if(*a == (double)i) goto S210;
08599     goto S220;
08600 S20:
08601     t1 = *a*log(*x)-*x;
08602     r = exp(t1)/Xgamm(a);
08603     goto S40;
08604 S30:
08605     l = *x/ *a;
08606     if(l == 0.0e0) goto S370;
08607     s = 0.5e0+(0.5e0-l);
08608     z = rlog(&l);
08609     if(z >= 700.0e0/ *a) goto S410;
08610     y = *a*z;
08611     rta = sqrt(*a);
08612     if(fabs(s) <= e0/rta) goto S330;
08613     if(fabs(s) <= 0.4e0) goto S270;
08614     t = pow(1.0e0/ *a,2.0);
08615     t1 = (((0.75e0*t-1.0e0)*t+3.5e0)*t-105.0e0)/(*a*1260.0e0);
08616     t1 -= y;
08617     r = rt2pin*rta*exp(t1);
08618 S40:
08619     if(r == 0.0e0) goto S420;
08620     if(*x <= fifdmax1(*a,alog10)) goto S50;
08621     if(*x < x0) goto S250;
08622     goto S100;
08623 S50:
08624 /*
08625                  TAYLOR SERIES FOR P/R
08626 */
08627     apn = *a+1.0e0;
08628     t = *x/apn;
08629     wk[0] = t;
08630     for(n=2; n<=20; n++) {
08631         apn += 1.0e0;
08632         t *= (*x/apn);
08633         if(t <= 1.e-3) goto S70;
08634         wk[n-1] = t;
08635     }
08636     n = 20;
08637 S70:
08638     sum = t;
08639     tol = 0.5e0*acc;
08640 S80:
08641     apn += 1.0e0;
08642     t *= (*x/apn);
08643     sum += t;
08644     if(t > tol) goto S80;
08645     max = n-1;
08646     for(m=1; m<=max; m++) {
08647         n -= 1;
08648         sum += wk[n-1];
08649     }
08650     *ans = r/ *a*(1.0e0+sum);
08651     *qans = 0.5e0+(0.5e0-*ans);
08652     return;
08653 S100:
08654 /*
08655                  ASYMPTOTIC EXPANSION
08656 */
08657     amn = *a-1.0e0;
08658     t = amn/ *x;
08659     wk[0] = t;
08660     for(n=2; n<=20; n++) {
08661         amn -= 1.0e0;
08662         t *= (amn/ *x);
08663         if(fabs(t) <= 1.e-3) goto S120;
08664         wk[n-1] = t;
08665     }
08666     n = 20;
08667 S120:
08668     sum = t;
08669 S130:
08670     if(fabs(t) <= acc) goto S140;
08671     amn -= 1.0e0;
08672     t *= (amn/ *x);
08673     sum += t;
08674     goto S130;
08675 S140:
08676     max = n-1;
08677     for(m=1; m<=max; m++) {
08678         n -= 1;
08679         sum += wk[n-1];
08680     }
08681     *qans = r/ *x*(1.0e0+sum);
08682     *ans = 0.5e0+(0.5e0-*qans);
08683     return;
08684 S160:
08685 /*
08686              TAYLOR SERIES FOR P(A,X)/X**A
08687 */
08688     an = 3.0e0;
08689     c = *x;
08690     sum = *x/(*a+3.0e0);
08691     tol = 3.0e0*acc/(*a+1.0e0);
08692 S170:
08693     an += 1.0e0;
08694     c = -(c*(*x/an));
08695     t = c/(*a+an);
08696     sum += t;
08697     if(fabs(t) > tol) goto S170;
08698     j = *a**x*((sum/6.0e0-0.5e0/(*a+2.0e0))**x+1.0e0/(*a+1.0e0));
08699     z = *a*log(*x);
08700     h = gam1(a);
08701     g = 1.0e0+h;
08702     if(*x < 0.25e0) goto S180;
08703     if(*a < *x/2.59e0) goto S200;
08704     goto S190;
08705 S180:
08706     if(z > -.13394e0) goto S200;
08707 S190:
08708     w = exp(z);
08709     *ans = w*g*(0.5e0+(0.5e0-j));
08710     *qans = 0.5e0+(0.5e0-*ans);
08711     return;
08712 S200:
08713     l = rexp(&z);
08714     w = 0.5e0+(0.5e0+l);
08715     *qans = (w*j-l)*g-h;
08716     if(*qans < 0.0e0) goto S380;
08717     *ans = 0.5e0+(0.5e0-*qans);
08718     return;
08719 S210:
08720 /*
08721              FINITE SUMS FOR Q WHEN A .GE. 1
08722                  AND 2*A IS AN INTEGER
08723 */
08724     sum = exp(-*x);
08725     t = sum;
08726     n = 1;
08727     c = 0.0e0;
08728     goto S230;
08729 S220:
08730     rtx = sqrt(*x);
08731     sum = erfc1(&K2,&rtx);
08732     t = exp(-*x)/(rtpi*rtx);
08733     n = 0;
08734     c = -0.5e0;
08735 S230:
08736     if(n == i) goto S240;
08737     n += 1;
08738     c += 1.0e0;
08739     t = *x*t/c;
08740     sum += t;
08741     goto S230;
08742 S240:
08743     *qans = sum;
08744     *ans = 0.5e0+(0.5e0-*qans);
08745     return;
08746 S250:
08747 /*
08748               CONTINUED FRACTION EXPANSION
08749 */
08750     tol = fifdmax1(5.0e0*e,acc);
08751     a2nm1 = a2n = 1.0e0;
08752     b2nm1 = *x;
08753     b2n = *x+(1.0e0-*a);
08754     c = 1.0e0;
08755 S260:
08756     a2nm1 = *x*a2n+c*a2nm1;
08757     b2nm1 = *x*b2n+c*b2nm1;
08758     am0 = a2nm1/b2nm1;
08759     c += 1.0e0;
08760     cma = c-*a;
08761     a2n = a2nm1+cma*a2n;
08762     b2n = b2nm1+cma*b2n;
08763     an0 = a2n/b2n;
08764     if(fabs(an0-am0) >= tol*an0) goto S260;
08765     *qans = r*an0;
08766     *ans = 0.5e0+(0.5e0-*qans);
08767     return;
08768 S270:
08769 /*
08770                 GENERAL TEMME EXPANSION
08771 */
08772     if(fabs(s) <= 2.0e0*e && *a*e*e > 3.28e-3) goto S430;
08773     c = exp(-y);
08774     T3 = sqrt(y);
08775     w = 0.5e0*erfc1(&K1,&T3);
08776     u = 1.0e0/ *a;
08777     z = sqrt(z+z);
08778     if(l < 1.0e0) z = -z;
08779     T4 = iop-2;
08780     if(T4 < 0) goto S280;
08781     else if(T4 == 0) goto S290;
08782     else  goto S300;
08783 S280:
08784     if(fabs(s) <= 1.e-3) goto S340;
08785     c0 = ((((((((((((d0[12]*z+d0[11])*z+d0[10])*z+d0[9])*z+d0[8])*z+d0[7])*z+d0[
08786       6])*z+d0[5])*z+d0[4])*z+d0[3])*z+d0[2])*z+d0[1])*z+d0[0])*z-third;
08787     c1 = (((((((((((d1[11]*z+d1[10])*z+d1[9])*z+d1[8])*z+d1[7])*z+d1[6])*z+d1[5]
08788       )*z+d1[4])*z+d1[3])*z+d1[2])*z+d1[1])*z+d1[0])*z+d10;
08789     c2 = (((((((((d2[9]*z+d2[8])*z+d2[7])*z+d2[6])*z+d2[5])*z+d2[4])*z+d2[3])*z+
08790       d2[2])*z+d2[1])*z+d2[0])*z+d20;
08791     c3 = (((((((d3[7]*z+d3[6])*z+d3[5])*z+d3[4])*z+d3[3])*z+d3[2])*z+d3[1])*z+
08792       d3[0])*z+d30;
08793     c4 = (((((d4[5]*z+d4[4])*z+d4[3])*z+d4[2])*z+d4[1])*z+d4[0])*z+d40;
08794     c5 = (((d5[3]*z+d5[2])*z+d5[1])*z+d5[0])*z+d50;
08795     c6 = (d6[1]*z+d6[0])*z+d60;
08796     t = ((((((d70*u+c6)*u+c5)*u+c4)*u+c3)*u+c2)*u+c1)*u+c0;
08797     goto S310;
08798 S290:
08799     c0 = (((((d0[5]*z+d0[4])*z+d0[3])*z+d0[2])*z+d0[1])*z+d0[0])*z-third;
08800     c1 = (((d1[3]*z+d1[2])*z+d1[1])*z+d1[0])*z+d10;
08801     c2 = d2[0]*z+d20;
08802     t = (c2*u+c1)*u+c0;
08803     goto S310;
08804 S300:
08805     t = ((d0[2]*z+d0[1])*z+d0[0])*z-third;
08806 S310:
08807     if(l < 1.0e0) goto S320;
08808     *qans = c*(w+rt2pin*t/rta);
08809     *ans = 0.5e0+(0.5e0-*qans);
08810     return;
08811 S320:
08812     *ans = c*(w-rt2pin*t/rta);
08813     *qans = 0.5e0+(0.5e0-*ans);
08814     return;
08815 S330:
08816 /*
08817                TEMME EXPANSION FOR L = 1
08818 */
08819     if(*a*e*e > 3.28e-3) goto S430;
08820     c = 0.5e0+(0.5e0-y);
08821     w = (0.5e0-sqrt(y)*(0.5e0+(0.5e0-y/3.0e0))/rtpi)/c;
08822     u = 1.0e0/ *a;
08823     z = sqrt(z+z);
08824     if(l < 1.0e0) z = -z;
08825     T5 = iop-2;
08826     if(T5 < 0) goto S340;
08827     else if(T5 == 0) goto S350;
08828     else  goto S360;
08829 S340:
08830     c0 = ((((((d0[6]*z+d0[5])*z+d0[4])*z+d0[3])*z+d0[2])*z+d0[1])*z+d0[0])*z-
08831       third;
08832     c1 = (((((d1[5]*z+d1[4])*z+d1[3])*z+d1[2])*z+d1[1])*z+d1[0])*z+d10;
08833     c2 = ((((d2[4]*z+d2[3])*z+d2[2])*z+d2[1])*z+d2[0])*z+d20;
08834     c3 = (((d3[3]*z+d3[2])*z+d3[1])*z+d3[0])*z+d30;
08835     c4 = (d4[1]*z+d4[0])*z+d40;
08836     c5 = (d5[1]*z+d5[0])*z+d50;
08837     c6 = d6[0]*z+d60;
08838     t = ((((((d70*u+c6)*u+c5)*u+c4)*u+c3)*u+c2)*u+c1)*u+c0;
08839     goto S310;
08840 S350:
08841     c0 = (d0[1]*z+d0[0])*z-third;
08842     c1 = d1[0]*z+d10;
08843     t = (d20*u+c1)*u+c0;
08844     goto S310;
08845 S360:
08846     t = d0[0]*z-third;
08847     goto S310;
08848 S370:
08849 /*
08850                      SPECIAL CASES
08851 */
08852     *ans = 0.0e0;
08853     *qans = 1.0e0;
08854     return;
08855 S380:
08856     *ans = 1.0e0;
08857     *qans = 0.0e0;
08858     return;
08859 S390:
08860     if(*x >= 0.25e0) goto S400;
08861     T6 = sqrt(*x);
08862     *ans = erf1(&T6);
08863     *qans = 0.5e0+(0.5e0-*ans);
08864     return;
08865 S400:
08866     T7 = sqrt(*x);
08867     *qans = erfc1(&K2,&T7);
08868     *ans = 0.5e0+(0.5e0-*qans);
08869     return;
08870 S410:
08871     if(fabs(s) <= 2.0e0*e) goto S430;
08872 S420:
08873     if(*x <= *a) goto S370;
08874     goto S380;
08875 S430:
08876 /*
08877                      ERROR RETURN
08878 */
08879     *ans = 2.0e0;
08880     return;
08881 } /* END */
08882 
08883 /***=====================================================================***/
08884 static double gsumln(double *a,double *b)
08885 /*
08886 -----------------------------------------------------------------------
08887           EVALUATION OF THE FUNCTION LN(GAMMA(A + B))
08888           FOR 1 .LE. A .LE. 2  AND  1 .LE. B .LE. 2
08889 -----------------------------------------------------------------------
08890 */
08891 {
08892 static double gsumln,x,T1,T2;
08893 /*
08894      ..
08895      .. Executable Statements ..
08896 */
08897     x = *a+*b-2.e0;
08898     if(x > 0.25e0) goto S10;
08899     T1 = 1.0e0+x;
08900     gsumln = gamln1(&T1);
08901     return gsumln;
08902 S10:
08903     if(x > 1.25e0) goto S20;
08904     gsumln = gamln1(&x)+alnrel(&x);
08905     return gsumln;
08906 S20:
08907     T2 = x-1.0e0;
08908     gsumln = gamln1(&T2)+log(x*(1.0e0+x));
08909     return gsumln;
08910 } /* END */
08911 
08912 /***=====================================================================***/
08913 static double psi(double *xx)
08914 /*
08915 ---------------------------------------------------------------------
08916 
08917                  EVALUATION OF THE DIGAMMA FUNCTION
08918 
08919                            -----------
08920 
08921      PSI(XX) IS ASSIGNED THE VALUE 0 WHEN THE DIGAMMA FUNCTION CANNOT
08922      BE COMPUTED.
08923 
08924      THE MAIN COMPUTATION INVOLVES EVALUATION OF RATIONAL CHEBYSHEV
08925      APPROXIMATIONS PUBLISHED IN MATH. COMP. 27, 123-127(1973) BY
08926      CODY, STRECOK AND THACHER.
08927 
08928 ---------------------------------------------------------------------
08929      PSI WAS WRITTEN AT ARGONNE NATIONAL LABORATORY FOR THE FUNPACK
08930      PACKAGE OF SPECIAL FUNCTION SUBROUTINES. PSI WAS MODIFIED BY
08931      A.H. MORRIS (NSWC).
08932 ---------------------------------------------------------------------
08933 */
08934 {
08935 static double dx0 = 1.461632144968362341262659542325721325e0;
08936 static double piov4 = .785398163397448e0;
08937 static double p1[7] = {
08938     .895385022981970e-02,.477762828042627e+01,.142441585084029e+03,
08939     .118645200713425e+04,.363351846806499e+04,.413810161269013e+04,
08940     .130560269827897e+04
08941 };
08942 static double p2[4] = {
08943     -.212940445131011e+01,-.701677227766759e+01,-.448616543918019e+01,
08944     -.648157123766197e+00
08945 };
08946 static double q1[6] = {
08947     .448452573429826e+02,.520752771467162e+03,.221000799247830e+04,
08948     .364127349079381e+04,.190831076596300e+04,.691091682714533e-05
08949 };
08950 static double q2[4] = {
08951     .322703493791143e+02,.892920700481861e+02,.546117738103215e+02,
08952     .777788548522962e+01
08953 };
08954 static int K1 = 3;
08955 static int K2 = 1;
08956 static double psi,aug,den,sgn,upper,w,x,xmax1,xmx0,xsmall,z;
08957 static int i,m,n,nq;
08958 /*
08959      ..
08960      .. Executable Statements ..
08961 */
08962 /*
08963 ---------------------------------------------------------------------
08964      MACHINE DEPENDENT CONSTANTS ...
08965         XMAX1  = THE SMALLEST POSITIVE FLOATING POINT CONSTANT
08966                  WITH ENTIRELY INTEGER REPRESENTATION.  ALSO USED
08967                  AS NEGATIVE OF LOWER BOUND ON ACCEPTABLE NEGATIVE
08968                  ARGUMENTS AND AS THE POSITIVE ARGUMENT BEYOND WHICH
08969                  PSI MAY BE REPRESENTED AS ALOG(X).
08970         XSMALL = ABSOLUTE ARGUMENT BELOW WHICH PI*COTAN(PI*X)
08971                  MAY BE REPRESENTED BY 1/X.
08972 ---------------------------------------------------------------------
08973 */
08974     xmax1 = ipmpar(&K1);
08975     xmax1 = fifdmin1(xmax1,1.0e0/spmpar(&K2));
08976     xsmall = 1.e-9;
08977     x = *xx;
08978     aug = 0.0e0;
08979     if(x >= 0.5e0) goto S50;
08980 /*
08981 ---------------------------------------------------------------------
08982      X .LT. 0.5,  USE REFLECTION FORMULA
08983      PSI(1-X) = PSI(X) + PI * COTAN(PI*X)
08984 ---------------------------------------------------------------------
08985 */
08986     if(fabs(x) > xsmall) goto S10;
08987     if(x == 0.0e0) goto S100;
08988 /*
08989 ---------------------------------------------------------------------
08990      0 .LT. ABS(X) .LE. XSMALL.  USE 1/X AS A SUBSTITUTE
08991      FOR  PI*COTAN(PI*X)
08992 ---------------------------------------------------------------------
08993 */
08994     aug = -(1.0e0/x);
08995     goto S40;
08996 S10:
08997 /*
08998 ---------------------------------------------------------------------
08999      REDUCTION OF ARGUMENT FOR COTAN
09000 ---------------------------------------------------------------------
09001 */
09002     w = -x;
09003     sgn = piov4;
09004     if(w > 0.0e0) goto S20;
09005     w = -w;
09006     sgn = -sgn;
09007 S20:
09008 /*
09009 ---------------------------------------------------------------------
09010      MAKE AN ERROR EXIT IF X .LE. -XMAX1
09011 ---------------------------------------------------------------------
09012 */
09013     if(w >= xmax1) goto S100;
09014     nq = fifidint(w);
09015     w -= (double)nq;
09016     nq = fifidint(w*4.0e0);
09017     w = 4.0e0*(w-(double)nq*.25e0);
09018 /*
09019 ---------------------------------------------------------------------
09020      W IS NOW RELATED TO THE FRACTIONAL PART OF  4.0 * X.
09021      ADJUST ARGUMENT TO CORRESPOND TO VALUES IN FIRST
09022      QUADRANT AND DETERMINE SIGN
09023 ---------------------------------------------------------------------
09024 */
09025     n = nq/2;
09026     if(n+n != nq) w = 1.0e0-w;
09027     z = piov4*w;
09028     m = n/2;
09029     if(m+m != n) sgn = -sgn;
09030 /*
09031 ---------------------------------------------------------------------
09032      DETERMINE FINAL VALUE FOR  -PI*COTAN(PI*X)
09033 ---------------------------------------------------------------------
09034 */
09035     n = (nq+1)/2;
09036     m = n/2;
09037     m += m;
09038     if(m != n) goto S30;
09039 /*
09040 ---------------------------------------------------------------------
09041      CHECK FOR SINGULARITY
09042 ---------------------------------------------------------------------
09043 */
09044     if(z == 0.0e0) goto S100;
09045 /*
09046 ---------------------------------------------------------------------
09047      USE COS/SIN AS A SUBSTITUTE FOR COTAN, AND
09048      SIN/COS AS A SUBSTITUTE FOR TAN
09049 ---------------------------------------------------------------------
09050 */
09051     aug = sgn*(cos(z)/sin(z)*4.0e0);
09052     goto S40;
09053 S30:
09054     aug = sgn*(sin(z)/cos(z)*4.0e0);
09055 S40:
09056     x = 1.0e0-x;
09057 S50:
09058     if(x > 3.0e0) goto S70;
09059 /*
09060 ---------------------------------------------------------------------
09061      0.5 .LE. X .LE. 3.0
09062 ---------------------------------------------------------------------
09063 */
09064     den = x;
09065     upper = p1[0]*x;
09066     for(i=1; i<=5; i++) {
09067         den = (den+q1[i-1])*x;
09068         upper = (upper+p1[i+1-1])*x;
09069     }
09070     den = (upper+p1[6])/(den+q1[5]);
09071     xmx0 = x-dx0;
09072     psi = den*xmx0+aug;
09073     return psi;
09074 S70:
09075 /*
09076 ---------------------------------------------------------------------
09077      IF X .GE. XMAX1, PSI = LN(X)
09078 ---------------------------------------------------------------------
09079 */
09080     if(x >= xmax1) goto S90;
09081 /*
09082 ---------------------------------------------------------------------
09083      3.0 .LT. X .LT. XMAX1
09084 ---------------------------------------------------------------------
09085 */
09086     w = 1.0e0/(x*x);
09087     den = w;
09088     upper = p2[0]*w;
09089     for(i=1; i<=3; i++) {
09090         den = (den+q2[i-1])*w;
09091         upper = (upper+p2[i+1-1])*w;
09092     }
09093     aug = upper/(den+q2[3])-0.5e0/x+aug;
09094 S90:
09095     psi = aug+log(x);
09096     return psi;
09097 S100:
09098 /*
09099 ---------------------------------------------------------------------
09100      ERROR RETURN
09101 ---------------------------------------------------------------------
09102 */
09103     psi = 0.0e0;
09104     return psi;
09105 } /* END */
09106 
09107 /***=====================================================================***/
09108 static double rcomp(double *a,double *x)
09109 /*
09110      -------------------
09111      EVALUATION OF EXP(-X)*X**A/GAMMA(A)
09112      -------------------
09113      RT2PIN = 1/SQRT(2*PI)
09114      -------------------
09115 */
09116 {
09117 static double rt2pin = .398942280401433e0;
09118 static double rcomp,t,t1,u;
09119 /*
09120      ..
09121      .. Executable Statements ..
09122 */
09123     rcomp = 0.0e0;
09124     if(*a >= 20.0e0) goto S20;
09125     t = *a*log(*x)-*x;
09126     if(*a >= 1.0e0) goto S10;
09127     rcomp = *a*exp(t)*(1.0e0+gam1(a));
09128     return rcomp;
09129 S10:
09130     rcomp = exp(t)/Xgamm(a);
09131     return rcomp;
09132 S20:
09133     u = *x/ *a;
09134     if(u == 0.0e0) return rcomp;
09135     t = pow(1.0e0/ *a,2.0);
09136     t1 = (((0.75e0*t-1.0e0)*t+3.5e0)*t-105.0e0)/(*a*1260.0e0);
09137     t1 -= (*a*rlog(&u));
09138     rcomp = rt2pin*sqrt(*a)*exp(t1);
09139     return rcomp;
09140 } /* END */
09141 
09142 /***=====================================================================***/
09143 static double rexp(double *x)
09144 /*
09145 -----------------------------------------------------------------------
09146             EVALUATION OF THE FUNCTION EXP(X) - 1
09147 -----------------------------------------------------------------------
09148 */
09149 {
09150 static double p1 = .914041914819518e-09;
09151 static double p2 = .238082361044469e-01;
09152 static double q1 = -.499999999085958e+00;
09153 static double q2 = .107141568980644e+00;
09154 static double q3 = -.119041179760821e-01;
09155 static double q4 = .595130811860248e-03;
09156 static double rexp,w;
09157 /*
09158      ..
09159      .. Executable Statements ..
09160 */
09161     if(fabs(*x) > 0.15e0) goto S10;
09162     rexp = *x*(((p2**x+p1)**x+1.0e0)/((((q4**x+q3)**x+q2)**x+q1)**x+1.0e0));
09163     return rexp;
09164 S10:
09165     w = exp(*x);
09166     if(*x > 0.0e0) goto S20;
09167     rexp = w-0.5e0-0.5e0;
09168     return rexp;
09169 S20:
09170     rexp = w*(0.5e0+(0.5e0-1.0e0/w));
09171     return rexp;
09172 } /* END */
09173 
09174 /***=====================================================================***/
09175 static double rlog(double *x)
09176 /*
09177      -------------------
09178      COMPUTATION OF  X - 1 - LN(X)
09179      -------------------
09180 */
09181 {
09182 static double a = .566749439387324e-01;
09183 static double b = .456512608815524e-01;
09184 static double p0 = .333333333333333e+00;
09185 static double p1 = -.224696413112536e+00;
09186 static double p2 = .620886815375787e-02;
09187 static double q1 = -.127408923933623e+01;
09188 static double q2 = .354508718369557e+00;
09189 static double rlog,r,t,u,w,w1;
09190 /*
09191      ..
09192      .. Executable Statements ..
09193 */
09194     if(*x < 0.61e0 || *x > 1.57e0) goto S40;
09195     if(*x < 0.82e0) goto S10;
09196     if(*x > 1.18e0) goto S20;
09197 /*
09198               ARGUMENT REDUCTION
09199 */
09200     u = *x-0.5e0-0.5e0;
09201     w1 = 0.0e0;
09202     goto S30;
09203 S10:
09204     u = *x-0.7e0;
09205     u /= 0.7e0;
09206     w1 = a-u*0.3e0;
09207     goto S30;
09208 S20:
09209     u = 0.75e0**x-1.e0;
09210     w1 = b+u/3.0e0;
09211 S30:
09212 /*
09213                SERIES EXPANSION
09214 */
09215     r = u/(u+2.0e0);
09216     t = r*r;
09217     w = ((p2*t+p1)*t+p0)/((q2*t+q1)*t+1.0e0);
09218     rlog = 2.0e0*t*(1.0e0/(1.0e0-r)-r*w)+w1;
09219     return rlog;
09220 S40:
09221     r = *x-0.5e0-0.5e0;
09222     rlog = r-log(*x);
09223     return rlog;
09224 } /* END */
09225 
09226 /***=====================================================================***/
09227 static double rlog1(double *x)
09228 /*
09229 -----------------------------------------------------------------------
09230              EVALUATION OF THE FUNCTION X - LN(1 + X)
09231 -----------------------------------------------------------------------
09232 */
09233 {
09234 static double a = .566749439387324e-01;
09235 static double b = .456512608815524e-01;
09236 static double p0 = .333333333333333e+00;
09237 static double p1 = -.224696413112536e+00;
09238 static double p2 = .620886815375787e-02;
09239 static double q1 = -.127408923933623e+01;
09240 static double q2 = .354508718369557e+00;
09241 static double rlog1,h,r,t,w,w1;
09242 /*
09243      ..
09244      .. Executable Statements ..
09245 */
09246     if(*x < -0.39e0 || *x > 0.57e0) goto S40;
09247     if(*x < -0.18e0) goto S10;
09248     if(*x > 0.18e0) goto S20;
09249 /*
09250               ARGUMENT REDUCTION
09251 */
09252     h = *x;
09253     w1 = 0.0e0;
09254     goto S30;
09255 S10:
09256     h = *x+0.3e0;
09257     h /= 0.7e0;
09258     w1 = a-h*0.3e0;
09259     goto S30;
09260 S20:
09261     h = 0.75e0**x-0.25e0;
09262     w1 = b+h/3.0e0;
09263 S30:
09264 /*
09265                SERIES EXPANSION
09266 */
09267     r = h/(h+2.0e0);
09268     t = r*r;
09269     w = ((p2*t+p1)*t+p0)/((q2*t+q1)*t+1.0e0);
09270     rlog1 = 2.0e0*t*(1.0e0/(1.0e0-r)-r*w)+w1;
09271     return rlog1;
09272 S40:
09273     w = *x+0.5e0+0.5e0;
09274     rlog1 = *x-log(w);
09275     return rlog1;
09276 } /* END */
09277 
09278 /***=====================================================================***/
09279 static double spmpar(int *i)
09280 /*
09281 -----------------------------------------------------------------------
09282 
09283      SPMPAR PROVIDES THE SINGLE PRECISION MACHINE CONSTANTS FOR
09284      THE COMPUTER BEING USED. IT IS ASSUMED THAT THE ARGUMENT
09285      I IS AN INTEGER HAVING ONE OF THE VALUES 1, 2, OR 3. IF THE
09286      SINGLE PRECISION ARITHMETIC BEING USED HAS M BASE B DIGITS AND
09287      ITS SMALLEST AND LARGEST EXPONENTS ARE EMIN AND EMAX, THEN
09288 
09289         SPMPAR(1) = B**(1 - M), THE MACHINE PRECISION,
09290 
09291         SPMPAR(2) = B**(EMIN - 1), THE SMALLEST MAGNITUDE,
09292 
09293         SPMPAR(3) = B**EMAX*(1 - B**(-M)), THE LARGEST MAGNITUDE.
09294 
09295 -----------------------------------------------------------------------
09296      WRITTEN BY
09297         ALFRED H. MORRIS, JR.
09298         NAVAL SURFACE WARFARE CENTER
09299         DAHLGREN VIRGINIA
09300 -----------------------------------------------------------------------
09301 -----------------------------------------------------------------------
09302      MODIFIED BY BARRY W. BROWN TO RETURN DOUBLE PRECISION MACHINE
09303      CONSTANTS FOR THE COMPUTER BEING USED.  THIS MODIFICATION WAS
09304      MADE AS PART OF CONVERTING BRATIO TO DOUBLE PRECISION
09305 -----------------------------------------------------------------------
09306 */
09307 {
09308 static int K1 = 4;
09309 static int K2 = 8;
09310 static int K3 = 9;
09311 static int K4 = 10;
09312 static double spmpar,b,binv,bm1,one,w,z;
09313 static int emax,emin,ibeta,m;
09314 /*
09315      ..
09316      .. Executable Statements ..
09317 */
09318     if(*i > 1) goto S10;
09319     b = ipmpar(&K1);
09320     m = ipmpar(&K2);
09321     spmpar = pow(b,(double)(1-m));
09322     return spmpar;
09323 S10:
09324     if(*i > 2) goto S20;
09325     b = ipmpar(&K1);
09326     emin = ipmpar(&K3);
09327     one = 1.0;
09328     binv = one/b;
09329     w = pow(b,(double)(emin+2));
09330     spmpar = w*binv*binv*binv;
09331     return spmpar;
09332 S20:
09333     ibeta = ipmpar(&K1);
09334     m = ipmpar(&K2);
09335     emax = ipmpar(&K4);
09336     b = ibeta;
09337     bm1 = ibeta-1;
09338     one = 1.0;
09339     z = pow(b,(double)(m-1));
09340     w = ((z-one)*b+bm1)/(b*z);
09341     z = pow(b,(double)(emax-2));
09342     spmpar = w*z*b*b;
09343     return spmpar;
09344 } /* END */
09345 
09346 /***=====================================================================***/
09347 static double stvaln(double *p)
09348 /*
09349 **********************************************************************
09350 
09351      double stvaln(double *p)
09352                     STarting VALue for Neton-Raphon
09353                 calculation of Normal distribution Inverse
09354 
09355 
09356                               Function
09357 
09358 
09359      Returns X  such that CUMNOR(X)  =   P,  i.e., the  integral from -
09360      infinity to X of (1/SQRT(2*PI)) EXP(-U*U/2) dU is P
09361 
09362 
09363                               Arguments
09364 
09365 
09366      P --> The probability whose normal deviate is sought.
09367                     P is DOUBLE PRECISION
09368 
09369 
09370                               Method
09371 
09372 
09373      The  rational   function   on  page 95    of Kennedy  and  Gentle,
09374      Statistical Computing, Marcel Dekker, NY , 1980.
09375 
09376 **********************************************************************
09377 */
09378 {
09379 static double xden[5] = {
09380     0.993484626060e-1,0.588581570495e0,0.531103462366e0,0.103537752850e0,
09381     0.38560700634e-2
09382 };
09383 static double xnum[5] = {
09384     -0.322232431088e0,-1.000000000000e0,-0.342242088547e0,-0.204231210245e-1,
09385     -0.453642210148e-4
09386 };
09387 static int K1 = 5;
09388 static double stvaln,sign,y,z;
09389 /*
09390      ..
09391      .. Executable Statements ..
09392 */
09393     if(!(*p <= 0.5e0)) goto S10;
09394     sign = -1.0e0;
09395     z = *p;
09396     goto S20;
09397 S10:
09398     sign = 1.0e0;
09399     z = 1.0e0-*p;
09400 S20:
09401     y = sqrt(-(2.0e0*log(z)));
09402     stvaln = y+devlpl(xnum,&K1,&y)/devlpl(xden,&K1,&y);
09403     stvaln = sign*stvaln;
09404     return stvaln;
09405 } /* END */
09406 
09407 /***=====================================================================***/
09408 static double fifdint(double a)
09409 /************************************************************************
09410 FIFDINT:
09411 Truncates a double precision number to an integer and returns the
09412 value in a double.
09413 ************************************************************************/
09414 /* a     -     number to be truncated */
09415 {
09416   return (double) ((int) a);
09417 } /* END */
09418 
09419 /***=====================================================================***/
09420 static double fifdmax1(double a,double b)
09421 /************************************************************************
09422 FIFDMAX1:
09423 returns the maximum of two numbers a and b
09424 ************************************************************************/
09425 /* a     -      first number */
09426 /* b     -      second number */
09427 {
09428   if (a < b) return b;
09429   else return a;
09430 } /* END */
09431 
09432 /***=====================================================================***/
09433 static double fifdmin1(double a,double b)
09434 /************************************************************************
09435 FIFDMIN1:
09436 returns the minimum of two numbers a and b
09437 ************************************************************************/
09438 /* a     -     first number */
09439 /* b     -     second number */
09440 {
09441   if (a < b) return a;
09442   else return b;
09443 } /* END */
09444 
09445 /***=====================================================================***/
09446 static double fifdsign(double mag,double sign)
09447 /************************************************************************
09448 FIFDSIGN:
09449 transfers the sign of the variable "sign" to the variable "mag"
09450 ************************************************************************/
09451 /* mag     -     magnitude */
09452 /* sign    -     sign to be transfered */
09453 {
09454   if (mag < 0) mag = -mag;
09455   if (sign < 0) mag = -mag;
09456   return mag;
09457 
09458 } /* END */
09459 
09460 /***=====================================================================***/
09461 static long fifidint(double a)
09462 /************************************************************************
09463 FIFIDINT:
09464 Truncates a double precision number to a long integer
09465 ************************************************************************/
09466 /* a - number to be truncated */
09467 {
09468   if (a < 1.0) return (long) 0;
09469   else return (long) a;
09470 } /* END */
09471 
09472 /***=====================================================================***/
09473 static long fifmod(long a,long b)
09474 /************************************************************************
09475 FIFMOD:
09476 returns the modulo of a and b
09477 ************************************************************************/
09478 /* a - numerator */
09479 /* b - denominator */
09480 {
09481   return a % b;
09482 } /* END */
09483 
09484 /***=====================================================================***/
09485 static void ftnstop(char* msg)
09486 /************************************************************************
09487 FTNSTOP:
09488 Prints msg to standard error and then exits
09489 ************************************************************************/
09490 /* msg - error message */
09491 {
09492   if (msg != NULL) fprintf(stderr,"*** CDFLIB ERROR: %s\n",msg);
09493   /** exit(1); **/  /** RWCox - DON'T EXIT */
09494 } /* END */
09495 
09496 /***=====================================================================***/
09497 static int ipmpar(int *i)
09498 /*
09499 -----------------------------------------------------------------------
09500 
09501      IPMPAR PROVIDES THE INTEGER MACHINE CONSTANTS FOR THE COMPUTER
09502      THAT IS USED. IT IS ASSUMED THAT THE ARGUMENT I IS AN INTEGER
09503      HAVING ONE OF THE VALUES 1-10. IPMPAR(I) HAS THE VALUE ...
09504 
09505   INTEGERS.
09506 
09507      ASSUME INTEGERS ARE REPRESENTED IN THE N-DIGIT, BASE-A FORM
09508 
09509                SIGN ( X(N-1)*A**(N-1) + ... + X(1)*A + X(0) )
09510 
09511                WHERE 0 .LE. X(I) .LT. A FOR I=0,...,N-1.
09512 
09513      IPMPAR(1) = A, THE BASE.
09514 
09515      IPMPAR(2) = N, THE NUMBER OF BASE-A DIGITS.
09516 
09517      IPMPAR(3) = A**N - 1, THE LARGEST MAGNITUDE.
09518 
09519   FLOATING-POINT NUMBERS.
09520 
09521      IT IS ASSUMED THAT THE SINGLE AND DOUBLE PRECISION FLOATING
09522      POINT ARITHMETICS HAVE THE SAME BASE, SAY B, AND THAT THE
09523      NONZERO NUMBERS ARE REPRESENTED IN THE FORM
09524 
09525                SIGN (B**E) * (X(1)/B + ... + X(M)/B**M)
09526 
09527                WHERE X(I) = 0,1,...,B-1 FOR I=1,...,M,
09528                X(1) .GE. 1, AND EMIN .LE. E .LE. EMAX.
09529 
09530      IPMPAR(4) = B, THE BASE.
09531 
09532   SINGLE-PRECISION
09533 
09534      IPMPAR(5) = M, THE NUMBER OF BASE-B DIGITS.
09535 
09536      IPMPAR(6) = EMIN, THE SMALLEST EXPONENT E.
09537 
09538      IPMPAR(7) = EMAX, THE LARGEST EXPONENT E.
09539 
09540   DOUBLE-PRECISION
09541 
09542      IPMPAR(8) = M, THE NUMBER OF BASE-B DIGITS.
09543 
09544      IPMPAR(9) = EMIN, THE SMALLEST EXPONENT E.
09545 
09546      IPMPAR(10) = EMAX, THE LARGEST EXPONENT E.
09547 
09548 -----------------------------------------------------------------------
09549 
09550      TO DEFINE THIS FUNCTION FOR THE COMPUTER BEING USED REMOVE
09551      THE COMMENT DELIMITORS FROM THE DEFINITIONS DIRECTLY BELOW THE NAME
09552      OF THE MACHINE
09553 
09554 *** RWCox: at this time, the IEEE parameters are enabled.
09555 
09556 -----------------------------------------------------------------------
09557 
09558      IPMPAR IS AN ADAPTATION OF THE FUNCTION I1MACH, WRITTEN BY
09559      P.A. FOX, A.D. HALL, AND N.L. SCHRYER (BELL LABORATORIES).
09560      IPMPAR WAS FORMED BY A.H. MORRIS (NSWC). THE CONSTANTS ARE
09561      FROM BELL LABORATORIES, NSWC, AND OTHER SOURCES.
09562 
09563 -----------------------------------------------------------------------
09564      .. Scalar Arguments ..
09565 */
09566 {
09567 static int imach[11];
09568 static int outval ;
09569 /*     MACHINE CONSTANTS FOR AMDAHL MACHINES. */
09570 /*
09571    imach[1] = 2;
09572    imach[2] = 31;
09573    imach[3] = 2147483647;
09574    imach[4] = 16;
09575    imach[5] = 6;
09576    imach[6] = -64;
09577    imach[7] = 63;
09578    imach[8] = 14;
09579    imach[9] = -64;
09580    imach[10] = 63;
09581 */
09582 /*     MACHINE CONSTANTS FOR THE AT&T 3B SERIES, AT&T
09583        PC 7300, AND AT&T 6300. */
09584 /*
09585    imach[1] = 2;
09586    imach[2] = 31;
09587    imach[3] = 2147483647;
09588    imach[4] = 2;
09589    imach[5] = 24;
09590    imach[6] = -125;
09591    imach[7] = 128;
09592    imach[8] = 53;
09593    imach[9] = -1021;
09594    imach[10] = 1024;
09595 */
09596 /*     MACHINE CONSTANTS FOR THE BURROUGHS 1700 SYSTEM. */
09597 /*
09598    imach[1] = 2;
09599    imach[2] = 33;
09600    imach[3] = 8589934591;
09601    imach[4] = 2;
09602    imach[5] = 24;
09603    imach[6] = -256;
09604    imach[7] = 255;
09605    imach[8] = 60;
09606    imach[9] = -256;
09607    imach[10] = 255;
09608 */
09609 /*     MACHINE CONSTANTS FOR THE BURROUGHS 5700 SYSTEM. */
09610 /*
09611    imach[1] = 2;
09612    imach[2] = 39;
09613    imach[3] = 549755813887;
09614    imach[4] = 8;
09615    imach[5] = 13;
09616    imach[6] = -50;
09617    imach[7] = 76;
09618    imach[8] = 26;
09619    imach[9] = -50;
09620    imach[10] = 76;
09621 */
09622 /*     MACHINE CONSTANTS FOR THE BURROUGHS 6700/7700 SYSTEMS. */
09623 /*
09624    imach[1] = 2;
09625    imach[2] = 39;
09626    imach[3] = 549755813887;
09627    imach[4] = 8;
09628    imach[5] = 13;
09629    imach[6] = -50;
09630    imach[7] = 76;
09631    imach[8] = 26;
09632    imach[9] = -32754;
09633    imach[10] = 32780;
09634 */
09635 /*     MACHINE CONSTANTS FOR THE CDC 6000/7000 SERIES
09636        60 BIT ARITHMETIC, AND THE CDC CYBER 995 64 BIT
09637        ARITHMETIC (NOS OPERATING SYSTEM). */
09638 /*
09639    imach[1] = 2;
09640    imach[2] = 48;
09641    imach[3] = 281474976710655;
09642    imach[4] = 2;
09643    imach[5] = 48;
09644    imach[6] = -974;
09645    imach[7] = 1070;
09646    imach[8] = 95;
09647    imach[9] = -926;
09648    imach[10] = 1070;
09649 */
09650 /*     MACHINE CONSTANTS FOR THE CDC CYBER 995 64 BIT
09651        ARITHMETIC (NOS/VE OPERATING SYSTEM). */
09652 /*
09653    imach[1] = 2;
09654    imach[2] = 63;
09655    imach[3] = 9223372036854775807;
09656    imach[4] = 2;
09657    imach[5] = 48;
09658    imach[6] = -4096;
09659    imach[7] = 4095;
09660    imach[8] = 96;
09661    imach[9] = -4096;
09662    imach[10] = 4095;
09663 */
09664 /*     MACHINE CONSTANTS FOR THE CRAY 1, XMP, 2, AND 3. */
09665 /*
09666    imach[1] = 2;
09667    imach[2] = 63;
09668    imach[3] = 9223372036854775807;
09669    imach[4] = 2;
09670    imach[5] = 47;
09671    imach[6] = -8189;
09672    imach[7] = 8190;
09673    imach[8] = 94;
09674    imach[9] = -8099;
09675    imach[10] = 8190;
09676 */
09677 /*     MACHINE CONSTANTS FOR THE DATA GENERAL ECLIPSE S/200. */
09678 /*
09679    imach[1] = 2;
09680    imach[2] = 15;
09681    imach[3] = 32767;
09682    imach[4] = 16;
09683    imach[5] = 6;
09684    imach[6] = -64;
09685    imach[7] = 63;
09686    imach[8] = 14;
09687    imach[9] = -64;
09688    imach[10] = 63;
09689 */
09690 /*     MACHINE CONSTANTS FOR THE HARRIS 220. */
09691 /*
09692    imach[1] = 2;
09693    imach[2] = 23;
09694    imach[3] = 8388607;
09695    imach[4] = 2;
09696    imach[5] = 23;
09697    imach[6] = -127;
09698    imach[7] = 127;
09699    imach[8] = 38;
09700    imach[9] = -127;
09701    imach[10] = 127;
09702 */
09703 /*     MACHINE CONSTANTS FOR THE HONEYWELL 600/6000
09704        AND DPS 8/70 SERIES. */
09705 /*
09706    imach[1] = 2;
09707    imach[2] = 35;
09708    imach[3] = 34359738367;
09709    imach[4] = 2;
09710    imach[5] = 27;
09711    imach[6] = -127;
09712    imach[7] = 127;
09713    imach[8] = 63;
09714    imach[9] = -127;
09715    imach[10] = 127;
09716 */
09717 /*     MACHINE CONSTANTS FOR THE HP 2100
09718        3 WORD DOUBLE PRECISION OPTION WITH FTN4 */
09719 /*
09720    imach[1] = 2;
09721    imach[2] = 15;
09722    imach[3] = 32767;
09723    imach[4] = 2;
09724    imach[5] = 23;
09725    imach[6] = -128;
09726    imach[7] = 127;
09727    imach[8] = 39;
09728    imach[9] = -128;
09729    imach[10] = 127;
09730 */
09731 /*     MACHINE CONSTANTS FOR THE HP 2100
09732        4 WORD DOUBLE PRECISION OPTION WITH FTN4 */
09733 /*
09734    imach[1] = 2;
09735    imach[2] = 15;
09736    imach[3] = 32767;
09737    imach[4] = 2;
09738    imach[5] = 23;
09739    imach[6] = -128;
09740    imach[7] = 127;
09741    imach[8] = 55;
09742    imach[9] = -128;
09743    imach[10] = 127;
09744 */
09745 /*     MACHINE CONSTANTS FOR THE HP 9000. */
09746 /*
09747    imach[1] = 2;
09748    imach[2] = 31;
09749    imach[3] = 2147483647;
09750    imach[4] = 2;
09751    imach[5] = 24;
09752    imach[6] = -126;
09753    imach[7] = 128;
09754    imach[8] = 53;
09755    imach[9] = -1021;
09756    imach[10] = 1024;
09757 */
09758 /*     MACHINE CONSTANTS FOR THE IBM 360/370 SERIES,
09759        THE ICL 2900, THE ITEL AS/6, THE XEROX SIGMA
09760        5/7/9 AND THE SEL SYSTEMS 85/86. */
09761 /*
09762    imach[1] = 2;
09763    imach[2] = 31;
09764    imach[3] = 2147483647;
09765    imach[4] = 16;
09766    imach[5] = 6;
09767    imach[6] = -64;
09768    imach[7] = 63;
09769    imach[8] = 14;
09770    imach[9] = -64;
09771    imach[10] = 63;
09772 */
09773 /*     MACHINE CONSTANTS FOR THE IBM PC. */
09774 /*
09775    imach[1] = 2;
09776    imach[2] = 31;
09777    imach[3] = 2147483647;
09778    imach[4] = 2;
09779    imach[5] = 24;
09780    imach[6] = -125;
09781    imach[7] = 128;
09782    imach[8] = 53;
09783    imach[9] = -1021;
09784    imach[10] = 1024;
09785 */
09786 /*     MACHINE CONSTANTS FOR THE MACINTOSH II - ABSOFT
09787        MACFORTRAN II. */
09788 /*
09789    imach[1] = 2;
09790    imach[2] = 31;
09791    imach[3] = 2147483647;
09792    imach[4] = 2;
09793    imach[5] = 24;
09794    imach[6] = -125;
09795    imach[7] = 128;
09796    imach[8] = 53;
09797    imach[9] = -1021;
09798    imach[10] = 1024;
09799 */
09800 /*     MACHINE CONSTANTS FOR THE MICROVAX - VMS FORTRAN. */
09801 /*
09802    imach[1] = 2;
09803    imach[2] = 31;
09804    imach[3] = 2147483647;
09805    imach[4] = 2;
09806    imach[5] = 24;
09807    imach[6] = -127;
09808    imach[7] = 127;
09809    imach[8] = 56;
09810    imach[9] = -127;
09811    imach[10] = 127;
09812 */
09813 /*     MACHINE CONSTANTS FOR THE PDP-10 (KA PROCESSOR). */
09814 /*
09815    imach[1] = 2;
09816    imach[2] = 35;
09817    imach[3] = 34359738367;
09818    imach[4] = 2;
09819    imach[5] = 27;
09820    imach[6] = -128;
09821    imach[7] = 127;
09822    imach[8] = 54;
09823    imach[9] = -101;
09824    imach[10] = 127;
09825 */
09826 /*     MACHINE CONSTANTS FOR THE PDP-10 (KI PROCESSOR). */
09827 /*
09828    imach[1] = 2;
09829    imach[2] = 35;
09830    imach[3] = 34359738367;
09831    imach[4] = 2;
09832    imach[5] = 27;
09833    imach[6] = -128;
09834    imach[7] = 127;
09835    imach[8] = 62;
09836    imach[9] = -128;
09837    imach[10] = 127;
09838 */
09839 /*     MACHINE CONSTANTS FOR THE PDP-11 FORTRAN SUPPORTING
09840        32-BIT INTEGER ARITHMETIC. */
09841 /*
09842    imach[1] = 2;
09843    imach[2] = 31;
09844    imach[3] = 2147483647;
09845    imach[4] = 2;
09846    imach[5] = 24;
09847    imach[6] = -127;
09848    imach[7] = 127;
09849    imach[8] = 56;
09850    imach[9] = -127;
09851    imach[10] = 127;
09852 */
09853 /*     MACHINE CONSTANTS FOR THE SEQUENT BALANCE 8000. */
09854 /*
09855    imach[1] = 2;
09856    imach[2] = 31;
09857    imach[3] = 2147483647;
09858    imach[4] = 2;
09859    imach[5] = 24;
09860    imach[6] = -125;
09861    imach[7] = 128;
09862    imach[8] = 53;
09863    imach[9] = -1021;
09864    imach[10] = 1024;
09865 */
09866 /*     MACHINE CONSTANTS FOR THE SILICON GRAPHICS IRIS-4D
09867        SERIES (MIPS R3000 PROCESSOR). */
09868 /*
09869    imach[1] = 2;
09870    imach[2] = 31;
09871    imach[3] = 2147483647;
09872    imach[4] = 2;
09873    imach[5] = 24;
09874    imach[6] = -125;
09875    imach[7] = 128;
09876    imach[8] = 53;
09877    imach[9] = -1021;
09878    imach[10] = 1024;
09879 */
09880 /*     MACHINE CONSTANTS FOR IEEE ARITHMETIC MACHINES, SUCH AS THE AT&T
09881        3B SERIES, MOTOROLA 68000 BASED MACHINES (E.G. SUN 3 AND AT&T
09882        PC 7300), AND 8087 BASED MICROS (E.G. IBM PC AND AT&T 6300). */
09883 
09884    imach[1] = 2;
09885    imach[2] = 31;
09886    imach[3] = 2147483647;
09887    imach[4] = 2;
09888    imach[5] = 24;
09889    imach[6] = -125;
09890    imach[7] = 128;
09891    imach[8] = 53;
09892    imach[9] = -1021;
09893    imach[10] = 1024;
09894 
09895 /*     MACHINE CONSTANTS FOR THE UNIVAC 1100 SERIES. */
09896 /*
09897    imach[1] = 2;
09898    imach[2] = 35;
09899    imach[3] = 34359738367;
09900    imach[4] = 2;
09901    imach[5] = 27;
09902    imach[6] = -128;
09903    imach[7] = 127;
09904    imach[8] = 60;
09905    imach[9] = -1024;
09906    imach[10] = 1023;
09907 */
09908 /*     MACHINE CONSTANTS FOR THE VAX 11/780. */
09909 /*
09910    imach[1] = 2;
09911    imach[2] = 31;
09912    imach[3] = 2147483647;
09913    imach[4] = 2;
09914    imach[5] = 24;
09915    imach[6] = -127;
09916    imach[7] = 127;
09917    imach[8] = 56;
09918    imach[9] = -127;
09919    imach[10] = 127;
09920 */
09921     outval  = imach[*i];
09922     return outval ;
09923 }
09924 
09925 /*************************************************************************/
09926 /*************************************************************************/
09927 /************************ End of cdflib inclusion ************************/
09928 /*************************************************************************/
09929 /*************************************************************************/
09930 
09931 /*-----------------------------------------------------------------------*/
09932 typedef struct { double p,q ; } pqpair ;  /* for returning p=cdf q=1-cdf */
09933 /*-----------------------------------------------------------------------*/
09934 #undef  BIGG
09935 #define BIGG 9.99e+37                     /* a really big number (duh)   */
09936 /*-----------------------------------------------------------------------*/
09937 
09938 /*************************************************************************/
09939 /******** Internal functions for various statistical computations ********/
09940 /*************************************************************************/
09941 
09942 /*---------------------------------------------------------------
09943   F statistic
09944 -----------------------------------------------------------------*/
09945 
09946 static double fstat_pq2s( pqpair pq , double dofnum , double dofden )
09947 {
09948    int which , status ;
09949    double p , q , f , dfn , dfd , bound ;
09950 
09951    which  = 2 ;
09952    p      = pq.p ; if( p <= 0.0 ) return 0.0 ;
09953    q      = pq.q ; if( q <= 0.0 ) return BIGG ;
09954    f      = 0.0 ;
09955    dfn    = dofnum ;
09956    dfd    = dofden ;
09957 
09958    cdff( &which , &p , &q , &f , &dfn , &dfd , &status , &bound ) ;
09959    return f ;
09960 }
09961 
09962 /*------------------------------*/
09963 
09964 static pqpair fstat_s2pq( double ff , double dofnum , double dofden )
09965 {
09966    int which , status ;
09967    double p , q , f , dfn , dfd , bound ;
09968    pqpair pq={0.0,1.0} ;
09969 
09970    which  = 1 ;
09971    p      = 0.0 ;
09972    q      = 1.0 ;
09973    f      = ff ;     if( f   <= 0.0 ) return pq;
09974    dfn    = dofnum ; if( dfn <= 0.0 ) return pq ;
09975    dfd    = dofden ; if( dfd <= 0.0 ) return pq ;
09976 
09977    cdff( &which , &p , &q , &f , &dfn , &dfd , &status , &bound ) ;
09978    pq.p = p ; pq.q = q ; return pq ;
09979 }
09980 
09981 /*---------------------------------------------------------------
09982   noncentral F statistic
09983 -----------------------------------------------------------------*/
09984 
09985 static double fnonc_pq2s( pqpair pq , double dofnum , double dofden , double nonc )
09986 {
09987    int which , status ;
09988    double p , q , f , dfn , dfd , bound , pnonc ;
09989 
09990    which  = 2 ;
09991    p      = pq.p ;   if( p <= 0.0 ) return 0.0 ;
09992    q      = pq.q ;   if( q <= 0.0 ) return BIGG ;
09993    f      = 0.0 ;
09994    dfn    = dofnum ;
09995    dfd    = dofden ;
09996    pnonc  = nonc ;
09997 
09998    cdffnc( &which , &p , &q , &f , &dfn , &dfd , &pnonc , &status , &bound ) ;
09999    return f ;
10000 }
10001 
10002 /*------------------------------*/
10003 
10004 static pqpair fnonc_s2pq( double ff , double dofnum , double dofden , double nonc )
10005 {
10006    int which , status ;
10007    double p , q , f , dfn , dfd , bound , pnonc ;
10008    pqpair pq={0.0,1.0} ;
10009 
10010    which  = 1 ;
10011    p      = 0.0 ;
10012    q      = 1.0 ;
10013    f      = ff ;     if(   f   <= 0.0 ) return pq ;
10014    dfn    = dofnum ; if( dfn   <= 0.0 ) return pq ;
10015    dfd    = dofden ; if( dfd   <= 0.0 ) return pq ;
10016    pnonc  = nonc ;   if( pnonc <  0.0 ) return pq ;
10017 
10018    cdffnc( &which , &p , &q , &f , &dfn , &dfd , &pnonc , &status , &bound ) ;
10019    pq.p = p ; pq.q = q ; return pq ;
10020 }
10021 
10022 /*---------------------------------------------------------------
10023   Standard Normal distribution
10024 -----------------------------------------------------------------*/
10025 
10026 static pqpair normal_s2pq( double zz )
10027 {
10028    double p , q , x=zz ;
10029    pqpair pq ;
10030 
10031    cumnor( &x, &p, &q ) ;
10032    pq.p = p ; pq.q = q ; return pq ;
10033 }
10034 
10035 /*------------------------------*/
10036 
10037 static double normal_pq2s( pqpair pq )
10038 {
10039    double p=pq.p , q=pq.q ;
10040 
10041    if( p <= 0.0 ) return -BIGG ;
10042    if( q <= 0.0 ) return  BIGG ;
10043    return dinvnr( &p,&q ) ;
10044 }
10045 
10046 /*----------------------------------------------------------------
10047    Chi-square
10048 ------------------------------------------------------------------*/
10049 
10050 static pqpair chisq_s2pq( double xx , double dof )
10051 {
10052    int which , status ;
10053    double p,q,x,df,bound ;
10054    pqpair pq={0.0,1.0} ;
10055 
10056    which  = 1 ;
10057    p      = 0.0 ;
10058    q      = 1.0 ;
10059    x      = xx ;  if(   x <= 0.0 ) return pq ;
10060    df     = dof ; if( dof <= 0.0 ) return pq ;
10061 
10062    cdfchi( &which , &p , &q , &x , &df , &status , &bound ) ;
10063    pq.p = p ; pq.q = q ; return pq ;
10064 }
10065 
10066 /*------------------------------*/
10067 
10068 static double chisq_pq2s( pqpair pq , double dof )
10069 {
10070    int which , status ;
10071    double p,q,x,df,bound ;
10072 
10073    which  = 2 ;
10074    p      = pq.p ; if( p <= 0.0 ) return  0.0 ;
10075    q      = pq.q ; if( q <= 0.0 ) return BIGG ;
10076    x      = 0.0 ;
10077    df     = dof ;
10078 
10079    cdfchi( &which , &p , &q , &x , &df , &status , &bound ) ;
10080    return x ;
10081 }
10082 
10083 /*----------------------------------------------------------------
10084    noncentral Chi-square
10085 ------------------------------------------------------------------*/
10086 
10087 static pqpair chsqnonc_s2pq( double xx , double dof , double nonc )
10088 {
10089    int which , status ;
10090    double p,q,x,df,bound , pnonc ;
10091    pqpair pq={0.0,1.0} ;
10092 
10093    which  = 1 ;
10094    p      = 0.0 ;
10095    q      = 1.0 ;
10096    x      = xx ;   if( x     <= 0.0 ) return pq ;
10097    df     = dof ;  if( df    <= 0.0 ) return pq ;
10098    pnonc  = nonc ; if( pnonc <  0.0 ) return pq ;
10099 
10100    cdfchn( &which , &p , &q , &x , &df , &pnonc , &status , &bound ) ;
10101    pq.p = p ; pq.q = q ; return pq ;
10102 }
10103 
10104 /*------------------------------*/
10105 
10106 static double chsqnonc_pq2s( pqpair pq , double dof , double nonc )
10107 {
10108    int which , status ;
10109    double p,q,x,df,bound , pnonc ;
10110 
10111    which  = 2 ;
10112    p      = pq.p ; if( p <= 0.0 ) return  0.0 ;
10113    q      = pq.q ; if( q <= 0.0 ) return BIGG ;
10114    x      = 0.0 ;
10115    df     = dof ;
10116    pnonc  = nonc ;
10117 
10118    cdfchn( &which , &p , &q , &x , &df , &pnonc , &status , &bound ) ;
10119    return x ;
10120 }
10121 
10122 /*----------------------------------------------------------------
10123    Beta distribution
10124 ------------------------------------------------------------------*/
10125 
10126 static pqpair beta_s2pq( double xx , double aa , double bb )
10127 {
10128    int which , status ;
10129    double p,q,x,y,a,b,bound ;
10130    pqpair pq={0.0,1.0} ;
10131 
10132    which  = 1 ;
10133    p      = 0.0 ;
10134    q      = 1.0 ;
10135    x      = xx ;       if( x <= 0.0 ) return pq ;
10136    y      = 1.0 - xx ; if( y <= 0.0 ){ pq.p=1.0; pq.q=0.0; return pq; }
10137    a      = aa ;       if( a <  0.0 ) return pq ;
10138    b      = bb ;       if( b <  0.0 ) return pq ;
10139 
10140    cdfbet( &which , &p , &q , &x , &y , &a , &b ,  &status , &bound ) ;
10141    pq.p = p ; pq.q = q ; return pq ;
10142 }
10143 
10144 /*------------------------------*/
10145 
10146 static double beta_pq2s( pqpair pq , double aa , double bb )
10147 {
10148    int which , status ;
10149    double p,q,x,y,a,b,bound ;
10150 
10151    which  = 2 ;
10152    p      = pq.p ; if( p <= 0.0 ) return 0.0 ;
10153    q      = pq.q ; if( q <= 0.0 ) return 1.0 ;
10154    x      = 0.0 ;
10155    y      = 1.0 ;
10156    a      = aa ;
10157    b      = bb ;
10158 
10159    cdfbet( &which , &p , &q , &x , &y , &a , &b ,  &status , &bound ) ;
10160    return x ;
10161 }
10162 
10163 /*----------------------------------------------------------------
10164    Binomial distribution
10165    (that is, the probability that more than ss out of ntrial
10166     trials were successful).
10167 ------------------------------------------------------------------*/
10168 
10169 static pqpair binomial_s2pq( double ss , double ntrial , double ptrial )
10170 {
10171    int which , status ;
10172    double p,q, s,xn,pr,ompr,bound ;
10173    pqpair pq={0.0,1.0} ;
10174 
10175    which  = 1 ;
10176    p      = 0.0 ;
10177    q      = 1.0 ;
10178    s      = ss ;            if( s  <  0.0 ) return pq ;
10179    xn     = ntrial ;        if( xn <= 0.0 ) return pq ;
10180    pr     = ptrial ;        if( pr <  0.0 ) return pq ;
10181    ompr   = 1.0 - ptrial ;
10182 
10183    cdfbin( &which , &p , &q , &s , &xn , &pr , &ompr , &status , &bound ) ;
10184    pq.p = p ; pq.q = q ; return pq ;
10185 }
10186 
10187 /*------------------------------*/
10188 
10189 static double binomial_pq2s( pqpair pq , double ntrial , double ptrial )
10190 {
10191    int which , status ;
10192    double p,q, s,xn,pr,ompr,bound ;
10193 
10194    which  = 2 ;
10195    p      = pq.p ;
10196    q      = pq.q ;
10197    s      = 0.0 ;
10198    xn     = ntrial ;
10199    pr     = ptrial ;
10200    ompr   = 1.0 - ptrial ;
10201 
10202    cdfbin( &which , &p , &q , &s , &xn , &pr , &ompr , &status , &bound ) ;
10203    return s ;
10204 }
10205 
10206 /*----------------------------------------------------------------
10207    Gamma distribution.
10208 ------------------------------------------------------------------*/
10209 
10210 static pqpair gamma_s2pq( double xx , double sh , double sc )
10211 {
10212    int which , status ;
10213    double p,q, x,shape,scale,bound ;
10214    pqpair pq={0.0,1.0} ;
10215 
10216    which  = 1 ;
10217    p      = 0.0 ;
10218    q      = 1.0 ;
10219    x      = xx ;  if(     x <= 0.0 ) return pq ;
10220    shape  = sh ;  if( shape <= 0.0 ) return pq ;
10221    scale  = sc ;  if( scale <= 0.0 ) return pq ;
10222 
10223    cdfgam( &which , &p , &q , &x , &shape , &scale , &status , &bound ) ;
10224    pq.p = p ; pq.q = q ; return pq ;
10225 }
10226 
10227 /*------------------------------*/
10228 
10229 static double gamma_pq2s( pqpair pq , double sh , double sc )
10230 {
10231    int which , status ;
10232    double p,q, x,shape,scale,bound ;
10233 
10234    which  = 2 ;
10235    p      = pq.p ; if( p <= 0.0 ) return  0.0 ;
10236    q      = pq.q ; if( q <= 0.0 ) return BIGG ;
10237    x      = 0.0 ;
10238    shape  = sh ;
10239    scale  = sc ;
10240 
10241    cdfgam( &which , &p , &q , &x , &shape , &scale , &status , &bound ) ;
10242    return x ;
10243 }
10244 
10245 /*----------------------------------------------------------------
10246    Poisson distribution
10247 ------------------------------------------------------------------*/
10248 
10249 static pqpair poisson_s2pq( double xx , double lambda )
10250 {
10251    int which , status ;
10252    double p,q, s,xlam,bound ;
10253    pqpair pq={0.0,1.0} ;
10254 
10255    which  = 1 ;
10256    p      = 0.0 ;
10257    q      = 1.0 ;
10258    s      = xx ;     if(    s < 0.0 ) return pq ;
10259    xlam   = lambda ; if( xlam < 0.0 ) return pq ;
10260 
10261    cdfpoi( &which , &p , &q , &s , &xlam , &status , &bound ) ;
10262    pq.p = p ; pq.q = q ; return pq ;
10263 }
10264 
10265 /*------------------------------*/
10266 
10267 static double poisson_pq2s( pqpair pq , double lambda )
10268 {
10269    int which , status ;
10270    double p,q, s,xlam,bound ;
10271 
10272    which  = 2 ;
10273    p      = pq.p ;
10274    q      = pq.q ;
10275    s      = 0.0 ;
10276    xlam   = lambda ;
10277 
10278    cdfpoi( &which , &p , &q , &s , &xlam , &status , &bound ) ;
10279    return s ;
10280 }
10281 
10282 /*----------------------------------------------------------------
10283    T distribution.
10284 ------------------------------------------------------------------*/
10285 
10286 static pqpair student_s2pq( double xx , double dof )
10287 {
10288    int which , status ;
10289    double p,q, s,xlam,bound ;
10290    pqpair pq={0.0,1.0} ;
10291 
10292    which  = 1 ;
10293    p      = 0.0 ;
10294    q      = 1.0 ;
10295    s      = xx ;
10296    xlam   = dof ;  if( xlam <= 0.0 ) return pq ;
10297 
10298    cdft( &which , &p , &q , &s , &xlam , &status , &bound ) ;
10299    pq.p = p ; pq.q = q ; return pq ;
10300 }
10301 
10302 /*------------------------------*/
10303 
10304 double student_pq2s( pqpair pq , double dof )
10305 {
10306    int which , status ;
10307    double p,q, s,xlam,bound ;
10308 
10309    which  = 2 ;
10310    p      = pq.p ;
10311    q      = pq.q ;
10312    s      = 0.0 ;
10313    xlam   = dof ;
10314 
10315    cdft( &which , &p , &q , &s , &xlam , &status , &bound ) ;
10316    return s ;
10317 }
10318 
10319 /****************************************************************************/
10320 /* For the distributions below here, cdflib can't do what we want directly. */
10321 /****************************************************************************/
10322 
10323 /*----------------------------------------------------------------
10324    Null correlation distribution.
10325    Let x = (rr+1)/2; then x is Beta(dof/2,dof/2).
10326 ------------------------------------------------------------------*/
10327 
10328 static pqpair correl_s2pq( double rr , double dof )  /* fake it with cdflib */
10329 {
10330    return beta_s2pq( 0.5*(rr+1.0) , 0.5*dof , 0.5*dof ) ;
10331 }
10332 
10333 /*------------------------------*/
10334 
10335 static double correl_pq2s( pqpair pq , double dof )
10336 {
10337    double xx = beta_pq2s( pq , 0.5*dof , 0.5*dof ) ;
10338    return (2.0*xx-1.0) ;
10339 }
10340 
10341 /*----------------------------------------------------------------
10342   Uniform U(0,1) distribution.
10343 ------------------------------------------------------------------*/
10344 
10345 static pqpair uniform_s2pq( double xx )  /* this isn't too hard */
10346 {
10347    pqpair pq ;
10348         if( xx <= 0.0 ) pq.p = 0.0 ;
10349    else if( xx >= 1.0 ) pq.p = 1.0 ;
10350    else                 pq.p = xx  ;
10351    pq.q = 1.0-xx ; return pq ;
10352 }
10353 
10354 /*------------------------------*/
10355 
10356 static double uniform_pq2s( pqpair pq )
10357 {
10358    return pq.p ;   /* that was easy */
10359 }
10360 
10361 /*----------------------------------------------------------------
10362   standard Logistic distribution.
10363 ------------------------------------------------------------------*/
10364 
10365 static pqpair logistic_s2pq( double xx )  /* this isn't hard, either */
10366 {
10367    pqpair pq ;
10368    if( xx >= 0.0 ){ pq.q = 1.0/(1.0+exp( xx)); pq.p = 1.0-pq.q; }
10369    else           { pq.p = 1.0/(1.0+exp(-xx)); pq.q = 1.0-pq.p; }
10370    return pq ;
10371 }
10372 
10373 /*------------------------------*/
10374 
10375 static double logistic_pq2s( pqpair pq )
10376 {
10377         if( pq.p <= 0.0 ) return -BIGG ;
10378    else if( pq.q <= 0.0 ) return  BIGG ;
10379 
10380    if( pq.p < pq.q ) return -log(1.0/pq.p-1.0) ;
10381    else              return  log(1.0/pq.q-1.0) ;
10382 }
10383 
10384 /*----------------------------------------------------------------
10385   standard Laplace distribution.
10386 ------------------------------------------------------------------*/
10387 
10388 static pqpair laplace_s2pq( double xx )  /* easy */
10389 {
10390    pqpair pq ;
10391 
10392    if( xx >= 0.0 ){ pq.q = 0.5*exp(-xx) ; pq.p = 1.0-pq.q ; }
10393    else           { pq.p = 0.5*exp( xx) ; pq.q = 1.0-pq.p ; }
10394    return pq ;
10395 }
10396 
10397 /*------------------------------*/
10398 
10399 static double laplace_pq2s( pqpair pq )
10400 {
10401         if( pq.p <= 0.0 ) return -BIGG ;
10402    else if( pq.q <= 0.0 ) return  BIGG ;
10403 
10404    if( pq.p < pq.q ) return  log(2.0*pq.p) ;
10405    else              return -log(2.0*pq.q) ;
10406 }
10407 
10408 /*----------------------------------------------------------------
10409    noncentral T distribution = hard calculation
10410 ------------------------------------------------------------------*/
10411 
10412 /****************************************************************************
10413   Noncentral t distribution function by
10414     Professor K. Krishnamoorthy
10415     Department of Mathematics
10416     University of Louisiana at Lafayette
10417   Manually translated from Fortran by RWC.
10418 *****************************************************************************/
10419 
10420 #if 0
10421 static double alng( double x )   /* log(Gamma(x)) from K */
10422 {
10423    int indx ;
10424    double xx,fterm,sum,valg ;
10425    double b[9] = { 0.0 ,
10426                    8.33333333333333e-2, 3.33333333333333e-2,
10427                    2.52380952380952e-1, 5.25606469002695e-1,
10428                    1.01152306812684e0,  1.51747364915329e0,
10429                    2.26948897420496e0,  3.00991738325940e0   } ;
10430 
10431    if( x < 8.0 ){ xx = x + 8.0 ; indx = 1 ; }
10432    else         { xx = x       ; indx = 0 ; }
10433 
10434    fterm = (xx-0.5)*log(xx) - xx + 9.1893853320467e-1 ;
10435    sum = b[1]/(xx+b[2]/(xx+b[3]/(xx+b[4]/(xx+b[5]/(xx+b[6]/
10436                                          (xx+b[7]/(xx+b[8]))))))) ;
10437    valg = sum + fterm ;
10438    if(indx)
10439      valg = valg-log(x+7.0)-log(x+6.0)-log(x+5.0)
10440                 -log(x+4.0)-log(x+3.0)-log(x+2.0)-log(x+1.0)-log(x) ;
10441    return valg ;
10442 }
10443 #else
10444 static double alng( double x ) /*-- replace with cdflib function --*/
10445 {
10446   double xx=x ; return alngam( &xx ) ;
10447 }
10448 #endif
10449 
10450 /*---------------------------------------------------------------------------*/
10451 
10452 #if 0
10453 static double gaudf( double x )  /* N(0,1) cdf from K */
10454 {
10455    static double p0=913.16744211475570 , p1=1024.60809538333800,
10456                  p2=580.109897562908800, p3=202.102090717023000,
10457                  p4=46.0649519338751400, p5=6.81311678753268400,
10458                  p6=6.047379926867041e-1,p7=2.493381293151434e-2 ;
10459    static double q0=1826.33488422951125, q1=3506.420597749092,
10460                  q2=3044.77121163622200, q3=1566.104625828454,
10461                  q4=523.596091947383490, q5=116.9795245776655,
10462                  q6=17.1406995062577800, q7=1.515843318555982,
10463                  q8=6.25e-2 ;
10464    static double sqr2pi=2.506628274631001 ;
10465    int check ;
10466    double reslt,z , first,phi ;
10467 
10468    if(x > 0.0){ z = x ; check = 1 ; }
10469    else       { z =-x ; check = 0 ; }
10470 
10471    if( z > 32.0 ) return (x > 0.0) ? 1.0 : 0.0 ;
10472 
10473    first = exp(-0.5*z*z) ;
10474    phi   = first/sqr2pi ;
10475 
10476    if (z < 7.0)
10477       reslt = first* (((((((p7*z+p6)*z+p5)*z+p4)*z+p3)*z+p2)*z+p1)*z+p0)
10478                    /((((((((q8*z+q7)*z+q6)*z+q5)*z+q4)*z+q3)*z+q2)*z+q1)*z+q0);
10479    else
10480       reslt = phi/(z+1.0/(z+2.0/(z+3.0/(z+4.0/(z+6.0/(z+7.0)))))) ;
10481 
10482    if(check) reslt = 1.0 - reslt ;
10483    return reslt ;
10484 }
10485 #else
10486 static double gaudf( double x ) /*-- replace with cdflib func --*/
10487 {
10488    double xx=x , p,q ;
10489    cumnor( &xx, &p, &q ); return p;
10490 }
10491 #endif
10492 
10493 /*---------------------------------------------------------------------------*/
10494 
10495 #if 0
10496 static double betadf( double x , double p , double q ) /* Beta cdf from K */
10497 {
10498    int check , ns ;
10499    double result,betf,psq,xx,cx,pp,qq ;
10500    double term,ai,rx,temp ;
10501 
10502    if( x >= 1.0 ) return 1.0 ;
10503    if( x <= 0.0 ) return 0.0 ;
10504 
10505    betf = alng(p)+alng(q)-alng(p+q) ;
10506    result=x ;
10507    psq=p+q ;
10508    cx=1.0-x ;
10509    if(p < psq*x){ xx=cx ; cx=x ; pp=q ; qq=p ; check=1 ; }
10510    else         { xx=x  ;        pp=p ; qq=q ; check=0 ; }
10511 
10512    term=1.0 ;
10513    ai=1.0 ;
10514    result=1.0 ;
10515    ns=(int)(qq+cx*psq) ;
10516    rx=xx/cx ;
10517 L3:
10518    temp=qq-ai ;
10519    if(ns == 0) rx=xx ;
10520 L4:
10521    term=term*temp*rx/(pp+ai) ;
10522    result=result+term ;
10523    temp=fabs(term) ;
10524    if(temp <= 1.e-14 && temp <= 1.e-14*result) goto L5 ;
10525    ai=ai+1.0 ;
10526    ns=ns-1 ;
10527    if(ns >= 0) goto L3 ;
10528    temp=psq ;
10529    psq=psq+1.0 ;
10530    goto L4 ;
10531 
10532 L5:
10533    result=result*exp(pp*log(xx)+(qq-1.0)*log(cx)-betf)/pp ;
10534    if(check) result=1.0-result ;
10535    return result ;
10536 }
10537 #else
10538 static double betadf( double x , double p , double q ) /*-- cdflib func --*/
10539 {
10540    double xx=x,yy=1.0-x , aa=p,bb=q , pp,qq ;
10541    cumbet( &xx,&yy , &aa,&bb , &pp,&qq ) ; return pp ;
10542 }
10543 #endif
10544 
10545 /*---------------------------------------------------------------------------*/
10546 /* Krishnamoorthy's function for cdf of noncentral t, for df > 0,
10547    translated into C by RW Cox [Mar 2004].
10548    Note the original fails for delta=0, so we call the cdflib func for this.
10549    A couple of other minor fixes are also included.
10550 -----------------------------------------------------------------------------*/
10551 
10552 static pqpair tnonc_s2pq( double t , double df , double delta )
10553 {
10554    int indx , k , i ;
10555    double x,del,tnd,ans,y,dels,a,b,c ;
10556    double pkf,pkb,qkf,qkb , pgamf,pgamb,qgamf,qgamb ;
10557    double pbetaf,pbetab,qbetaf,qbetab ;
10558    double ptermf,qtermf,ptermb,qtermb,term ;
10559    double rempois,delosq2,sum,cons,error ;
10560 
10561    pqpair pq={0.0,1.0} ;  /* will be return value */
10562    double ab1 ;
10563 
10564    /*-- stupid user? --*/
10565 
10566    if( df <= 0.0 ) return pq ;
10567 
10568    /*-- non-centrality = 0? --*/
10569 
10570    if( fabs(delta) < 1.e-8 ) return student_s2pq(t,df) ;
10571 
10572    /*-- start K's code here --*/
10573 
10574    if( t < 0.0 ){ x = -t ; del = -delta ; indx = 1 ; }  /* x will be */
10575    else         { x =  t ; del =  delta ; indx = 0 ; }  /* positive */
10576 
10577    ans = gaudf(-del) ;  /* prob that x <= 0 = Normal cdf */
10578 
10579    /*-- the nearly trivial case of x=0 --*/
10580 
10581    if( x == 0.0 ){ pq.p = ans; pq.q = 1.0-ans; return pq; }
10582 
10583    if( df == 1.0 ) df = 1.0000001 ;  /** df=1 is BAD **/
10584 
10585    y = x*x/(df+x*x) ;    /* between 0 and 1 */
10586    dels = 0.5*del*del ;  /* will be positive */
10587    k = (int)dels ;       /* 0, 1, 2, ... */
10588    a = k+0.5 ;           /* might be as small as 0.5 */
10589    c = k+1.0 ;
10590    b = 0.5*df ;          /* might be as small as 0.0 */
10591 
10592    pkf = exp(-dels+k*log(dels)-alng(k+1.0)) ;
10593    pkb = pkf ;
10594    qkf = exp(-dels+k*log(dels)-alng(k+1.0+0.5)) ;
10595    qkb = qkf ;
10596 
10597    pbetaf = betadf(y, a, b) ;
10598    pbetab = pbetaf ;
10599    qbetaf = betadf(y, c, b) ;
10600    qbetab = qbetaf ;
10601 
10602    ab1 = a+b-1.0 ;  /* might be as small as -0.5 */
10603 
10604    /*-- RWCox: if a+b-1 < 0, log(Gamma(a+b-1)) won't work;
10605                instead, use Gamma(a+b-1)=Gamma(a+b)/(a+b-1) --*/
10606 
10607    if( ab1 > 0.0 )
10608      pgamf = exp(alng(ab1)-alng(a)-alng(b)+(a-1.0)*log(y)+b*log(1.0-y)) ;
10609    else
10610      pgamf = exp(alng(a+b)-alng(a)-alng(b)+(a-1.0)*log(y)+b*log(1.0-y))/ab1 ;
10611 
10612    pgamb = pgamf*y*(ab1)/a ;
10613 
10614    /*-- we can't have c+b-1 < 0, so the above patchup isn't needed --*/
10615 
10616    qgamf = exp(alng(c+b-1.0)-alng(c)-alng(b)+(c-1.0)*log(y) + b*log(1.0-y)) ;
10617    qgamb = qgamf*y*(c+b-1.0)/c ;
10618 
10619    rempois = 1.0 - pkf ;
10620    delosq2 = del/1.4142135623731 ;
10621    sum = pkf*pbetaf+delosq2*qkf*qbetaf ;
10622    cons = 0.5*(1.0 + 0.5*fabs(delta)) ;
10623    i = 0 ;
10624 L1:
10625    i = i + 1 ;
10626    pgamf = pgamf*y*(a+b+i-2.0)/(a+i-1.0) ;
10627    pbetaf = pbetaf - pgamf ;
10628    pkf = pkf*dels/(k+i) ;
10629    ptermf = pkf*pbetaf ;
10630    qgamf = qgamf*y*(c+b+i-2.0)/(c+i-1.0) ;
10631    qbetaf = qbetaf - qgamf ;
10632    qkf = qkf*dels/(k+i-1.0+1.5) ;
10633    qtermf = qkf*qbetaf ;
10634    term = ptermf + delosq2*qtermf  ;
10635    sum = sum + term ;
10636    error = rempois*cons*pbetaf ;
10637    rempois = rempois - pkf ;
10638 
10639    if( i > k ){
10640      if( error <= 1.e-12 || i >= 9999 ) goto L2 ;
10641      goto L1 ;
10642    } else {
10643      pgamb = pgamb*(a-i+1.0)/(y*(a+b-i)) ;
10644      pbetab = pbetab + pgamb ;
10645      pkb = (k-i+1.0)*pkb/dels ;
10646      ptermb = pkb*pbetab  ;
10647      qgamb = qgamb*(c-i+1.0)/(y*(c+b-i)) ;
10648      qbetab = qbetab + qgamb ;
10649      qkb = (k-i+1.0+0.5)*qkb/dels ;
10650      qtermb = qkb*qbetab  ;
10651      term =  ptermb + delosq2*qtermb ;
10652      sum = sum + term  ;
10653      rempois = rempois - pkb ;
10654      if (rempois <= 1.e-12 || i >= 9999) goto L2 ;
10655      goto L1 ;
10656    }
10657 L2:
10658    tnd = 0.5*sum + ans ;
10659 
10660    /*-- return a pqpair, not just the cdf --*/
10661 
10662    if( indx ){ pq.p = 1.0-tnd; pq.q = tnd    ; }
10663    else      { pq.p = tnd    ; pq.q = 1.0-tnd; }
10664    return pq ;
10665 }
10666 
10667 /*------------------------------*/
10668 /* Inverse to above function;
10669    uses cdflib dstinv()/dinvr()
10670    to solve the equation.
10671 --------------------------------*/
10672 
10673 static double tnonc_pq2s( pqpair pq , double dof , double nonc )
10674 {
10675    double t ;  /* will be result */
10676    double tbot,ttop , dt ;
10677    double T6=1.e-50,T7=1.e-8 ;
10678    double K4=0.5,K5=5.0 ;
10679    double fx ;
10680    unsigned long qhi,qleft ;
10681    int status , qporq , ite ;
10682    pqpair tpq ;
10683 
10684    if( dof  <= 0.0 ) return  BIGG ;  /* bad user */
10685    if( pq.p <= 0.0 ) return -BIGG ;
10686    if( pq.q <= 0.0 ) return  BIGG ;
10687 
10688    t = student_pq2s(pq,dof) ;   /* initial guess */
10689 
10690    if( fabs(nonc) < 1.e-8 ) return t ;
10691 
10692    t += 0.5*nonc ;  /* adjust up or down */
10693 
10694    dt = 0.1 * fabs(t) ; if( dt < 1.0 ) dt = 1.0 ;  /* stepsize */
10695 
10696    /* scan down for lower bound, below which cdf is < p */
10697 
10698    tbot = t ;
10699    for( ite=0 ; ite < 1000 ; ite++ ){
10700      tpq = tnonc_s2pq( tbot , dof , nonc ) ;
10701      if( tpq.p <= pq.p ) break ;
10702      tbot -= dt ;
10703    }
10704    if( ite >= 1000 ) return -BIGG ;
10705 
10706    /* scan up for upper bound, above which cdf is > p */
10707 
10708    ttop = tbot+0.5*dt ;
10709    for( ite=0 ; ite < 1000 ; ite++ ){
10710      tpq = tnonc_s2pq( ttop , dof , nonc ) ;
10711      if( tpq.p >= pq.p ) break ;
10712      ttop += dt ;
10713    }
10714    if( ite >= 1000 ) return BIGG ;
10715 
10716    t = 0.5*(tbot+ttop) ;  /* initial guess in middle */
10717 
10718    /* initialize searching parameters */
10719 
10720    dstinv(&tbot,&ttop,&K4,&K4,&K5,&T6,&T7);
10721 
10722    status = 0 ; qporq = (pq.p <= pq.q) ;
10723 
10724    while(1){
10725 
10726      dinvr(&status,&t,&fx,&qleft,&qhi) ;
10727 
10728      if( status != 1 ) return t ;  /* done! */
10729 
10730      tpq = tnonc_s2pq( t , dof , nonc ) ;  /* get cdf */
10731 
10732      /* goal of dinvr is to drive fx to zero */
10733 
10734      fx = (qporq) ? pq.p-tpq.p : pq.q-tpq.q ;
10735    }
10736 
10737    return BIGG ;  /* unreachable */
10738 }
10739 
10740 /*----------------------------------------------------------------
10741    Chi distribution (sqrt of chi-squared, duh).
10742 ------------------------------------------------------------------*/
10743 
10744 static pqpair chi_s2pq( double xx , double dof )
10745 {
10746    pqpair pq={0.0,1.0} ;
10747 
10748    if( xx <= 0.0 || dof <= 0.0 ) return pq ;
10749    return chisq_s2pq( xx*xx , dof ) ;
10750 }
10751 
10752 /*------------------------------*/
10753 
10754 static double chi_pq2s( pqpair pq , double dof )
10755 {
10756    if( pq.p <= 0.0 ) return  0.0 ;
10757    if( pq.q <= 0.0 ) return BIGG ;
10758    return sqrt(chisq_pq2s(pq,dof)) ;
10759 }
10760 
10761 /*----------------------------------------------------------------
10762    Extreme value type I: cdf(x) = exp(-exp(-x)).
10763 ------------------------------------------------------------------*/
10764 
10765 static pqpair extval1_s2pq( double x )
10766 {
10767    double p,q,y ; pqpair pq ;
10768 
10769    if( x > -5.0 ){ y = exp(-x) ; p = exp(-y) ; }
10770    else          { y = 1.0     ; p = 0.0     ; }
10771 
10772    if( y >= 1.e-4 ) q = 1.0-p ;
10773    else             q = y*(1.0+y*(-0.5+y*(1.0/6.0-y/24.0))) ;
10774    pq.p = p ; pq.q = q ; return pq ;
10775 }
10776 
10777 /*------------------------------*/
10778 
10779 static double extval1_pq2s( pqpair pq )
10780 {
10781         if( pq.p <= 0.0 ) return -BIGG ;
10782    else if( pq.p >= 1.0 ) return  BIGG ;
10783    return -log(-log(pq.p)) ;
10784 }
10785 
10786 /*----------------------------------------------------------------
10787    Weibull distribution: cdf(x) = 1 - exp( -x^c ) for x>0 and c>0.
10788 ------------------------------------------------------------------*/
10789 
10790 static pqpair weibull_s2pq( double x , double c )
10791 {
10792    double y ;
10793    pqpair pq={0.0,1.0} ;
10794 
10795    if( x <= 0.0 || c <= 0.0 ) return pq ;
10796 
10797    y = pow(x,c) ; pq.q = exp(-y) ;
10798    if( y >= 1.e-4 ) pq.p = 1.0-pq.q ;
10799    else             pq.p = y*(1.0+y*(-0.5+y*(1.0/6.0-y/24.0))) ;
10800    return pq ;
10801 }
10802 
10803 /*------------------------------*/
10804 
10805 static double weibull_pq2s( pqpair pq , double c )
10806 {
10807         if( pq.p <= 0.0 || c <= 0.0 ) return  0.0 ;
10808    else if( pq.q <= 0.0             ) return BIGG ;
10809    return pow( -log(pq.q) , 1.0/c ) ;
10810 }
10811 
10812 /*----------------------------------------------------------------
10813    Inverse Gaussian:
10814     density proportional to exp(-0.5*c(x+1/x))/x^1.5 (x,c >0).
10815 ------------------------------------------------------------------*/
10816 
10817 static pqpair invgauss_s2pq( double x, double c )
10818 {
10819    double y , p1,q1 , p2,q2 , v ;
10820    pqpair pq={0.0,1.0} ;
10821 
10822    if( x <= 0.0 || c <= 0.0 ) return pq ;
10823 
10824    y = sqrt(c/x) ;
10825    v =  y*(x-1.0) ; cumnor( &v , &p1,&q1 ) ;
10826    v = -y*(x+1.0) ; cumnor( &v , &p2,&q2 ) ;
10827    pq.p = p1 ;
10828    if( p2 > 0.0 ) pq.p += exp(2.0*c+log(p2)) ;
10829    pq.q = 1.0-pq.p ; return pq ;
10830 }
10831 
10832 /*------------------------------*/
10833 /* Inverse to above function;
10834    uses cdflib dstinv()/dinvr()
10835    to solve the equation.
10836 --------------------------------*/
10837 
10838 static double invgauss_pq2s( pqpair pq , double c )
10839 {
10840    double t ;  /* will be result */
10841    double tbot,ttop , dt ;
10842    double T6=1.e-50,T7=1.e-8 ;
10843    double K4=0.5,K5=5.0 ;
10844    double fx ;
10845    unsigned long qhi,qleft ;
10846    int status , qporq , ite ;
10847    pqpair tpq ;
10848 
10849    if( c    <= 0.0 ) return  BIGG ;  /* bad user */
10850    if( pq.p <= 0.0 ) return   0.0 ;
10851    if( pq.q <= 0.0 ) return  BIGG ;
10852 
10853    /* initial guess is t=1; scan down for lower bound */
10854 
10855    tbot = 1.01 ; dt = 0.9 ;
10856    for( ite=0 ; ite < 1000 ; ite++ ){
10857      tpq = invgauss_s2pq( tbot , c ) ;
10858      if( tpq.p <= pq.p ) break ;
10859      tbot *= dt ;
10860    }
10861    if( ite >= 1000 ) return 0.0 ;
10862 
10863    /* scan up for upper bound */
10864 
10865    dt = 1.1 ; ttop = tbot*dt ;
10866    for( ite=0 ; ite < 1000 ; ite++ ){
10867      tpq = invgauss_s2pq( ttop , c ) ;
10868      if( tpq.p >= pq.p ) break ;
10869      ttop *= dt ;
10870    }
10871    if( ite >= 1000 ) return BIGG ;
10872 
10873    t = sqrt(tbot*ttop) ; /* start at geometric mean */
10874 
10875    /* initialize searching parameters */
10876 
10877    dstinv(&tbot,&ttop,&K4,&K4,&K5,&T6,&T7);
10878 
10879    status = 0 ; qporq = (pq.p <= pq.q) ;
10880 
10881    while(1){
10882 
10883      dinvr(&status,&t,&fx,&qleft,&qhi) ;
10884 
10885      if( status != 1 ) return t ;  /* done! */
10886 
10887      tpq = invgauss_s2pq( t , c ) ;
10888 
10889      /* goal is to drive fx to zero */
10890 
10891      fx = (qporq) ? pq.p-tpq.p : pq.q-tpq.q ;
10892    }
10893 
10894    return BIGG ;  /* unreachable */
10895 }
10896 
10897 /*--------------------------------------------------------------------------*/
10898 /*! Given a value, calculate both its cdf and reversed cdf (1.0-cdf).
10899     If an error occurs, you'll probably get back {0.0,1.0}.
10900     All the actual work is done in utility functions for each distribution.
10901 ----------------------------------------------------------------------------*/
10902 
10903 static pqpair stat2pq( double val, int code, double p1,double p2,double p3 )
10904 {
10905    pqpair pq={0.0,1.0} ;
10906 
10907    switch( code ){
10908 
10909      case NIFTI_INTENT_CORREL:     pq = correl_s2pq  ( val, p1 )      ; break;
10910      case NIFTI_INTENT_TTEST:      pq = student_s2pq ( val, p1 )      ; break;
10911      case NIFTI_INTENT_FTEST:      pq = fstat_s2pq   ( val, p1,p2 )   ; break;
10912      case NIFTI_INTENT_ZSCORE:     pq = normal_s2pq  ( val )          ; break;
10913      case NIFTI_INTENT_CHISQ:      pq = chisq_s2pq   ( val, p1 )      ; break;
10914      case NIFTI_INTENT_BETA:       pq = beta_s2pq    ( val, p1,p2 )   ; break;
10915      case NIFTI_INTENT_BINOM:      pq = binomial_s2pq( val, p1,p2 )   ; break;
10916      case NIFTI_INTENT_GAMMA:      pq = gamma_s2pq   ( val, p1,p2 )   ; break;
10917      case NIFTI_INTENT_POISSON:    pq = poisson_s2pq ( val, p1 )      ; break;
10918      case NIFTI_INTENT_FTEST_NONC: pq = fnonc_s2pq   ( val, p1,p2,p3 ); break;
10919      case NIFTI_INTENT_CHISQ_NONC: pq = chsqnonc_s2pq( val, p1,p2    ); break;
10920      case NIFTI_INTENT_TTEST_NONC: pq = tnonc_s2pq   ( val, p1,p2 )   ; break;
10921      case NIFTI_INTENT_CHI:        pq = chi_s2pq     ( val, p1 )      ; break;
10922 
10923      /* these distributions are shifted and scaled copies of a standard case */
10924 
10925      case NIFTI_INTENT_INVGAUSS:
10926         if( p1 > 0.0 && p2 > 0.0 ) pq = invgauss_s2pq( val/p1,p2/p1 ) ; break;
10927 
10928      case NIFTI_INTENT_WEIBULL:
10929         if( p2 > 0.0 && p3 > 0.0 ) pq = weibull_s2pq ((val-p1)/p2,p3) ; break;
10930 
10931      case NIFTI_INTENT_EXTVAL:
10932                     if( p2 > 0.0 ) pq = extval1_s2pq ( (val-p1)/p2 )  ; break;
10933 
10934      case NIFTI_INTENT_NORMAL:
10935                     if( p2 > 0.0 ) pq = normal_s2pq  ( (val-p1)/p2 )  ; break;
10936 
10937      case NIFTI_INTENT_LOGISTIC:
10938                     if( p2 > 0.0 ) pq = logistic_s2pq( (val-p1)/p2 )  ; break;
10939 
10940      case NIFTI_INTENT_LAPLACE:
10941                     if( p2 > 0.0 ) pq = laplace_s2pq ( (val-p1)/p2 )  ; break;
10942 
10943      case NIFTI_INTENT_UNIFORM:
10944                     if( p2 > p1  ) pq = uniform_s2pq((val-p1)/(p2-p1)); break;
10945 
10946      /* this case is trivial */
10947 
10948      case NIFTI_INTENT_PVAL:       pq.p = 1.0-val ; pq.q = val        ; break;
10949    }
10950 
10951    return pq ;
10952 }
10953 
10954 /*--------------------------------------------------------------------------*/
10955 /*! Given a pq value (cdf and 1-cdf), compute the value that gives this.
10956     If an error occurs, you'll probably get back a BIGG number.
10957     All the actual work is done in utility functions for each distribution.
10958 ----------------------------------------------------------------------------*/
10959 
10960 static double pq2stat( pqpair pq, int code, double p1,double p2,double p3 )
10961 {
10962    double val=BIGG ;
10963 
10964    if( pq.p < 0.0 || pq.q < 0.0 || pq.p > 1.0 || pq.q > 1.0 ) return val ;
10965 
10966    switch( code ){
10967 
10968      case NIFTI_INTENT_CORREL:     val = correl_pq2s  ( pq , p1 )      ; break;
10969      case NIFTI_INTENT_TTEST:      val = student_pq2s ( pq , p1 )      ; break;
10970      case NIFTI_INTENT_FTEST:      val = fstat_pq2s   ( pq , p1,p2 )   ; break;
10971      case NIFTI_INTENT_ZSCORE:     val = normal_pq2s  ( pq )           ; break;
10972      case NIFTI_INTENT_CHISQ:      val = chisq_pq2s   ( pq , p1 )      ; break;
10973      case NIFTI_INTENT_BETA:       val = beta_pq2s    ( pq , p1,p2 )   ; break;
10974      case NIFTI_INTENT_BINOM:      val = binomial_pq2s( pq , p1,p2 )   ; break;
10975      case NIFTI_INTENT_GAMMA:      val = gamma_pq2s   ( pq , p1,p2 )   ; break;
10976      case NIFTI_INTENT_POISSON:    val = poisson_pq2s ( pq , p1 )      ; break;
10977      case NIFTI_INTENT_FTEST_NONC: val = fnonc_pq2s   ( pq , p1,p2,p3 ); break;
10978      case NIFTI_INTENT_CHISQ_NONC: val = chsqnonc_pq2s( pq , p1,p2    ); break;
10979      case NIFTI_INTENT_TTEST_NONC: val = tnonc_pq2s   ( pq , p1,p2 )   ; break;
10980      case NIFTI_INTENT_CHI:        val = chi_pq2s     ( pq , p1 )      ; break;
10981 
10982      /* these distributions are shifted and scaled copies of a standard case */
10983 
10984      case NIFTI_INTENT_INVGAUSS:
10985         if( p1 > 0.0 && p2 > 0.0 ) val = p1*invgauss_pq2s   ( pq,p2/p1); break;
10986 
10987      case NIFTI_INTENT_WEIBULL:
10988         if( p2 > 0.0 && p3 > 0.0 ) val = p1+p2*weibull_pq2s ( pq, p3 ) ; break;
10989 
10990      case NIFTI_INTENT_EXTVAL:
10991                     if( p2 > 0.0 ) val = p1+p2*extval1_pq2s ( pq )     ; break;
10992 
10993      case NIFTI_INTENT_NORMAL:
10994                     if( p2 > 0.0 ) val = p1+p2*normal_pq2s  ( pq )     ; break;
10995 
10996      case NIFTI_INTENT_LOGISTIC:
10997                     if( p2 > 0.0 ) val = p1+p2*logistic_pq2s( pq )     ; break;
10998 
10999      case NIFTI_INTENT_LAPLACE:
11000                     if( p2 > 0.0 ) val = p1+p2*laplace_pq2s ( pq )     ; break;
11001 
11002      case NIFTI_INTENT_UNIFORM:
11003                     if( p2 > p1  ) val = p1+(p2-p1)*uniform_pq2s(pq)   ; break;
11004 
11005      /* this case is trivial */
11006 
11007      case NIFTI_INTENT_PVAL:       val = pq.q                          ; break;
11008    }
11009 
11010    return val ;
11011 }
11012 
11013 /****************************************************************************/
11014 /*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]*/
11015 /*..........................................................................*/
11016 /*............. AT LAST!  Functions to be called by the user! ..............*/
11017 /*..........................................................................*/
11018 /*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]*/
11019 /****************************************************************************/
11020 
11021 /****************************************************************************
11022  Statistical codes implemented here:
11023 
11024      NIFTI_INTENT_CORREL     = correlation statistic
11025      NIFTI_INTENT_TTEST      = t statistic (central)
11026      NIFTI_INTENT_FTEST      = F statistic (central)
11027      NIFTI_INTENT_ZSCORE     = N(0,1) statistic
11028      NIFTI_INTENT_CHISQ      = Chi-squared (central)
11029      NIFTI_INTENT_BETA       = Beta variable (central)
11030      NIFTI_INTENT_BINOM      = Binomial variable
11031      NIFTI_INTENT_GAMMA      = Gamma distribution
11032      NIFTI_INTENT_POISSON    = Poisson distribution
11033      NIFTI_INTENT_FTEST_NONC = noncentral F statistic
11034      NIFTI_INTENT_CHISQ_NONC = noncentral chi-squared
11035      NIFTI_INTENT_TTEST_NONC = noncentral t statistic
11036      NIFTI_INTENT_CHI        = Chi statistic (central)
11037      NIFTI_INTENT_INVGAUSS   = inverse Gaussian variable
11038      NIFTI_INTENT_WEIBULL    = Weibull distribution
11039      NIFTI_INTENT_EXTVAL     = Extreme value type I
11040      NIFTI_INTENT_NORMAL     = N(mu,variance) normal
11041      NIFTI_INTENT_LOGISTIC   = Logistic distribution
11042      NIFTI_INTENT_LAPLACE    = Laplace distribution
11043      NIFTI_INTENT_UNIFORM    = Uniform distribution
11044      NIFTI_INTENT_PVAL       = "p-value"
11045 *****************************************************************************/
11046 
11047 static char *inam[]={ NULL , NULL ,
11048                        "CORREL"   , "TTEST"   , "FTEST"      , "ZSCORE"     ,
11049                        "CHISQ"    , "BETA"    , "BINOM"      , "GAMMA"      ,
11050                        "POISSON"  , "NORMAL"  , "FTEST_NONC" , "CHISQ_NONC" ,
11051                        "LOGISTIC" , "LAPLACE" , "UNIFORM"    , "TTEST_NONC" ,
11052                        "WEIBULL"  , "CHI"     , "INVGAUSS"   , "EXTVAL"     ,
11053                        "PVAL"     ,
11054                      NULL } ;
11055 
11056 #include <ctype.h>
11057 #include <string.h>
11058 
11059 /*--------------------------------------------------------------------------*/
11060 /*! Given a string name for a statistic, return its integer code.
11061     Returns -1 if not found.
11062 ----------------------------------------------------------------------------*/
11063 
11064 int nifti_intent_code( char *name )
11065 {
11066    char *unam , *upt ;
11067    int ii ;
11068 
11069    if( name == NULL || *name == '\0' ) return -1 ;
11070 
11071    unam = strdup(name) ;
11072    for( upt=unam ; *upt != '\0' ; upt++ ) *upt = (char)toupper(*upt) ;
11073 
11074    for( ii=NIFTI_FIRST_STATCODE ; ii <= NIFTI_LAST_STATCODE ; ii++ )
11075      if( strcmp(inam[ii],unam) == 0 ) break ;
11076 
11077    free(unam) ;
11078    return (ii <= NIFTI_LAST_STATCODE) ? ii : -1 ;
11079 }
11080 
11081 /*--------------------------------------------------------------------------*/
11082 /*! Given a value, return its cumulative distribution function (cdf):
11083       - val      = statistic
11084       - code     = NIFTI_INTENT_* statistical code
11085       - p1,p2,p3 = parameters of the distribution
11086 
11087     If an error occurs, you'll probably get back 0.0.
11088 ----------------------------------------------------------------------------*/
11089 
11090 double nifti_stat2cdf( double val, int code, double p1,double p2,double p3 )
11091 {
11092    pqpair pq ;
11093    pq = stat2pq( val, code, p1,p2,p3 ) ;
11094    return pq.p ;
11095 }
11096 
11097 /*--------------------------------------------------------------------------*/
11098 /*! Given a value, return its reversed cumulative distribution function
11099    (1-cdf):
11100       - val      = statistic
11101       - code     = NIFTI_INTENT_* statistical code
11102       - p1,p2,p3 = parameters of the distribution
11103 
11104   If an error transpires, you'll probably get back 1.0.
11105 ----------------------------------------------------------------------------*/
11106 
11107 double nifti_stat2rcdf( double val, int code, double p1,double p2,double p3 )
11108 {
11109    pqpair pq ;
11110    pq = stat2pq( val, code, p1,p2,p3 ) ;
11111    return pq.q ;
11112 }
11113 
11114 /*--------------------------------------------------------------------------*/
11115 /*! Given a cdf probability, find the value that gave rise to it.
11116      - p        = cdf; 0 < p < 1
11117      - code     = NIFTI_INTENT_* statistical code
11118      - p1,p2,p3 = parameters of the distribution
11119 
11120   If an error transpires, you'll probably get back a BIGG number.
11121 ----------------------------------------------------------------------------*/
11122 
11123 double nifti_cdf2stat( double p , int code, double p1,double p2,double p3 )
11124 {
11125    pqpair pq ;
11126    pq.p = p ; pq.q = 1.0-p ;
11127    return pq2stat(pq,code,p1,p2,p3) ;
11128 }
11129 
11130 /*--------------------------------------------------------------------------*/
11131 /*! Given a reversed cdf probability, find the value that gave rise to it.
11132      - q        = 1-cdf; 0 < q < 1
11133      - code     = NIFTI_INTENT_* statistical code
11134      - p1,p2,p3 = parameters of the distribution
11135 
11136   If an error transpires, you'll probably get back a BIGG number.
11137 ----------------------------------------------------------------------------*/
11138 
11139 double nifti_rcdf2stat( double q , int code, double p1,double p2,double p3 )
11140 {
11141    pqpair pq ;
11142    pq.p = 1.0-q ; pq.q = q ;
11143    return pq2stat(pq,code,p1,p2,p3) ;
11144 }
11145 
11146 /*--------------------------------------------------------------------------*/
11147 /*! Given a statistic, compute a z-score from it.  That is, the output
11148     is z such that cdf(z) of a N(0,1) variable is the same as the cdf
11149     of the given distribution at val.
11150 ----------------------------------------------------------------------------*/
11151 
11152 double nifti_stat2zscore( double val , int code, double p1,double p2,double p3 )
11153 {
11154    pqpair pq ;
11155 
11156    if( code == NIFTI_INTENT_ZSCORE ) return val ;           /* trivial */
11157    if( code == NIFTI_INTENT_NORMAL ) return (val-p1)/p2 ;   /* almost so */
11158 
11159    pq = stat2pq( val, code, p1,p2,p3 ) ;                    /* find cdf */
11160    return normal_pq2s( pq ) ;                               /* find z  */
11161 }
11162 
11163 /*--------------------------------------------------------------------------*/
11164 /*! Given a statistic, compute a half-z-score from it.  That is, the output
11165     is z such that cdf(z) of a half-N(0,1) variable is the same as the cdf
11166     of the given distribution at val.  A half-N(0,1) variable has density
11167     zero for z < 0 and twice the usual N(0,1) density for z > 0.
11168 ----------------------------------------------------------------------------*/
11169 
11170 double nifti_stat2hzscore( double val, int code, double p1,double p2,double p3 )
11171 {
11172    pqpair pq ;
11173 
11174    pq = stat2pq( val, code, p1,p2,p3 ) ;                    /* find cdf */
11175    pq.q = 0.5*(1.0-pq.p) ; pq.p = 0.5*(1.0+pq.p) ;          /* mangle it */
11176    return normal_pq2s( pq ) ;                               /* find z  */
11177 }
11178 
11179 /****************************************************************************/
11180 /*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]*/
11181 /****************************************************************************/
11182 
11183 /*--------------------------------------------------------------------------*/
11184 /* Sample program to test the above functions.  Otherwise unimportant.
11185 ----------------------------------------------------------------------------*/
11186 
11187 int main( int argc , char *argv[] )
11188 {
11189    double val , p , q , p1=0.0,p2=0.0,p3=0.0 ;
11190    double vbot,vtop,vdel ;
11191    int code , iarg=1 , doq=0 , dod=0 , doi=0 , doz=0 , doh=0 ;
11192 
11193    /*-- print some help for the pitiful user --*/
11194 
11195    if( argc < 3 || strstr(argv[1],"help") != NULL ){
11196     int ii ;
11197     printf("\n") ;
11198     printf("Demo program for computing NIfTI statistical functions.\n") ;
11199     printf("Usage: nifti_stats [-q|-d|-1|-z] val CODE [p1 p2 p3]\n") ;
11200     printf(" val can be a single number or in the form bot:top:step.\n") ;
11201     printf(" default ==> output p = Prob(statistic < val).\n") ;
11202     printf("  -q     ==> output is 1-p.\n") ;
11203     printf("  -d     ==> output is density.\n") ;
11204     printf("  -1     ==> output is x such that Prob(statistic < x) = val.\n") ;
11205     printf("  -z     ==> output is z such that Normal cdf(z) = p(val).\n") ;
11206     printf("  -h     ==> output is z such that 1/2-Normal cdf(z) = p(val).\n");
11207     printf(" Allowable CODEs:\n") ;
11208     for( ii=NIFTI_FIRST_STATCODE ; ii <= NIFTI_LAST_STATCODE ; ii++ ){
11209      printf("  %-10s",inam[ii]); if((ii-NIFTI_FIRST_STATCODE)%6==5)printf("\n");
11210     }
11211     printf("\n") ;
11212     printf(" Following CODE are distributional parameters, as needed.\n");
11213     printf("\n") ;
11214     printf("Results are written to stdout, 1 number per output line.\n") ;
11215     printf("Example (piping output into AFNI program 1dplot):\n") ;
11216     printf(" nifti_stats -d 0:4:.001 INVGAUSS 1 3 | 1dplot -dx 0.001 -stdin\n");
11217     printf("\n") ;
11218     printf("Author - RW Cox - SSCC/NIMH/NIH/DHHS/USA/EARTH - March 2004\n") ;
11219     printf("\n") ;
11220     exit(0) ;
11221    }
11222 
11223    /*-- check first arg to see if it is an output option;
11224         if so, set the appropriate output flag to determine what to compute --*/
11225 
11226         if( strcmp(argv[iarg],"-q") == 0 ){ doq = 1 ; iarg++ ; }
11227    else if( strcmp(argv[iarg],"-d") == 0 ){ dod = 1 ; iarg++ ; }
11228    else if( strcmp(argv[iarg],"-1") == 0 ){ doi = 1 ; iarg++ ; }
11229    else if( strcmp(argv[iarg],"-z") == 0 ){ doz = 1 ; iarg++ ; }
11230    else if( strcmp(argv[iarg],"-h") == 0 ){ doh = 1 ; iarg++ ; }
11231 
11232    /*-- get the value(s) to process --*/
11233 
11234    vbot=vtop=vdel = 0.0 ;
11235    sscanf( argv[iarg++] , "%lf:%lf:%lf" , &vbot,&vtop,&vdel ) ;
11236    if( vbot >= vtop ) vdel = 0.0 ;
11237    if( vdel <= 0.0  ) vtop = vbot ;
11238 
11239    /*-- decode the CODE into the integer signifying the distribution --*/
11240 
11241    code = nifti_intent_code(argv[iarg++]) ;
11242      if( code < 0 ){ fprintf(stderr,"illegal code=%s\n",argv[iarg-1]); exit(1); }
11243 
11244    /*-- get the parameters, if present (defaults are 0) --*/
11245 
11246    if( argc > iarg ) p1 = strtod(argv[iarg++],NULL) ;
11247    if( argc > iarg ) p2 = strtod(argv[iarg++],NULL) ;
11248    if( argc > iarg ) p3 = strtod(argv[iarg++],NULL) ;
11249 
11250    /*-- loop over input value(s), compute output, write to stdout --*/
11251 
11252    for( val=vbot ; val <= vtop ; val += vdel ){
11253      if( doq )                                        /* output = 1-cdf */
11254        p = nifti_stat2rcdf( val , code,p1,p2,p3 ) ;
11255      else if( dod )                                   /* output = density */
11256        p = 1000.0*( nifti_stat2cdf(val+.001,code,p1,p2,p3)
11257                    -nifti_stat2cdf(val     ,code,p1,p2,p3)) ;
11258      else if( doi )                                   /* output = inverse */
11259        p = nifti_cdf2stat( val , code,p1,p2,p3 ) ;
11260      else if( doz )                                   /* output = z score */
11261        p = nifti_stat2zscore( val , code,p1,p2,p3 ) ;
11262      else if( doh )                                   /* output = halfz score */
11263        p = nifti_stat2hzscore( val , code,p1,p2,p3 ) ;
11264      else                                              /* output = cdf */
11265        p = nifti_stat2cdf( val , code,p1,p2,p3 ) ;
11266 
11267      printf("%.9g\n",p) ;
11268      if( vdel <= 0.0 ) break ;  /* the case of just 1 value */
11269    }
11270 
11271    /*-- terminus est --*/
11272 
11273    exit(0) ;
11274 }
Powered by Plone

This site conforms to the following standards: