//Multiply this with b Matrix* Matrix::multiplyMatrix(Matrix* b) { if(col!=b->getRowCnt()) { return NULL; } Matrix* res=new Matrix(row,b->getColCnt()); gsl_matrix_set_zero (res->matrix); gsl_matrix_float* resmatrix=gsl_matrix_float_alloc(row,b->getColCnt()); convertToFloat(resmatrix,res->matrix,row,b->getColCnt()); gsl_matrix_float* cmatrix=gsl_matrix_float_alloc(row,col); convertToFloat(cmatrix,matrix,row,col); gsl_matrix_float* bmatrix=gsl_matrix_float_alloc(b->getRowCnt(),b->getColCnt()); convertToFloat(bmatrix,b->matrix,b->getRowCnt(),b->getColCnt()); gsl_blas_sgemm (CblasNoTrans, CblasNoTrans, 1, cmatrix, bmatrix, 0, resmatrix); convertFromFloat(resmatrix,res->matrix,row,b->getColCnt()); gsl_matrix_float_free(resmatrix); gsl_matrix_float_free(cmatrix); gsl_matrix_float_free(bmatrix); return res; }
int Matrix::multiplyWithMatrix(Matrix* b) { if(col!=b->getRowCnt()) { return -1; } gsl_matrix* res=gsl_matrix_alloc(row,b->getColCnt()); gsl_matrix_set_zero(res); gsl_matrix_float* resmatrix=gsl_matrix_float_alloc(row,b->getColCnt()); convertToFloat(resmatrix,res,row,b->getColCnt()); gsl_matrix_float* cmatrix=gsl_matrix_float_alloc(row,col); convertToFloat(cmatrix,matrix,row,col); gsl_matrix_float* bmatrix=gsl_matrix_float_alloc(b->getRowCnt(),b->getColCnt()); convertToFloat(bmatrix,b->matrix,b->getRowCnt(),b->getColCnt()); gsl_blas_sgemm(CblasNoTrans, CblasNoTrans, 1, cmatrix, bmatrix, 0, resmatrix); convertFromFloat(resmatrix,res,row,b->getColCnt()); gsl_matrix_float_free(resmatrix); gsl_matrix_float_free(cmatrix); gsl_matrix_float_free(bmatrix); gsl_matrix_memcpy(matrix, res); gsl_matrix_free(res); return 0; }
/* ** general linear regression */ VAttrList VRegression(ListInfo *linfo, int nlists, VShort minval, VImage design, VFloat sigma, VLong itr) { VAttrList out_list; VImageInfo *xinfo; int nbands = 0, nslices = 0, nrows = 0, ncols = 0, slice, row, col, nr, nc; VImage src[NSLICES], res_image = NULL; VImage beta_image[MBETA], BCOV = NULL, KX_image = NULL; VImage res_map[ETMP]; float smooth_fwhm = 0, vx = 0, vy = 0, vz = 0; VFloat *float_pp, df; VRepnKind repn; float d, err; int i, k, l, n, m = 0, nt, fd = 0, npix = 0; int i0 = 0, i1 = 0; double u, sig, trace = 0, trace2 = 0, var = 0, sum = 0, nx = 0, mean = 0, sum2; float *ptr1, *ptr2; double x; gsl_matrix_float *X = NULL, *XInv = NULL, *SX = NULL; gsl_vector_float *y, *z, *beta, *ys; gsl_vector *kernel; gsl_matrix_float *S = NULL, *Vc = NULL, *F = NULL, *P = NULL, *Q = NULL; gsl_matrix_float *R = NULL, *RV = NULL; VBoolean smooth = TRUE; /* no smoothness estimation */ gsl_set_error_handler_off(); /* ** read input data */ nslices = nbands = nrows = ncols = 0; for(k = 0; k < nlists; k++) { n = linfo[k].nslices; nr = linfo[k].nrows; nc = linfo[k].ncols; nt = linfo[k].ntimesteps; nbands += nt; if(nslices == 0) nslices = n; else if(nslices != n) VError(" inconsistent image dimensions, slices: %d %d", n, nslices); if(nrows == 0) nrows = nr; else if(nrows != nr) VError(" inconsistent image dimensions, rows: %d %d", nr, nrows); if(ncols == 0) ncols = nc; else if(ncols != nc) VError(" inconsistent image dimensions, cols: %d %d", nc, ncols); } fprintf(stderr, " num images: %d, image dimensions: %d x %d x %d\n", nlists, nslices, nrows, ncols); /* ** get design dimensions */ m = VImageNRows(design); /* number of timesteps */ n = VImageNColumns(design); /* number of covariates */ fprintf(stderr, " ntimesteps=%d, num covariates=%d\n", m, n); if(n >= MBETA) VError(" too many covariates (%d), max is %d", n, MBETA); if(m != nbands) VError(" design dimension inconsistency: %d %d", m, nbands); fprintf(stderr, " working...\n"); /* ** read design matrix */ X = gsl_matrix_float_alloc(m, n); for(k = 0; k < m; k++) { for(l = 0; l < n; l++) { x = VGetPixel(design, 0, k, l); fmset(X, k, l, (float)x); } } /* ** pre-coloring, set up K-matrix, S=K, V = K*K^T with K=S */ S = gsl_matrix_float_alloc(m, m); GaussMatrix((double)sigma, S); Vc = fmat_x_matT(S, S, NULL); /* ** compute pseudoinverse */ SX = fmat_x_mat(S, X, NULL); XInv = fmat_PseudoInv(SX, NULL); /* ** get variance estimate */ Q = fmat_x_mat(XInv, Vc, Q); F = fmat_x_matT(Q, XInv, F); BCOV = VCreateImage(1, n, n, VFloatRepn); float_pp = VImageData(BCOV); ptr1 = F->data; for(i = 0; i < n * n; i++) *float_pp++ = *ptr1++; gsl_matrix_float_free(Q); gsl_matrix_float_free(F); /* ** get effective degrees of freedom */ R = gsl_matrix_float_alloc(m, m); P = fmat_x_mat(SX, XInv, P); gsl_matrix_float_set_identity(R); gsl_matrix_float_sub(R, P); RV = fmat_x_mat(R, Vc, NULL); trace = 0; for(i = 0; i < m; i++) trace += fmget(RV, i, i); P = fmat_x_mat(RV, RV, P); trace2 = 0; for(i = 0; i < m; i++) trace2 += fmget(P, i, i); df = (trace * trace) / trace2; fprintf(stderr, " df= %.3f\n", df); /* ** create output images */ xinfo = linfo[0].info; out_list = VCreateAttrList(); res_image = VCreateImage(nslices, nrows, ncols, VFloatRepn); VFillImage(res_image, VAllBands, 0); VSetAttr(VImageAttrList(res_image), "name", NULL, VStringRepn, "RES/trRV"); VSetAttr(VImageAttrList(res_image), "modality", NULL, VStringRepn, "RES/trRV"); VSetAttr(VImageAttrList(res_image), "df", NULL, VFloatRepn, df); VSetAttr(VImageAttrList(res_image), "patient", NULL, VStringRepn, xinfo->patient); VSetAttr(VImageAttrList(res_image), "voxel", NULL, VStringRepn, xinfo->voxel); VSetAttr(VImageAttrList(res_image), "repetition_time", NULL, VLongRepn, itr); VSetAttr(VImageAttrList(res_image), "talairach", NULL, VStringRepn, xinfo->talairach); /* neu */ VSetAttr(VImageAttrList(res_image),"indexOrigin",NULL,VStringRepn,xinfo->indexOrigin); VSetAttr(VImageAttrList(res_image),"columnVec",NULL,VStringRepn,xinfo->columnVec); VSetAttr(VImageAttrList(res_image),"rowVec",NULL,VStringRepn,xinfo->rowVec); VSetAttr(VImageAttrList(res_image),"sliceVec",NULL,VStringRepn,xinfo->sliceVec); VSetAttr(VImageAttrList(res_image),"FOV",NULL,VStringRepn,xinfo->FOV); /*--------*/ if(xinfo->fixpoint[0] != 'N') VSetAttr(VImageAttrList(res_image), "fixpoint", NULL, VStringRepn, xinfo->fixpoint); if(xinfo->ca[0] != 'N') { VSetAttr(VImageAttrList(res_image), "ca", NULL, VStringRepn, xinfo->ca); VSetAttr(VImageAttrList(res_image), "cp", NULL, VStringRepn, xinfo->cp); VSetAttr(VImageAttrList(res_image), "extent", NULL, VStringRepn, xinfo->extent); } VAppendAttr(out_list, "image", NULL, VImageRepn, res_image); for(i = 0; i < n; i++) { beta_image[i] = VCreateImage(nslices, nrows, ncols, VFloatRepn); VFillImage(beta_image[i], VAllBands, 0); VSetAttr(VImageAttrList(beta_image[i]), "patient", NULL, VStringRepn, xinfo->patient); VSetAttr(VImageAttrList(beta_image[i]), "voxel", NULL, VStringRepn, xinfo->voxel); VSetAttr(VImageAttrList(beta_image[i]), "repetition_time", NULL, VLongRepn, itr); VSetAttr(VImageAttrList(beta_image[i]), "talairach", NULL, VStringRepn, xinfo->talairach); /* neu */ VSetAttr(VImageAttrList(beta_image[i]),"indexOrigin",NULL,VStringRepn,xinfo->indexOrigin); VSetAttr(VImageAttrList(beta_image[i]),"columnVec",NULL,VStringRepn,xinfo->columnVec); VSetAttr(VImageAttrList(beta_image[i]),"rowVec",NULL,VStringRepn,xinfo->rowVec); VSetAttr(VImageAttrList(beta_image[i]),"sliceVec",NULL,VStringRepn,xinfo->sliceVec); VSetAttr(VImageAttrList(beta_image[i]),"FOV",NULL,VStringRepn,xinfo->FOV); /*--------*/ if(xinfo->fixpoint[0] != 'N') VSetAttr(VImageAttrList(beta_image[i]), "fixpoint", NULL, VStringRepn, xinfo->fixpoint); if(xinfo->ca[0] != 'N') { VSetAttr(VImageAttrList(beta_image[i]), "ca", NULL, VStringRepn, xinfo->ca); VSetAttr(VImageAttrList(beta_image[i]), "cp", NULL, VStringRepn, xinfo->cp); VSetAttr(VImageAttrList(beta_image[i]), "extent", NULL, VStringRepn, xinfo->extent); } VSetAttr(VImageAttrList(beta_image[i]), "name", NULL, VStringRepn, "BETA"); VSetAttr(VImageAttrList(beta_image[i]), "modality", NULL, VStringRepn, "BETA"); VSetAttr(VImageAttrList(beta_image[i]), "beta", NULL, VShortRepn, i + 1); VSetAttr(VImageAttrList(beta_image[i]), "df", NULL, VFloatRepn, df); VAppendAttr(out_list, "image", NULL, VImageRepn, beta_image[i]); } VSetAttr(VImageAttrList(design), "name", NULL, VStringRepn, "X"); VSetAttr(VImageAttrList(design), "modality", NULL, VStringRepn, "X"); VAppendAttr(out_list, "image", NULL, VImageRepn, design); KX_image = Mat2Vista(SX); VSetAttr(VImageAttrList(KX_image), "name", NULL, VStringRepn, "KX"); VSetAttr(VImageAttrList(KX_image), "modality", NULL, VStringRepn, "KX"); VAppendAttr(out_list, "image", NULL, VImageRepn, KX_image); VSetAttr(VImageAttrList(BCOV), "name", NULL, VStringRepn, "BCOV"); VSetAttr(VImageAttrList(BCOV), "modality", NULL, VStringRepn, "BCOV"); VAppendAttr(out_list, "image", NULL, VImageRepn, BCOV); /* ** create temporary images for smoothness estimation */ /* smoothness estim only for 3D images, i.e. CA/CP known */ /* if(xinfo->ca[0] == 'N') smooth = FALSE;*/ if(smooth) { i0 = 20; i1 = i0 + 30; if(i1 > m) i1 = m; for(i = i0; i < i1; i++) { if(i - i0 >= ETMP) VError(" too many tmp images"); res_map[i - i0] = VCreateImage(nslices, nrows, ncols, VFloatRepn); VFillImage(res_map[i - i0], VAllBands, 0); } } /* ** process */ ys = gsl_vector_float_alloc(m); y = gsl_vector_float_alloc(m); z = gsl_vector_float_alloc(m); beta = gsl_vector_float_alloc(n); kernel = GaussKernel((double)sigma); for(k = 0; k < nlists; k++) { src[k] = VCreateImage(linfo[k].ntimesteps, nrows, ncols, linfo[k].repn); VFillImage(src[k], VAllBands, 0); } npix = 0; for(slice = 0; slice < nslices; slice++) { if(slice % 5 == 0) fprintf(stderr, " slice: %3d\r", slice); for(k = 0; k < nlists; k++) { if(linfo[k].zero[slice] == 0) goto next1; fd = open(linfo[k].filename, O_RDONLY); if(fd == -1) VError("could not open file %s", linfo[k].filename); nt = linfo[k].ntimesteps; if(! VReadBandDataFD(fd, &linfo[k].info[slice], 0, nt, &src[k])) VError(" error reading data"); close(fd); } repn = linfo[0].repn; for(row = 0; row < nrows; row++) { for(col = 0; col < ncols; col++) { for(k = 0; k < nlists; k++) if(VPixel(src[k], 0, row, col, VShort) < minval + 1) goto next; npix++; /* read time series data */ sum = sum2 = nx = 0; ptr1 = y->data; for(k = 0; k < nlists; k++) { nt = VImageNBands(src[k]); for(i = 0; i < nt; i++) { u = VPixel(src[k], i, row, col, VShort); (*ptr1++) = u; sum += u; sum2 += u * u; nx++; } } mean = sum / nx; sig = sqrt((double)((sum2 - nx * mean * mean) / (nx - 1.0))); if(sig < 0.001) continue; /* centering and scaling, Seber, p.330 */ ptr1 = y->data; for(i = 0; i < m; i++) { u = ((*ptr1) - mean) / sig; (*ptr1++) = u + 100.0; } /* S x y */ ys = VectorConvolve(y, ys, kernel); /* compute beta's */ fmat_x_vector(XInv, ys, beta); /* residuals */ fmat_x_vector(SX, beta, z); err = 0; ptr1 = ys->data; ptr2 = z->data; for(i = 0; i < m; i++) { d = ((*ptr1++) - (*ptr2++)); err += d * d; } /* sigma^2 */ var = err / trace; /* write residuals output */ VPixel(res_image, slice, row, col, VFloat) = (VFloat)var; /* save residuals of several timesteps for smoothness estimation */ if(smooth) { ptr1 = ys->data; ptr2 = z->data; err = 0; for(i = i0; i < i1; i++) { d = ((*ptr1++) - (*ptr2++)); err += d * d; VPixel(res_map[i - i0], slice, row, col, VFloat) = d; } if (err > 0) err = sqrt(err); for(i = i0; i < i1; i++) { d = VPixel(res_map[i - i0], slice, row, col, VFloat); if (err > 1.0e-6) d /= err; else d = 0; VPixel(res_map[i - i0], slice, row, col, VFloat) = d / err; } } /* write beta output */ ptr1 = beta->data; for(i = 0; i < n; i++) VPixel(beta_image[i], slice, row, col, VFloat) = (VFloat)(*ptr1++); next: ; } } next1: ; } /* ** Smoothness estimation based on residual images */ if(smooth) { smooth_fwhm = VSmoothnessEstim(res_map, i1 - i0); sscanf(xinfo->voxel, "%f %f %f", &vx, &vy, &vz); vx = (vx + vy + vz) / 3.0; /* voxels should be isotropic */ smooth_fwhm *= vx; fprintf(stderr, " smoothness: %f\n", smooth_fwhm); VSetAttr(VImageAttrList(res_image), "smoothness", NULL, VFloatRepn, smooth_fwhm); for(i = 0; i < n; i++) { VSetAttr(VImageAttrList(beta_image[i]), "smoothness", NULL, VFloatRepn, smooth_fwhm); } for(i = 0; i < i1 - i0; i++) VDestroyImage(res_map[i]); } ende: if(npix == 0) VError(" no voxels above threshold %d found", minval); return out_list; }
VAttrList VGetContrast(VAttrList list, gsl_vector_float *con, VShort type) { VAttrList out_list; int nbands = 0, nrows = 0, ncols = 0, band, row, col; VImage src = NULL, dest = NULL, std_image = NULL; VImage beta_images[MBETA], res_image = NULL, bcov_image = NULL; VString buf = NULL; VAttrListPosn posn; VString str; int i, nbeta; float t = 0, s = 0, tsigma = 0, z = 0, zmax = 0, zmin = 0; float sigma, var, sum, df; float *ptr1, *ptr2; char *constring = NULL; gsl_vector_float *beta = NULL, *tmp = NULL; gsl_matrix_float *bcov = NULL; i = 0; for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VPixelRepn(src) != VFloatRepn) continue; VGetAttr(VImageAttrList(src), "modality", NULL, VStringRepn, &str); if(strcmp(str, "BETA") == 0) { beta_images[i++] = VCopyImage(src, NULL, VAllBands); } else if(strcmp(str, "RES/trRV") == 0) { res_image = VCopyImage(src, NULL, VAllBands); } else if(strcmp(str, "BCOV") == 0) { bcov_image = VCopyImage(src, NULL, VAllBands); } } nbeta = VImageNRows(bcov_image); nbands = VImageNBands(beta_images[0]); nrows = VImageNRows(beta_images[0]); ncols = VImageNColumns(beta_images[0]); if(VGetAttr(VImageAttrList(beta_images[0]), "df", NULL, VFloatRepn, &df) != VAttrFound) VError(" attribute 'df' not found"); if(nbeta > MBETA) { fprintf(stderr, " number of betas: %d, maximum number of betas: %d\n", nbeta, MBETA); VError(" maximum number of betas is exceeded"); } /* ** read contrast vector */ if(nbeta != con->size) VError("contrast vector has bad length (%d), correct length is %d", con->size, nbeta); fprintf(stderr, " contrast vector:\n"); char str1[10]; constring = (char *)VMalloc(sizeof(char) * 10 * nbeta); constring[0] = '\0'; for(i = 0; i < nbeta; i++) { fprintf(stderr, " %.2f", fvget(con, i)); sprintf(str1, "%1.2f ", fvget(con, i)); strcat((char *)constring, (const char *)str1); } fprintf(stderr, "\n"); /* get variance estimation */ bcov = gsl_matrix_float_alloc(nbeta, nbeta); ptr1 = VImageData(bcov_image); ptr2 = bcov->data; for(i = 0; i < nbeta * nbeta; i++) *ptr2++ = *ptr1++; gsl_matrix_float_transpose(bcov); tmp = fmat_x_vector(bcov, con, tmp); var = fskalarproduct(tmp, con); sigma = sqrt(var); /* ** create output data structs */ out_list = VCreateAttrList(); dest = VCreateImage(nbands, nrows, ncols, VFloatRepn); VFillImage(dest, VAllBands, 0); VCopyImageAttrs(beta_images[0], dest); switch(type) { case 0: /* conimg */ buf = VNewString("conimg"); break; case 1: /* t-image */ buf = VNewString("tmap"); break; case 2: /* zmap */ buf = VNewString("zmap"); break; default: VError(" illegal type"); } fprintf(stderr, " output type: %s\n", buf); VSetAttr(VImageAttrList(dest), "modality", NULL, VStringRepn, buf); VSetAttr(VImageAttrList(dest), "name", NULL, VStringRepn, buf); VSetAttr(VImageAttrList(dest), "contrast", NULL, VStringRepn, constring); VAppendAttr(out_list, "image", NULL, VImageRepn, dest); if(type == 0) { std_image = VCreateImage(nbands, nrows, ncols, VFloatRepn); VFillImage(std_image, VAllBands, 0); VCopyImageAttrs(beta_images[0], std_image); VSetAttr(VImageAttrList(std_image), "modality", NULL, VStringRepn, "std_dev"); VSetAttr(VImageAttrList(std_image), "name", NULL, VStringRepn, "std_dev"); VAppendAttr(out_list, "image", NULL, VImageRepn, std_image); } /* ** loop thru image */ zmax = zmin = 0; beta = gsl_vector_float_alloc(nbeta); for(band = 0; band < nbands; band++) { for(row = 0; row < nrows; row++) { for(col = 0; col < ncols; col++) { t = z = sum = 0; ptr1 = beta->data; for(i = 0; i < nbeta; i++) { *ptr1++ = VPixel(beta_images[i], band, row, col, VFloat); } sum = fskalarproduct(beta, con); if(ABS(sum) < 1.0e-10) continue; s = VPixel(res_image, band, row, col, VFloat); tsigma = sqrt(s) * sigma; if(tsigma > 0.00001) t = sum / tsigma; else t = 0; if(isnan(t) || isinf(t)) t = 0; switch(type) { case 0: /* conimg */ z = sum; break; case 1: /* t-image */ z = t; break; case 2: /* zmap */ z = t2z_approx(t, df); if(z > 30) z = 30; if(sum < 0) z = -z; break; default: ; } if(isnan(z) || isinf(z)) z = 0; if(z > zmax) zmax = z; if(z < zmin) zmin = z; VPixel(dest, band, row, col, VFloat) = z; if(type == 0) VPixel(std_image, band, row, col, VFloat) = tsigma; } } } fprintf(stderr, " min= %.3f, max= %.3f\n", zmin, zmax); return out_list; }