Skip to content

AFNI/NIfTI Server

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

Doxygen Source Code Documentation


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

cdf_28.c

Go to the documentation of this file.
00001 #include "cdflib.h"
00002 void cumchn(double *x,double *df,double *pnonc,double *cum,
00003             double *ccum)
00004 /*
00005 **********************************************************************
00006  
00007      void cumchn(double *x,double *df,double *pnonc,double *cum,
00008             double *ccum)
00009 
00010              CUMulative of the Non-central CHi-square distribution
00011  
00012  
00013                               Function
00014  
00015  
00016      Calculates     the       cumulative      non-central    chi-square
00017      distribution, i.e.,  the probability   that  a   random   variable
00018      which    follows  the  non-central chi-square  distribution,  with
00019      non-centrality  parameter    PNONC  and   continuous  degrees   of
00020      freedom DF, is less than or equal to X.
00021  
00022  
00023                               Arguments
00024  
00025  
00026      X       --> Upper limit of integration of the non-central
00027                  chi-square distribution.
00028                                                  X is DOUBLE PRECISION
00029  
00030      DF      --> Degrees of freedom of the non-central
00031                  chi-square distribution.
00032                                                  DF is DOUBLE PRECISION
00033  
00034      PNONC   --> Non-centrality parameter of the non-central
00035                  chi-square distribution.
00036                                                  PNONC is DOUBLE PRECIS
00037  
00038      CUM <-- Cumulative non-central chi-square distribution.
00039                                                  CUM is DOUBLE PRECISIO
00040  
00041      CCUM <-- Compliment of Cumulative non-central chi-square distribut
00042                                                  CCUM is DOUBLE PRECISI
00043  
00044  
00045                               Method
00046  
00047  
00048      Uses  formula  26.4.25   of  Abramowitz  and  Stegun, Handbook  of
00049      Mathematical    Functions,  US   NBS   (1966)    to calculate  the
00050      non-central chi-square.
00051  
00052  
00053                               Variables
00054  
00055  
00056      EPS     --- Convergence criterion.  The sum stops when a
00057                  term is less than EPS*SUM.
00058                                                  EPS is DOUBLE PRECISIO
00059  
00060      NTIRED  --- Maximum number of terms to be evaluated
00061                  in each sum.
00062                                                  NTIRED is INTEGER
00063  
00064      QCONV   --- .TRUE. if convergence achieved -
00065                  i.e., program did not stop on NTIRED criterion.
00066                                                  QCONV is LOGICAL
00067  
00068      CCUM <-- Compliment of Cumulative non-central
00069               chi-square distribution.
00070                                                  CCUM is DOUBLE PRECISI
00071  
00072 **********************************************************************
00073 */
00074 {
00075 #define dg(i) (*df+2.0e0*(double)(i))
00076 #define qsmall(xx) (int)(sum < 1.0e-20 || (xx) < eps*sum)
00077 #define qtired(i) (int)((i) > ntired)
00078 static double eps = 1.0e-5;
00079 static int ntired = 1000;
00080 static double adj,centaj,centwt,chid2,dfd2,lcntaj,lcntwt,lfact,pcent,pterm,sum,
00081     sumadj,term,wt,xnonc;
00082 static int i,icent,iterb,iterf;
00083 static double T1,T2,T3;
00084 /*
00085      ..
00086      .. Executable Statements ..
00087 */
00088     if(!(*x <= 0.0e0)) goto S10;
00089     *cum = 0.0e0;
00090     *ccum = 1.0e0;
00091     return;
00092 S10:
00093     if(!(*pnonc <= 1.0e-10)) goto S20;
00094 /*
00095      When non-centrality parameter is (essentially) zero,
00096      use cumulative chi-square distribution
00097 */
00098     cumchi(x,df,cum,ccum);
00099     return;
00100 S20:
00101     xnonc = *pnonc/2.0e0;
00102 /*
00103 **********************************************************************
00104      The following code calcualtes the weight, chi-square, and
00105      adjustment term for the central term in the infinite series.
00106      The central term is the one in which the poisson weight is
00107      greatest.  The adjustment term is the amount that must
00108      be subtracted from the chi-square to move up two degrees
00109      of freedom.
00110 **********************************************************************
00111 */
00112     icent = fifidint(xnonc);
00113     if(icent == 0) icent = 1;
00114     chid2 = *x/2.0e0;
00115 /*
00116      Calculate central weight term
00117 */
00118     T1 = (double)(icent+1);
00119     lfact = alngam(&T1);
00120     lcntwt = -xnonc+(double)icent*log(xnonc)-lfact;
00121     centwt = exp(lcntwt);
00122 /*
00123      Calculate central chi-square
00124 */
00125     T2 = dg(icent);
00126     cumchi(x,&T2,&pcent,ccum);
00127 /*
00128      Calculate central adjustment term
00129 */
00130     dfd2 = dg(icent)/2.0e0;
00131     T3 = 1.0e0+dfd2;
00132     lfact = alngam(&T3);
00133     lcntaj = dfd2*log(chid2)-chid2-lfact;
00134     centaj = exp(lcntaj);
00135     sum = centwt*pcent;
00136 /*
00137 **********************************************************************
00138      Sum backwards from the central term towards zero.
00139      Quit whenever either
00140      (1) the zero term is reached, or
00141      (2) the term gets small relative to the sum, or
00142      (3) More than NTIRED terms are totaled.
00143 **********************************************************************
00144 */
00145     iterb = 0;
00146     sumadj = 0.0e0;
00147     adj = centaj;
00148     wt = centwt;
00149     i = icent;
00150     goto S40;
00151 S30:
00152     if(qtired(iterb) || qsmall(term) || i == 0) goto S50;
00153 S40:
00154     dfd2 = dg(i)/2.0e0;
00155 /*
00156      Adjust chi-square for two fewer degrees of freedom.
00157      The adjusted value ends up in PTERM.
00158 */
00159     adj = adj*dfd2/chid2;
00160     sumadj += adj;
00161     pterm = pcent+sumadj;
00162 /*
00163      Adjust poisson weight for J decreased by one
00164 */
00165     wt *= ((double)i/xnonc);
00166     term = wt*pterm;
00167     sum += term;
00168     i -= 1;
00169     iterb += 1;
00170     goto S30;
00171 S50:
00172     iterf = 0;
00173 /*
00174 **********************************************************************
00175      Now sum forward from the central term towards infinity.
00176      Quit when either
00177      (1) the term gets small relative to the sum, or
00178      (2) More than NTIRED terms are totaled.
00179 **********************************************************************
00180 */
00181     sumadj = adj = centaj;
00182     wt = centwt;
00183     i = icent;
00184     goto S70;
00185 S60:
00186     if(qtired(iterf) || qsmall(term)) goto S80;
00187 S70:
00188 /*
00189      Update weights for next higher J
00190 */
00191     wt *= (xnonc/(double)(i+1));
00192 /*
00193      Calculate PTERM and add term to sum
00194 */
00195     pterm = pcent-sumadj;
00196     term = wt*pterm;
00197     sum += term;
00198 /*
00199      Update adjustment term for DF for next iteration
00200 */
00201     i += 1;
00202     dfd2 = dg(i)/2.0e0;
00203     adj = adj*chid2/dfd2;
00204     sumadj += adj;
00205     iterf += 1;
00206     goto S60;
00207 S80:
00208     *cum = sum;
00209     *ccum = 0.5e0+(0.5e0-*cum);
00210     return;
00211 #undef dg
00212 #undef qsmall
00213 #undef qtired
00214 } /* END */
 

Powered by Plone

This site conforms to the following standards: