void PCOR_get_lsqfit(PCOR_references * ref, PCOR_voxel_corr * vc, float *fit[] ) { int vox,jj,kk , nv = vc->nvox , nr = vc->nref ; float sum ; float * ff ; /*** check inputs for OK-ness ***/ if( vc->nref != ref->nref ){ fprintf( stderr , "\nPCOR_get_lsqfit: reference size mismatch!\n" ) ; EXIT(1) ; } kk = 0 ; for( jj=0 ; jj < nr ; jj++ ) kk += (fit[jj] != NULL) ; if( kk == 0 ){ fprintf(stderr,"PCOR_get_lsqfit: NO OUTPUT REQUESTED!\n") ; return ; } ff = (float *) malloc( sizeof(float) * nr ) ; if( ff == NULL ){ fprintf( stderr, "\nPCOR_get_lsqfit: can't malloc workspace!\n") ; EXIT(1) ; } /*** for each voxel, compute the nr fit coefficients (backwards) ***/ for( vox=0 ; vox < nv ; vox++ ){ for( jj=nr-1 ; jj >=0 ; jj-- ){ sum = VCH(vc,vox,jj) ; for( kk=jj+1 ; kk < nr ; kk++ ) sum -= ff[kk] * RCH(ref,kk,jj) ; ff[jj] = sum / RCH(ref,jj,jj) ; } for( jj=0 ; jj < nr ; jj++ ) if( fit[jj] != NULL ) fit[jj][vox] = ff[jj] ; } free( ff ) ; return ; }
void add(TREE2,int x,double v){ M; ++tot; o1[tot] = o1[_t];o2[tot] = o2[_t];sgt[tot] = sgt[_t]; _t = tot; if(_l == _r) { sgt[_t].s[1] += v/double(x),sgt[_t].s[2] += v; return;} if(x <= mid) add(LEFT,x,v);else add(RIGHT,x,v); sgt[_t] = sgt[LCH(_t)] + sgt[RCH(_t)]; }
void PCOR_get_pcor_and_coef(PCOR_references * ref , PCOR_voxel_corr * vc , float pcthresh , float * pcor , float * coef ) { int vox , nv = vc->nvox , nr = vc->nref ; float den , num , scale ; float pc , co , thfac ; /*** check inputs for OK-ness ***/ if( vc->nref != ref->nref ){ fprintf( stderr , "\nPCOR_get_pcor_and_coef: reference size mismatch!\n" ) ; EXIT(1) ; } scale = 1.0 / RCH(ref,nr-1,nr-1) ; /* for coef calculation */ thfac = SQR(pcthresh)/(1.0-SQR(pcthresh)) ; /*** Compute pcor and coef, thresholded on pcthresh ***/ if( pcthresh <= 0.0 ){ for( vox=0 ; vox < nv ; vox++ ){ den = VCH(vc,vox,nr) ; num = VCH(vc,vox,nr-1) ; pcor[vox] = num / sqrt(den+SQR(num)) ; coef[vox] = scale * num ; } } else { thfac = SQR(pcthresh)/(1.0-SQR(pcthresh)) ; for( vox=0 ; vox < nv ; vox++ ){ den = VCH(vc,vox,nr) ; num = VCH(vc,vox,nr-1) ; if( SQR(num) > thfac*den ){ /* fancy threshold test */ pcor[vox] = num / sqrt(den+SQR(num)) ; coef[vox] = scale * num ; } else { /* fails pcor thresh */ pcor[vox] = coef[vox] = 0.0 ; } } } return ; }
void PCOR_get_coef(PCOR_references * ref, PCOR_voxel_corr * vc, float * coef) { int vox , nv = vc->nvox , nr = vc->nref ; float scale ; /*** check inputs for OK-ness ***/ if( vc->nref != ref->nref ){ fprintf( stderr , "\nPCOR_get_coef: reference size mismatch!\n" ) ; EXIT(1) ; } /*** Work ***/ scale = 1.0 / RCH(ref,nr-1,nr-1) ; for( vox=0 ; vox < nv ; vox++ ){ coef[vox] = scale * VCH(vc,vox,nr-1) ; } return ; }
void PCOR_get_perc(PCOR_references * ref, PCOR_voxel_corr * vc, float * coef, float * bline, int basaver ) { int vox,jj,kk , nv=vc->nvox , nr=vc->nref , nup=ref->nupdate ; float sum , base , rdif , rmin , rmax ; float * ff , * bb , * dd ; /*** check inputs for OK-ness ***/ if( vc->nref != ref->nref ){ fprintf( stderr , "\nPCOR_get_perc: reference size mismatch!\n" ) ; EXIT(1) ; } if( coef == NULL && bline == NULL ) return ; /* nothing to do */ /*** Setup ***/ ff = (float *) malloc( sizeof(float) * nr ) ; bb = (float *) malloc( sizeof(float) * nr ) ; dd = (float *) malloc( sizeof(float) * nr ) ; if( ff == NULL || bb == NULL || dd == NULL ){ fprintf( stderr, "\nPCOR_get_perc: can't malloc workspace!\n") ; EXIT(1) ; } /* range of last reference */ rmin = ref->rmin[nr-1] ; rmax = ref->rmax[nr-1] ; rdif = 100.0 * (rmax-rmin) ; if( rdif == 0.0 ){ /** 06 Dec 2000: zero out both coef and bline in this case **/ if( coef != NULL ) for( vox=0; vox < nv; vox++ ) coef[vox] = 0.0; if( bline != NULL ) for( vox=0; vox < nv; vox++ ) bline[vox] = 0.0; fprintf(stderr,"\nPCOR_get_perc: ref vector has no range!\n") ; return ; } for( jj=0 ; jj < nr ; jj++ ){ bb[jj] = ref->rsum[jj] / nup ; /* average of each ref */ dd[jj] = 1.0 / RCH(ref,jj,jj) ; /* factor for loop below */ } /*** Work: jj=nr-2 x(t) = fit[nr-1] * ref(t,nr-1) + SUM fit[jj] * ref(t,jj) jj=0 The percent change due to ref(t,nr-1) is computed by scaling this ref to run from 0 to 1 (that's why rmin and rmax are used), and by computing the baseline as fit[nr-1]*rmin + the sum of the averages of the other refs times their fit coefficients. ***/ for( vox=0 ; vox < nv ; vox++ ){ for( jj=nr-1 ; jj >=0 ; jj-- ){ /* compute fit coefficients */ sum = VCH(vc,vox,jj) ; for( kk=jj+1 ; kk < nr ; kk++ ) sum -= ff[kk] * RCH(ref,kk,jj) ; ff[jj] = sum * dd[jj] ; } switch( basaver ){ default: case 0: base = ff[nr-1] * rmin ; break; /* baseline = bottom */ case 1: base = ff[nr-1] * bb[nr-1]; break; /* baseline = average */ case 2: base = ff[nr-1] * rmax ; break; /* baseline = top */ } for( jj=0 ; jj < nr-1 ; jj++ ) /* 30 May 1999: used to have nr-2 */ base += ff[jj] * bb[jj] ; /* which was wrong! */ if( coef != NULL ) coef[vox] = (base > 0.0) ? ff[nr-1] * rdif / base : 0.0 ; if( bline != NULL ) bline[vox] = base ; } free(ff) ; free(bb) ; free(dd) ; return ; }
PCOR_references * new_PCOR_references(int numref) { PCOR_references *ref ; int ii,jj , nbad ; /*** check input for reasonableness ***/ if( numref < 1 ){ fprintf( stderr , "new_PCOR_references called with numref=%d\n" , numref ) ; return NULL ; } /*** allocate storage for top level data ***/ /* from malloc 12 Feb 2009 [lesstif patrol] */ ref = (PCOR_references *) calloc( 1, sizeof(PCOR_references) ) ; if( ref == NULL ){ fprintf( stderr , "new_PCOR_references: malloc error for base\n" ) ; return NULL ; } ref->nref = numref ; ref->nupdate = 0 ; /* June 1995: not updated at all yet */ /*** allocate storage for Cholesky factor (an array of rows, row #ii is length ii+1, for ii=0..numref-1) ***/ ref->chol = (float **) malloc( sizeof(float *) * numref ) ; if( ref->chol == NULL ){ fprintf( stderr , "new_PCOR_references: malloc error for chol\n" ) ; free(ref) ; return NULL ; } for( ii=0,nbad=0 ; ii < numref ; ii++ ){ ref->chol[ii] = (float *) malloc( sizeof(float) * (ii+1) ) ; if( ref->chol[ii] == NULL ) nbad++ ; } if( nbad > 0 ){ fprintf( stderr , "new_PCOR_references: malloc error for chol[ii]\n" ) ; free_PCOR_references( ref ) ; return NULL ; } /*** allocate storage for vectors of alpha, f, g ***/ ref->alp = (float *) malloc( sizeof(float) * numref ) ; ref->ff = (float *) malloc( sizeof(float) * numref ) ; ref->gg = (float *) malloc( sizeof(float) * numref ) ; if( ref->alp == NULL || ref->ff == NULL || ref->gg == NULL ){ fprintf( stderr , "new_PCOR_references: malloc error for data\n" ) ; free_PCOR_references( ref ) ; return NULL ; } /*** 14 Jan 1998: space for ref vector statistics ***/ ref->rmin = (float *) malloc( sizeof(float) * numref ) ; ref->rmax = (float *) malloc( sizeof(float) * numref ) ; ref->rsum = (float *) malloc( sizeof(float) * numref ) ; if( ref->rmin == NULL || ref->rmax == NULL || ref->rsum == NULL ){ fprintf( stderr , "new_PCOR_references: malloc error for data\n" ) ; free_PCOR_references( ref ) ; return NULL ; } /*** initialize Cholesky factor ***/ for( ii=0 ; ii < numref ; ii++ ){ for( jj=0 ; jj < ii ; jj++ ) RCH(ref,ii,jj) = 0.0 ; RCH(ref,ii,ii) = REF_EPS ; } return ref ; }
void update_PCOR_references(float * vec, PCOR_references * ref) { int nr = ref->nref , jj,kk ; float bold , bnew , aaa,fff,ggg ; static float * zz = NULL ; /* local storage for a copy of vec */ static int zz_size = -1 ; /*** copy vector data into local storage (will be altered below) ***/ if( zz_size < nr ){ /* get new space, if not enough is present */ if( zz != NULL ) free( zz ) ; zz = (float *) malloc( sizeof(float) * nr ) ; zz_size = nr ; if( zz == NULL ){ fprintf( stderr , "\nupdate_PCOR_references: can't malloc!\n" ) ; EXIT(1) ; } } for( jj=0 ; jj < nr ; jj++) zz[jj] = vec[jj] ; /*** 14 Jan 1998: collect ref vector stats ***/ if( ref->nupdate == 0 ){ /* initialize */ for( jj=0 ; jj < nr ; jj++ ){ ref->rmin[jj] = ref->rmax[jj] = ref->rsum[jj] = zz[jj] ; } } else { register float val ; for( jj=0 ; jj < nr ; jj++ ){ val = zz[jj] ; ref->rsum[jj] += val ; if( val < ref->rmin[jj] ) ref->rmin[jj] = val ; else if( val > ref->rmax[jj] ) ref->rmax[jj] = val ; } } /*** Carlson algorithm ***/ bold = 1.0 ; for( jj=0 ; jj < nr ; jj++ ){ aaa = zz[jj] / RCH(ref,jj,jj) ; /* alpha */ bnew = sqrt( bold*bold + aaa*aaa ) ; /* new beta */ fff = bnew / bold ; /* f factor */ ggg = aaa / (bnew*bold) ; /* g factor */ bold = bnew ; /* new beta becomes old beta */ ref->alp[jj] = aaa ; /* save these for later use */ ref->ff[jj] = fff ; ref->gg[jj] = ggg ; for( kk=jj ; kk < nr ; kk++ ){ zz[kk] -= aaa * RCH(ref,kk,jj) ; RCH(ref,kk,jj) = fff * RCH(ref,kk,jj) + ggg * zz[kk] ; } } ref->betasq = 1.0 / ( bold * bold ) ; /* and save this too! */ (ref->nupdate)++ ; /* June 1995: another update! */ return ; }