aimsalgo  5.1.2
Neuroimaging image processing
ppca.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 
35 #ifndef AIMS_MATH_PPCA_H
36 #define AIMS_MATH_PPCA_H
37 
38 #include <aims/def/general.h>
40 
41 namespace aims
42 {
43 
45  {
46  public:
47  ProbabilisticPcaElement( int nbOfSignificativeEV, double PIj = 1. ) ;
49 
50  template <class T>
51  void doIt( const carto::rc_ptr<carto::Volume<T> > & individuals,
52  double distanceRef = 0. );
53 
54  template <class T>
55  void doIt( const std::list< Point3d>& selectedPoints,
56  const carto::rc_ptr<carto::Volume<T> > & data,
57  double distanceRef = 0. );
58 
59  // set a priori class probability
60  void setPIj( double PIj )
61  {
62  _PIj = PIj ;
63  if( _computed )
64  _lnAddFactor = log( _detCi / ( _PIj * _PIj ) ) ;
65  }
66 
67  inline double distance(
68  const carto::rc_ptr<carto::Volume<double> > & individual );
69 
70  inline double posteriorProbability(
71  const carto::rc_ptr<carto::Volume<double> > & individual, double pX );
72 
73 // double normalizedPosteriorProbability( const carto::rc_ptr<carto::Volume<double> > & individual,
74 // double pX, double normX ) ;
75 
76  /* for comparison purposes only, because x prior probability is not taken
77  into account */
78  inline double lnPosteriorProbability(
79  const carto::rc_ptr<carto::Volume<double> > & individual );
80 
81  const carto::VolumeRef<double>& mean() const { return _mean ; }
82  double noiseVariance() const
83  { return _Sigma2 ; }
84 
85  template <class T>
86  double noiseVariance( const carto::rc_ptr<carto::Volume<T> > & individuals,
87  double& normMean ) const ;
88 
89  double meanNorm() { return _meanNorm ; }
90 
93 
94  double normFactor() const { return _normFactor ; }
95 
96  protected:
97  static double * _exp ;
98  inline double exponential( double x )
99  {
100  if( x < -750 )
101  return 0. ;
102  int approx = int( x * 10.) ;
103  double res = (x * 10. - approx) ;
104  return ( 1. - res ) * _exp[approx] + res * _exp[approx+1] ;
105  }
106  double _distanceRef ;
107  bool _computed ;
108  bool _valid ;
110  double _PIj ;
111 
113  double _meanMean ;
114  double _meanNorm ;
117 
122  double _Sigma2 ;
123 
124  double _detCi ;
125  double _normFactor ;
126  double _lnAddFactor ;
127  };
128 
129 
130  template <class T>
132  {
133  public:
135  const std::vector< std::list <Point3d> >& classes,
136  int nbOfSignificantEigenValues,
137  const std::vector<double>& PIj
138  = std::vector<double>() ) ;
140 
141  std::vector<double>
143  double px,
144  std::vector<double>& maxProbaByClass ) ;
145  std::vector<double>
146  andersonScores( const carto::rc_ptr<carto::Volume<double> > & x, double px,
147  std::vector<double>& maxProbaByClass ) ;
148  int affectedTo( const carto::rc_ptr<carto::Volume<double> > & x ) ;
149 
150  bool classification( const carto::rc_ptr<carto::Volume<T> > & dynamicImage,
152  carto::rc_ptr<carto::Volume<short> >& segmented );
153  bool fuzzyClassification(
154  const carto::rc_ptr<carto::Volume<T> > & dynamicImage,
156  carto::rc_ptr<carto::Volume<float> > & fuzzySegmented,
157  double thresholdOnMaxPercentage = 0.,
158  double andersonScoreThreshold = 0.2,
159  const carto::rc_ptr<carto::Volume<double> > & indivPriorProbabilities
161 
162 
164  const carto::rc_ptr<carto::Volume<double> > & x, float pX,
165  unsigned int classNb )
166  {
167  if( classNb >= _discrElements.size() )
168  throw std::runtime_error("Class number exceeds number of classes") ;
169  else
170  return _discrElements[classNb].posteriorProbability(x, pX) ;
171  }
172 
173  double pX(const carto::rc_ptr<carto::Volume<double> >& x ) ;
174 
175  short nbOfClasses() const { return _discrElements.size() ; }
176 
177  private:
178  double weight( double norm2, int classe, float tolerance ) ;
179  double wienerFilter( double sigma2, double norm2, double factor ) ;
180  const std::vector< std::list< Point3d > >& _classes ;
181  const carto::VolumeRef<T> _data;
182  double _distanceRef ;
183  std::vector<double> _PIj ;
184  int _nbOfSignificantEigenValues ;
185  std::vector<ProbabilisticPcaElement> _discrElements ;
186  } ;
187 }
188 
189 double
192 {
193  if( ! _computed )
194  {
195  std::cerr << "ProbabilisticPcaElement::distance : " << std::endl ;
196  throw std::runtime_error( "You must doIt first, parameter not yet "
197  "computed !" ) ;
198  }
199 
200  if( !_valid ){
201  std::cerr << "Invalid ppca ! "<< std::endl ;
202  return 10000000. ;
203  }
204 
205 // for( int t = 0 ; t < indiv->getSizeX() ; ++t ){
206 // _xT(1, t) = indiv(t) - _mean(t) ;
207 // _x(t) = indiv(t) - _mean(t) ;
208 // }
209 
210  double distance = 0. ;
211  for(int i = 0 ; i < x->getSizeX() ; ++i )
212  {
213  double sum = 0. ;
214  for( int j = 0 ; j < x->getSizeX() ; ++j )
215  sum += _invCi(i, j) * ( x->at(j) - _mean(j) ) ;
216  distance += ( x->at(i) - _mean(i) ) * sum ;
217  }
218 // double distance = _xT.cross( _invCi.cross( _x ) )(0, 0) ;
219 
220  if( distance < 0. )
221  std::cout << "Distance = " << distance << std::endl ;
222 
223  return distance - _distanceRef ;
224 }
225 
226 
227 double
229  const carto::rc_ptr<carto::Volume<double> > & x, double pX )
230 {
231  if( ! _computed )
232  {
233  std::cerr << "ProbabilisticPcaElement::posteriorProbability : "
234  << std::endl ;
235  throw std::runtime_error( "You must doIt first, parameter not yet "
236  "computed !") ;
237  }
238 
239  if( !_valid )
240  return 0. ;
241 
242 
243  double distance = 0. ;
244  for(int i = 0 ; i < x->getSizeX() ; ++i ){
245  double sum = 0. ;
246  for( int j = 0 ; j < x->getSizeX() ; ++j )
247  sum += _invCi(i, j) * ( x->at(j) - _mean(j) ) ;
248  distance += ( x->at(i) - _mean(i) ) * sum ;
249  }
250 
251  if( distance < 0. )
252  std::cout << "Distance = " << distance << std::endl ;
253 
254 // double distance = _xT.cross( _invCi.cross( _x ) )(0, 0) ;
255 // double distance = xCentered.clone( ).transpose().cross
256 // ( _invCi.cross( xCentered ) )(0, 0) ;
257  int index = int( 0.5 * (distance - _distanceRef) * 100.
258  + 0.5 ) ;
259  if( index > 100000 )
260  return 0. ;
261  else if( index < 0. )
262  return _normFactor / _exp[ -index ] * _PIj / pX ;
263 
264  return _normFactor * _exp[ index ] * _PIj / pX ;
265 }
266 
267 double
270 {
271  if( ! _computed )
272  {
273  std::cerr << "ProbabilisticPcaElement::lnPosteriorProbability : "
274  << std::endl ;
275  throw std::runtime_error( "You must doIt first, parameter not yet "
276  "computed !") ;
277  }
278 
279  if( !_valid )
281 
282 
283  double distance = 0. ;
284  for(int i = 0 ; i < x->getSizeX() ; ++i )
285  {
286  double sum = 0. ;
287  for( int j = 0 ; j < x->getSizeX() ; ++j )
288  sum += _invCi(i, j) * ( x->at(j) - _mean(j) ) ;
289  distance += ( x->at(i) - _mean(i) ) * sum ;
290  }
291 // double distance = _xT.cross( _invCi.cross( _x ) )(0, 0) ;
292 
293  if( distance < 0. )
294  std::cout << "Distance = " << distance << std::endl ;
295 
296 // double distance = xCentered.clone( ).transpose().cross
297 // ( _invCi.cross( xCentered ) )(0, 0) ;
298  //std::cout << "distance = " << distance << "\tNormFactor = "
299  // << _lnAddFactor << std::endl ;
300  return ( _distanceRef - distance /*/ (x->getSizeX() - _nbOfSignificantEV )*/ + _lnAddFactor ) ;
301 }
302 
303 #endif
304 
305 
double normFactor() const
Definition: ppca.h:94
ProbabilisticPcaElement(int nbOfSignificativeEV, double PIj=1.)
const carto::VolumeRef< double > & mean() const
Definition: ppca.h:81
const carto::VolumeRef< double > & selectedEigenVectors()
Definition: ppca.h:92
void setPIj(double PIj)
Definition: ppca.h:60
carto::VolumeRef< double > _x
Definition: ppca.h:115
double noiseVariance() const
Definition: ppca.h:82
carto::VolumeRef< double > _Wi
Definition: ppca.h:118
const carto::VolumeRef< double > & eigenValues()
Definition: ppca.h:91
carto::VolumeRef< double > _xT
Definition: ppca.h:116
carto::VolumeRef< double > _invCi
Definition: ppca.h:119
carto::VolumeRef< double > _EValues
Definition: ppca.h:120
double distance(const carto::rc_ptr< carto::Volume< double > > &individual)
Definition: ppca.h:190
double exponential(double x)
Definition: ppca.h:98
double lnPosteriorProbability(const carto::rc_ptr< carto::Volume< double > > &individual)
Definition: ppca.h:268
virtual ~ProbabilisticPcaElement()
Definition: ppca.h:48
double posteriorProbability(const carto::rc_ptr< carto::Volume< double > > &individual, double pX)
Definition: ppca.h:228
carto::VolumeRef< double > _mean
Definition: ppca.h:112
static double * _exp
Definition: ppca.h:97
carto::VolumeRef< double > _EVect
Definition: ppca.h:121
void doIt(const carto::rc_ptr< carto::Volume< T > > &individuals, double distanceRef=0.)
Definition: ppca_d.h:87
ProbabilisticPca(const carto::rc_ptr< carto::Volume< T > > &data, const std::vector< std::list< Point3d > > &classes, int nbOfSignificantEigenValues, const std::vector< double > &PIj=std::vector< double >())
Definition: ppca_d.h:428
std::vector< double > andersonScores(const carto::rc_ptr< carto::Volume< double > > &x, double px, std::vector< double > &maxProbaByClass)
Definition: ppca_d.h:521
double pX(const carto::rc_ptr< carto::Volume< double > > &x)
Definition: ppca_d.h:754
bool classification(const carto::rc_ptr< carto::Volume< T > > &dynamicImage, const carto::rc_ptr< carto::Volume< byte > > &mask, carto::rc_ptr< carto::Volume< short > > &segmented)
Definition: ppca_d.h:603
short nbOfClasses() const
Definition: ppca.h:175
float posteriorProbability(const carto::rc_ptr< carto::Volume< double > > &x, float pX, unsigned int classNb)
Definition: ppca.h:163
std::vector< double > posteriorProbabilities(const carto::rc_ptr< carto::Volume< double > > &x, double px, std::vector< double > &maxProbaByClass)
Definition: ppca_d.h:553
bool fuzzyClassification(const carto::rc_ptr< carto::Volume< T > > &dynamicImage, const carto::rc_ptr< carto::Volume< byte > > &mask, carto::rc_ptr< carto::Volume< float > > &fuzzySegmented, double thresholdOnMaxPercentage=0., double andersonScoreThreshold=0.2, const carto::rc_ptr< carto::Volume< double > > &indivPriorProbabilities=carto::VolumeRef< double >())
Definition: ppca_d.h:644
int affectedTo(const carto::rc_ptr< carto::Volume< double > > &x)
Definition: ppca_d.h:580
BucketMap< Void > * mask(const BucketMap< Void > &src, const BucketMap< Void > &m, bool intersect=true)
DataTypeTraits< T >::LongType sum(const Volume< T > &vol)
static _Tp max()