/*-------------------------------------------------------------- EVScb1Matrix() - computes the first-order counter-balance matrix. The number in element i,j is the number of times that condition i was followed by condition j. This does not include condition 0. --------------------------------------------------------------*/ MATRIX *EVScb1Matrix(EVSCH *EvSch) { MATRIX *Ncb1; int nthev, i,j; Ncb1 = MatrixZero(EvSch->nEvTypes,EvSch->nEvTypes,NULL); for (nthev=0; nthev < EvSch->nevents-1; nthev++) { i = EvSch->eventid[nthev]; j = EvSch->eventid[nthev+1]; if (i==0 || j==0) continue; Ncb1->rptr[i][j]++; } return(Ncb1); }
static FUNC *ConvertTransform( FUNC *func, EDAT xform[16] ) { int d, which ; FUNC *loop ; static EDAT gnew[16] = ZERO_EDAT_16 ; EXPR *arg, *expr ; MatrixMultiInit(4) ; for( loop = func ; loop ; loop = OpticForward( FuncNext(loop) ) ) { which = (int) ( ExprValue( FuncArg( loop, 0 ) ) + 0.49 ) ; if( which > 5 ) /* surface */ break ; arg = Copy( FuncArg( loop, 1 ) ) ; if( FuncIsReversed( loop ) ) arg = Ecc( arg, "u-", Garbage() ) ; MatrixIdentity( 4, gnew ) ; if( which < 3 ) gnew[ RC( which, 3 ) ].E = ECc( arg, "u-", Garbage() ) ; else { d = which - 3 ; expr = ECc( arg, "cos", Garbage() ) ; gnew[ RC( (d+1)%3, (d+1)%3 ) ].E = Copy( expr ) ; gnew[ RC( (d+2)%3, (d+2)%3 ) ].E = expr ; expr = ECc( arg, "sin", Garbage() ) ; gnew[ RC( (d+1)%3, (d+2)%3 ) ].E = Copy( expr ) ; expr = Ecc( expr, "u-", Garbage() ) ; gnew[ RC( (d+2)%3, (d+1)%3 ) ].E = expr ; } Free( arg ) ; MatrixMultiNew( 4, gnew ) ; MatrixZero( 4, gnew ) ; /* free it up */ } MatrixMultiResult( 4, xform ) ; MatrixMultiInit(4) ; return loop ; }
/*-------------------------------------------------------------- EVScb1IdealProbMatrix() - computes the ideal first-order counter-balance PROBABILITY matrix. The value in element i,j is the ideal probability that condition i should be followed by condition j, which is just equal to the probability of condition j. This does not include condition 0. --------------------------------------------------------------*/ MATRIX *EVScb1IdealProbMatrix(EVSCH *EvSch) { MATRIX *IdealPcb1; int i,j; IdealPcb1 = MatrixZero(EvSch->nEvTypes,EvSch->nEvTypes,NULL); for (i=1; i<= EvSch->nEvTypes; i++) { for (j=1; j<= EvSch->nEvTypes; j++) { //printf("i=%d, j=%d, IP = %g, nEVj=%d, nev=%d\n",i,j, // IdealPcb1->rptr[i][j],EvSch->nEvReps[j-1],EvSch->nevents); IdealPcb1->rptr[i][j] = (float)EvSch->nEvReps[j-1]/EvSch->nevents; /* Note: j-1 needed in nEvReps because its normal C array */ } } return(IdealPcb1); }
/*-------------------------------------------------------------- EVScb1ProbMatrix() - computes an estimate of the first-order counter-balance PROBABILITY matrix. The value in element i,j is the probability (or rate) that condition i was followed by condition j. This does not include condition 0. In theory, the rows of Pcb1 should sum to 1.0, but this will not be the case for which ever condition the sequence ends on. --------------------------------------------------------------*/ MATRIX *EVScb1ProbMatrix(EVSCH *EvSch) { MATRIX *Ncb1, *Pcb1=NULL; int i,j; Ncb1 = EVScb1Matrix(EvSch); Pcb1 = MatrixZero(EvSch->nEvTypes,EvSch->nEvTypes,NULL); for (i=1; i<= EvSch->nEvTypes; i++) { for (j=1; j<= EvSch->nEvTypes; j++) { Pcb1->rptr[i][j] = Ncb1->rptr[i][j]/EvSch->nEvReps[i-1]; /* Note: i-1 needed in nEvReps because its normal C array */ } } MatrixFree(&Ncb1); return(Pcb1); }
/*------------------------------------------------------------- EVS2FIRmtx() - convert an event schedule for a given event id into an FIR design matrix. -------------------------------------------------------------*/ MATRIX *EVS2FIRmtx(int EvId, EVSCH *EvSch, float tDelay, float TR, int Ntps, float PSDMin, float PSDMax, float dPSD, MATRIX *X) { float tMax, tmp, PSDWindow, tPSD, PSD; int RSR, Npsds, nthPSD, n, rA, rB; /* Compute number of PSDs in the window */ PSDWindow = PSDMax-PSDMin; tmp = rint(PSDWindow/dPSD) - PSDWindow/dPSD; if (tmp > .0001) { printf("ERROR: EVS2FIRmtx: PSDWindow (%g) is not an integer multiple of dPSD (%g)\n", PSDWindow,dPSD); return(NULL); } Npsds = rint(PSDWindow/dPSD); /* Compute resampling rate */ tmp = rint(TR/dPSD) - TR/dPSD; if (tmp > .0001) { printf("ERROR: EVS2FIRmtx: TR (%g) is not an integer multiple " " of dPSD (%g)\n", TR, dPSD); return(NULL); } RSR = rint(TR/dPSD); /* Compute the time of the last row in X */ tMax = TR*(Ntps-1); /* Create X with all zeros */ if (X==NULL) X = MatrixAlloc(Ntps,Npsds,MATRIX_REAL); else { if (X->rows != Ntps || X->rows != Npsds) { printf("ERROR: EVS2FIRmtx: dimensions of X mismatch\n"); return(NULL); } X = MatrixZero(Ntps,Npsds,X); } /* Fill-in the non-zero entries of X for each event */ /* nthPSD will be the column in X */ for (nthPSD = 0; nthPSD < Npsds; nthPSD++) { PSD = nthPSD*dPSD + PSDMin; for (n = 0; n < EvSch->nevents; n++) { if (EvSch->eventid[n] != EvId) continue; tPSD = EvSch->tevent[n] + tDelay + PSD; if (tPSD < 0.0) continue; if (tPSD > tMax) break; /* Could compute the time of the closest row, then skip if fabs(tRow-tPSD) > dPSD/2 ????? This would be easily extended to the cases where the data were not aquired uniformly in time. */ /* rA would be the row of X if the rows of X were separated by dPSD */ rA = (int)rint(tPSD/dPSD); /* If rA does not fall into a row of X, skip */ if ( (rA % RSR) != 0) continue; /* rB is the row of X */ rB = rA/RSR; if (EvSch->weight != NULL) X->rptr[rB+1][nthPSD+1] = EvSch->weight[n]; else X->rptr[rB+1][nthPSD+1] = 1; } } return(X); }
/*-------------------------------------------------------------------- EVSdesignMtxStats() - computes statistics about design relevant for optimization. stats should have at least 6 elements. Returns 1 is the design is singular, 0 otherwise. ERROR: This needs to be modified to compute the VRF differently when there are different numbers of stimuli in each event type.x -------------------------------------------------------------------*/ int EVSdesignMtxStats(MATRIX *Xtask, MATRIX *Xnuis, EVSCH *EvSch, MATRIX *C, MATRIX *W) { MATRIX *X=NULL, *Xt=NULL, *XtX=NULL; MATRIX *iXtX=NULL, *VRF=NULL, *Ct=NULL, *CiXtX=NULL, *CiXtXCt=NULL; int r,m,nTaskAvgs,nNuisAvgs,nAvgs,Cfree,J; float diagsum; double dtmp, dtmp1, dtmp2; X = MatrixHorCat(Xtask,Xnuis,NULL); nTaskAvgs = Xtask->cols; if (Xnuis != NULL) nNuisAvgs = Xnuis->cols; else nNuisAvgs = 0; nAvgs = X->cols; if (W != NULL) X = MatrixMultiply(W,X,NULL); Xt = MatrixTranspose(X,Xt); XtX = MatrixMultiply(Xt,X,XtX); /* Compute the Inverse */ iXtX = MatrixInverse(XtX,NULL); Cfree = 0; if (C==NULL) { C = MatrixZero(nTaskAvgs,nAvgs,NULL); for (m=0; m < nTaskAvgs; m++) C->rptr[m+1][m+1] = 1; Cfree = 1; } J = C->rows; Ct = MatrixTranspose(C,NULL); /* Make sure that it was actually inverted */ if (iXtX != NULL) { r = 0; CiXtX = MatrixMultiply(C,iXtX,NULL); CiXtXCt = MatrixMultiply(CiXtX,Ct,NULL); VRF = MatrixAlloc(J,1,MATRIX_REAL); diagsum = 0.0; for (m=0; m < J; m++) {/* exctract diag */ diagsum += CiXtXCt->rptr[m+1][m+1]; VRF->rptr[m+1][1] = 1.0/(CiXtXCt->rptr[m+1][m+1]); } EvSch->eff = 1.0/diagsum; if (J>1) EvSch->vrfstd = VectorStdDev(VRF,&dtmp); else EvSch->vrfstd = 0.0; EvSch->vrfavg = dtmp; EvSch->vrfrange = VectorRange(VRF,&dtmp1,&dtmp2); EvSch->vrfmin = dtmp1; EvSch->vrfmax = dtmp2; MatrixFree(&iXtX); MatrixFree(&CiXtX); MatrixFree(&CiXtXCt); MatrixFree(&VRF); } else r = 1; MatrixFree(&X); MatrixFree(&Xt); MatrixFree(&XtX); if (Cfree) MatrixFree(&C); MatrixFree(&Ct); return(r); }