void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *val, *p, p1=0.0,p2=0.0,p3=0.0 ; int code=5, dop=1, doq=0, dod=0, doi=0, doz=0, doh=0 ; int ndim, i, n; const int *dim; if (nlhs>1) mexErrMsgTxt("Too many output arguments."); if (nrhs<1) mexErrMsgTxt("Not enough input arguments."); if (nrhs>4) mexErrMsgTxt("Too many input arguments."); /* VAL */ if (!mxIsNumeric(prhs[0]) || !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0])) mexErrMsgTxt("Wrong datatype for 1st argument."); ndim = mxGetNumberOfDimensions(prhs[0]); dim = mxGetDimensions(prhs[0]); n = 1; for(i=0,n=1; i<ndim; i++) n = n*dim[i]; val = mxGetPr(prhs[0]); /* CODE */ if (nrhs>=2) { if (mxIsChar(prhs[1])) { int buflen; char *buf; buflen = mxGetN(prhs[1])*mxGetM(prhs[1])+1; buf = (char *)mxCalloc(buflen,sizeof(char)); mxGetString(prhs[1],buf,buflen); code = nifti_intent_code(buf); mxFree(buf); } else if (mxIsNumeric(prhs[1]) && mxIsDouble(prhs[1]) && !mxIsComplex(prhs[1])) { if (mxGetM(prhs[1])*mxGetN(prhs[1]) != 1) mexErrMsgTxt("Wrong sized 2nd argument."); code = (int)mxGetPr(prhs[1])[0]; } else mexErrMsgTxt("Wrong datatype for 2nd argument."); if (code<NIFTI_FIRST_STATCODE || code>NIFTI_LAST_STATCODE) mexErrMsgTxt("Illegal Stat-Code."); } /* OPT */ if (nrhs>=3) { int buflen; char *buf; dop = 0; if (!mxIsChar(prhs[2])) mexErrMsgTxt("Wrong datatype for3rd argument."); buflen = mxGetN(prhs[2])*mxGetM(prhs[2])+1; buf = (char *)mxCalloc(buflen,sizeof(char)); mxGetString(prhs[2],buf,buflen); if ( strcmp(buf,"-p") == 0 ) dop = 1; else if ( strcmp(buf,"-q") == 0 ) doq = 1; else if ( strcmp(buf,"-d") == 0 ) dod = 1; else if ( strcmp(buf,"-1") == 0 ) doi = 1; else if ( strcmp(buf,"-z") == 0 ) doz = 1; else if ( strcmp(buf,"-h") == 0 ) doh = 1; else { mxFree(buf); mexErrMsgTxt("Unrecognised option."); } mxFree(buf); } /* PARAM */ if (nrhs>=4) { int np; if (!mxIsNumeric(prhs[3]) || !mxIsDouble(prhs[3]) || mxIsComplex(prhs[3])) mexErrMsgTxt("Wrong datatype for 4th argument."); np = mxGetM(prhs[3])*mxGetN(prhs[3]); if (np>3) mexErrMsgTxt("Wrong sized 4th argument."); if (np>=1) p1 = mxGetPr(prhs[3])[0]; if (np>=2) p2 = mxGetPr(prhs[3])[1]; if (np>=3) p3 = mxGetPr(prhs[3])[2]; } /* P */ plhs[0] = mxCreateNumericArray(ndim,dim,mxDOUBLE_CLASS,mxREAL); p = mxGetData(plhs[0]); /* Call Bob's code */ for(i=0; i<n; i++) { if ( dop ) p[i] = nifti_stat2cdf(val[i], code,p1,p2,p3 ) ; else if ( doq ) p[i] = nifti_stat2rcdf(val[i], code,p1,p2,p3 ) ; else if ( dod ) p[i] = 1000.0*( nifti_stat2cdf(val[i]+.001,code,p1,p2,p3) -nifti_stat2cdf(val[i] ,code,p1,p2,p3)) ; else if ( doi ) p[i] = nifti_cdf2stat(val[i], code,p1,p2,p3 ) ; else if ( doz ) p[i] = nifti_stat2zscore(val[i], code,p1,p2,p3 ) ; else if ( doh ) p[i] = nifti_stat2hzscore(val[i], code,p1,p2,p3 ) ; } }
int main( int argc , char *argv[] ) { double val , p , p1=0.0,p2=0.0,p3=0.0 ; double vbot,vtop,vdel ; int code , iarg=1 , doq=0 , dod=0 , doi=0 , doz=0 , doh=0 ; /*-- print some help for the pitiful user --*/ if( argc < 3 || strstr(argv[1],"help") != NULL ){ int ii ; printf("\n") ; printf("Demo program for computing NIfTI statistical functions.\n") ; printf("Usage: nifti_stats [-q|-d|-1|-z] val CODE [p1 p2 p3]\n") ; printf(" val can be a single number or in the form bot:top:step.\n") ; printf(" default ==> output p = Prob(statistic < val).\n") ; printf(" -q ==> output is 1-p.\n") ; printf(" -d ==> output is density.\n") ; printf(" -1 ==> output is x such that Prob(statistic < x) = val.\n") ; printf(" -z ==> output is z such that Normal cdf(z) = p(val).\n") ; printf(" -h ==> output is z such that 1/2-Normal cdf(z) = p(val).\n"); printf(" Allowable CODEs:\n") ; for( ii=NIFTI_FIRST_STATCODE ; ii <= NIFTI_LAST_STATCODE ; ii++ ){ printf(" %-10s",inam[ii]); if((ii-NIFTI_FIRST_STATCODE)%6==5)printf("\n"); } printf("\n") ; printf(" Following CODE are distributional parameters, as needed.\n"); printf("\n") ; printf("Results are written to stdout, 1 number per output line.\n") ; printf("Example (piping output into AFNI program 1dplot):\n") ; printf(" nifti_stats -d 0:4:.001 INVGAUSS 1 3 | 1dplot -dx 0.001 -stdin\n"); printf("\n") ; printf("Author - RW Cox - SSCC/NIMH/NIH/DHHS/USA/EARTH - March 2004\n") ; printf("\n") ; exit(0) ; } /*-- check first arg to see if it is an output option; if so, set the appropriate output flag to determine what to compute --*/ if( strcmp(argv[iarg],"-q") == 0 ){ doq = 1 ; iarg++ ; } else if( strcmp(argv[iarg],"-d") == 0 ){ dod = 1 ; iarg++ ; } else if( strcmp(argv[iarg],"-1") == 0 ){ doi = 1 ; iarg++ ; } else if( strcmp(argv[iarg],"-z") == 0 ){ doz = 1 ; iarg++ ; } else if( strcmp(argv[iarg],"-h") == 0 ){ doh = 1 ; iarg++ ; } /*-- get the value(s) to process --*/ vbot=vtop=vdel = 0.0 ; sscanf( argv[iarg++] , "%lf:%lf:%lf" , &vbot,&vtop,&vdel ) ; if( vbot >= vtop ) vdel = 0.0 ; if( vdel <= 0.0 ) vtop = vbot ; /*-- decode the CODE into the integer signifying the distribution --*/ code = nifti_intent_code(argv[iarg++]) ; if( code < 0 ){ fprintf(stderr,"illegal code=%s\n",argv[iarg-1]); exit(1); } /*-- get the parameters, if present (defaults are 0) --*/ if( argc > iarg ) p1 = strtod(argv[iarg++],NULL) ; if( argc > iarg ) p2 = strtod(argv[iarg++],NULL) ; if( argc > iarg ) p3 = strtod(argv[iarg++],NULL) ; /*-- loop over input value(s), compute output, write to stdout --*/ for( val=vbot ; val <= vtop ; val += vdel ){ if( doq ) /* output = 1-cdf */ p = nifti_stat2rcdf( val , code,p1,p2,p3 ) ; else if( dod ) /* output = density */ p = 1000.0*( nifti_stat2cdf(val+.001,code,p1,p2,p3) -nifti_stat2cdf(val ,code,p1,p2,p3)) ; else if( doi ) /* output = inverse */ p = nifti_cdf2stat( val , code,p1,p2,p3 ) ; else if( doz ) /* output = z score */ p = nifti_stat2zscore( val , code,p1,p2,p3 ) ; else if( doh ) /* output = halfz score */ p = nifti_stat2hzscore( val , code,p1,p2,p3 ) ; else /* output = cdf */ p = nifti_stat2cdf( val , code,p1,p2,p3 ) ; printf("%.9g\n",p) ; if( vdel <= 0.0 ) break ; /* the case of just 1 value */ } /*-- terminus est --*/ exit(0) ; }