aimsalgo 6.0.0
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>
39#include <cartodata/volume/volume.h>
40
41namespace 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 }
108 bool _valid ;
110 double _PIj ;
111
113 double _meanMean ;
114 double _meanNorm ;
117
122 double _Sigma2 ;
123
124 double _detCi ;
125 double _normFactor ;
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 ) ;
149
150 bool classification( const carto::rc_ptr<carto::Volume<T> > & dynamicImage,
152 carto::rc_ptr<carto::Volume<short> >& segmented );
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
189double
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
227double
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
267double
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.)
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
carto::VolumeRef< double > _xT
Definition ppca.h:116
const carto::VolumeRef< double > & eigenValues()
Definition ppca.h:91
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
const carto::VolumeRef< double > & mean() const
Definition ppca.h:81
double posteriorProbability(const carto::rc_ptr< carto::Volume< double > > &individual, double pX)
Definition ppca.h:228
const carto::VolumeRef< double > & selectedEigenVectors()
Definition ppca.h:92
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()
float norm2(const AimsVector< T, D > &v1)