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; }
//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; }
float * VCorrMatrix(VAttrList list,VImage map,VShort first,VShort length) { VAttrListPosn posn; VImage src[NSLICES]; size_t b,r,c,i,j,i1,n,m,nt,last,ntimesteps,nrows,ncols,nslices; gsl_matrix_float *mat=NULL; float *A=NULL; /* ** get image dimensions */ i = ntimesteps = nrows = ncols = 0; for (VFirstAttr (list, & posn); VAttrExists (& posn); VNextAttr (& posn)) { if (VGetAttrRepn (& posn) != VImageRepn) continue; VGetAttrValue (& posn, NULL,VImageRepn, & src[i]); if (VPixelRepn(src[i]) != VShortRepn) continue; if (VImageNBands(src[i]) > ntimesteps) ntimesteps = VImageNBands(src[i]); if (VImageNRows(src[i]) > nrows) nrows = VImageNRows(src[i]); if (VImageNColumns(src[i]) > ncols) ncols = VImageNColumns(src[i]); i++; if (i >= NSLICES) VError(" too many slices"); } nslices = i; /* get time steps to include */ if (length < 1) length = ntimesteps-2; last = first + length -1; if (last >= ntimesteps) last = ntimesteps-1; if (first < 0) first = 1; nt = last - first + 1; i1 = first+1; if (nt < 2) VError(" not enough timesteps, nt= %d",nt); /* number of voxels */ n = VImageNColumns(map); fprintf(stderr," ntimesteps: %d, first= %d, last= %d, nt= %d, nvoxels: %ld\n", (int)ntimesteps,(int)first,(int)last,(int)nt,(long)n); /* ** avoid casting to float, copy data to matrix */ mat = gsl_matrix_float_calloc(n,nt); if (!mat) VError(" err allocating mat"); for (i=0; i<n; i++) { b = VPixel(map,0,0,i,VShort); r = VPixel(map,0,1,i,VShort); c = VPixel(map,0,2,i,VShort); float *ptr = gsl_matrix_float_ptr(mat,i,0); int k; j = 0; for (k=first; k<=last; k++) { if (j >= mat->size2) VError(" j= %d %d",j,mat->size2); if (k >= VImageNBands(src[b])) VError(" k= %d %d",k, VImageNBands(src[b])); *ptr++ = (float) VPixel(src[b],k,r,c,VShort); j++; } } /* ** compute similarity matrix */ m = (n*(n+1))/2; fprintf(stderr," compute correlation matrix...\n"); A = (float *) VCalloc(m,sizeof(float)); if (!A) VError(" err allocating correlation matrix"); memset(A,0,m*sizeof(float)); size_t progress=0; #pragma omp parallel for shared(progress) private(j) schedule(guided) firstprivate(mat,A) for (i=0; i<n; i++) { if (i%100 == 0) fprintf(stderr," %d00\r",(int)(++progress)); const float *arr1 = gsl_matrix_float_const_ptr(mat,i,0); for (j=0; j<i; j++) { const float *arr2 = gsl_matrix_float_const_ptr(mat,j,0); const double v = Correlation(arr1,arr2,nt); const size_t k=j+i*(i+1)/2; if (k >= m) VError(" illegal addr k= %d, m= %d",k,m); A[k] = v; } } fprintf(stderr," matrix done.\n"); gsl_matrix_float_free(mat); return A; }
VAttrList VNCM(VAttrList list,VImage mask,VShort minval,VShort first,VShort length,VFloat threshold) { VAttrList out_list=NULL; VAttrListPosn posn; VImage src[NSLICES],map=NULL; VImage dest=NULL; size_t b,r,c,i,j,i1,n,m,nt,last,ntimesteps,nrows,ncols,nslices; gsl_matrix_float *mat=NULL; float *A=NULL,*ev=NULL; /* ** get image dimensions */ i = ntimesteps = nrows = ncols = 0; for (VFirstAttr (list, & posn); VAttrExists (& posn); VNextAttr (& posn)) { if (VGetAttrRepn (& posn) != VImageRepn) continue; VGetAttrValue (& posn, NULL,VImageRepn, & src[i]); if (VPixelRepn(src[i]) != VShortRepn) continue; if (VImageNBands(src[i]) > ntimesteps) ntimesteps = VImageNBands(src[i]); if (VImageNRows(src[i]) > nrows) nrows = VImageNRows(src[i]); if (VImageNColumns(src[i]) > ncols) ncols = VImageNColumns(src[i]); i++; if (i >= NSLICES) VError(" too many slices"); } nslices = i; /* get time steps to include */ if (length < 1) length = ntimesteps-2; last = first + length -1; if (last >= ntimesteps) last = ntimesteps-1; if (first < 0) first = 1; nt = last - first + 1; i1 = first+1; if (nt < 2) VError(" not enough timesteps, nt= %d",nt); fprintf(stderr,"# ntimesteps: %d, first= %d, last= %d, nt= %d\n", (int)ntimesteps,(int)first,(int)last,(int)nt); /* count number of voxels */ n = 0; for (b=0; b<nslices; b++) { if (VImageNRows(src[b]) < 2) continue; for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { if (VPixel(src[b],i1,r,c,VShort) < minval) continue; if (VGetPixel(mask,b,r,c) < 0.5) continue; n++; } } } fprintf(stderr," nvoxels: %ld\n",(long)n); /* ** voxel addresses */ map = VCreateImage(1,5,n,VFloatRepn); if (map == NULL) VError(" error allocating addr map"); VFillImage(map,VAllBands,0); VPixel(map,0,3,0,VFloat) = nslices; VPixel(map,0,3,1,VFloat) = nrows; VPixel(map,0,3,2,VFloat) = ncols; i = 0; for (b=0; b<nslices; b++) { if (VImageNRows(src[b]) < 2) continue; for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { if (VPixel(src[b],i1,r,c,VShort) < minval) continue; if (VGetPixel(mask,b,r,c) < 0.5) continue; VPixel(map,0,0,i,VFloat) = b; VPixel(map,0,1,i,VFloat) = r; VPixel(map,0,2,i,VFloat) = c; i++; } } } /* ** avoid casting to float, copy data to matrix */ mat = gsl_matrix_float_calloc(n,nt); for (i=0; i<n; i++) { b = VPixel(map,0,0,i,VFloat); r = VPixel(map,0,1,i,VFloat); c = VPixel(map,0,2,i,VFloat); float *ptr = gsl_matrix_float_ptr(mat,i,0); int k; j = 0; for (k=first; k<=last; k++) { if (j >= mat->size2) VError(" j= %d %d",j,mat->size2); if (k >= VImageNBands(src[b])) VError(" k= %d %d",k, VImageNBands(src[b])); *ptr++ = (float) VPixel(src[b],k,r,c,VShort); j++; } } /* ** compute similarity matrix */ m = (n*(n+1))/2; fprintf(stderr," matrix computation, n= %ld...\n",(long)n); A = (float *) calloc(m,sizeof(float)); if (!A) VError(" err allocating correlation matrix"); memset(A,0,m*sizeof(float)); size_t progress=0; #pragma omp parallel for shared(progress) private(j) schedule(guided) firstprivate(mat,A) for (i=0; i<n; i++) { if (i%100 == 0) fprintf(stderr," %d00\r",(int)(++progress)); const float *arr1 = gsl_matrix_float_const_ptr(mat,i,0); for (j=0; j<i; j++) { const float *arr2 = gsl_matrix_float_const_ptr(mat,j,0); const double v = Correlation(arr1,arr2,nt); const size_t k=j+i*(i+1)/2; if (k >= m) VError(" illegal addr k= %d, m= %d",k,m); A[k] = (float)v; } } fprintf(stderr," matrix done.\n"); gsl_matrix_float_free(mat); /* ** eigenvector centrality */ ev = (float *) VCalloc(n,sizeof(float)); DegreeCentrality(A,ev,n,threshold); dest = WriteOutput(src[0],map,nslices,nrows,ncols,ev,n); VSetAttr(VImageAttrList(dest),"name",NULL,VStringRepn,"DegreeCM"); out_list = VCreateAttrList(); VAppendAttr(out_list,"image",NULL,VImageRepn,dest); return out_list; }
/* ** 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; }