Пример #1
0
MRI_IMAGE * DES_get_psinv( int ntim , int nref , float **ref )
{
   MRI_IMAGE *refim , *psinv ; float *refar , *jar ; int ii , jj ;

   refim = mri_new(ntim,nref,MRI_float) ;
   refar = MRI_FLOAT_PTR(refim) ;
   for( jj=0 ; jj < nref ; jj++ ){
     jar = refar + jj*ntim ;
     for( ii=0 ; ii < ntim ; ii++ ) jar[ii] = ref[jj][ii] ;
   }
   mri_matrix_psinv_svd(1) ;
   psinv = mri_matrix_psinv(refim,NULL,0.0f) ;
   mri_free(refim) ;
   return psinv ;
}
Пример #2
0
MRI_IMAGE * LSS_setup( MRI_IMAGE *ima , MRI_IMAGE *imc )
{
   int nn, mm, nc, ii, jj, ic , nwarn=0 ;
   float *cc, *pp, *qq, *qj, *vv, *ss, *pv , cj, cvdot, pc ;
   MRI_IMAGE *ims , *imp , *imq ;
   MRI_IMARR *imar ;

ENTRY("LSS_setup") ;

   if( ima == NULL || imc == NULL ){  /* bad user */
     ERROR_message("LSS_setup: NULL input image?!") ;
     RETURN(NULL) ;
   }

   /* [A] is nn X mm ; [C] is nn x nc */

   nn = ima->nx ; mm = ima->ny ; nc = imc->ny ; cc = MRI_FLOAT_PTR(imc) ;

   if( imc->nx != nn || nn <= mm+2 ){  /* stoopid user */
     ERROR_message("LSS_setup: ima->nx=%d does not equal imc->nx=%d :-(" ,
                   ima->nx,imc->nx) ;
     RETURN(NULL) ;
   }

   /* get imp = [P] = psinv of [A] = mm X nn matrix
          imq = [Q] = ortproj onto column null space of [A] = nn X nn matrix */

   mri_matrix_psinv_svd(1) ;
   imar = mri_matrix_psinv_ortproj( ima , 1 ) ;

   if( imar == NULL ){  /* should not happen */
     ERROR_message("LSS_setup: cannot compute pseudo-inverse :-(") ;
     RETURN(NULL) ;
   }

   imp = IMARR_SUBIM(imar,0) ; pp = MRI_FLOAT_PTR(imp) ;
   imq = IMARR_SUBIM(imar,1) ; qq = MRI_FLOAT_PTR(imq) ;

   /* create output image = [S] = nn X nc
      Each column of [S] is the vector that we
      dot into a data vector [z] to get the estimate of
      gamma+delta for the corresponding column from [C] */

   ims = mri_new(nn,nc,MRI_float) ; ss = MRI_FLOAT_PTR(ims) ;

   /* workspace vectors */

   vv = (float *)malloc(sizeof(float)*nn) ;  /* will be [Q] [c] */

   pv = (float *)malloc(sizeof(float)*nn) ;  /* last row of [P] */
   for( ii=0 ; ii < nn ; ii++ ) pv[ii] = pp[ mm-1 + ii*mm ] ;

   /* loop over columns of [C] (and [S]) */

   for( ic=0 ; ic < nc ; ic++,cc+=nn,ss+=nn ){

     /* compute [v] = [Q] [c] */

     for( ii=0 ; ii < nn ; ii++ ) vv[ii] = 0.0f ;     /* initialize [v] to 0 */
     for( jj=0 ; jj < nn ; jj++ ){                 /* loop over columns of Q */
       qj = qq + jj*nn ;                         /* ptr to jj-th column of Q */
       cj = cc[jj] ;                                   /* jj-th value of [c] */
       for( ii=0 ; ii < nn ; ii++ ) vv[ii] += qj[ii] * cj ;  /* sum into [v] */
     }

     /* compute cvdot = [c] *dot* [v]
                cj    = [c] *dot* [c]
                pc    = [c] *dot* {last row of [P] = pv} */

     for( pc=cj=cvdot=ii=0 ; ii < nn ; ii++ ){
       cvdot += cc[ii]*vv[ii] ; cj += cc[ii]*cc[ii] ; pc += pv[ii]*cc[ii] ;
     }

     /* initialize [s] = last row of [P] */

     for( ii=0 ; ii < nn ; ii++ ) ss[ii] = pv[ii] ;

     /* If cvdot is zero(ish), this means that the extra column [c]
        is collinear(ish) with the columns of [A], and we skip the next step.
        Note that since [Q] is an orthogonal matrix,
        we are guaranteed that L2norm([Q][c]) == L2norm([c]),
        which implies that abs(cvdot) <= abs(cj), by the triangle inequality. */

     if( fabsf(cvdot) >= 1.e-5*cj ){

       /* add the proper fraction of [v] into [s] */

       pc = (1.0f - pc) / cvdot ;
       for( ii=0 ; ii < nn ; ii++ ) ss[ii] += pc * vv[ii] ;
     } else {
       nwarn++ ;
     }

   } /* end of loop over columns of [C] */

   if( verb && nwarn > 0 )
     INFO_message("%d (out of %d) LSS individual estimators were collinear",
                  nwarn , nc ) ;

   /* toss the trash and return the output set of columns */

   free(pv) ; free(vv) ; DESTROY_IMARR(imar) ; RETURN(ims) ;
}