36 #ifndef AIMS_MATH_PPCA_D_H
37 #define AIMS_MATH_PPCA_D_H
56 if( selectedPoints.size() <= (
unsigned) data->getSizeT() )
64 std::max(
int(selectedPoints.size()), 1), data->getSizeT(), 1, 1,
65 carto::AllocatorContext::fast() );
67 std::list< Point3d >::const_iterator iter( selectedPoints.begin() ),
68 last( selectedPoints.end() ) ;
73 for(
int t = 0 ; t < data->getSizeT() ; ++t )
74 individuals( i, t ) = T( data->at( (*iter)[0], (*iter)[1], (*iter)[2],
82 doIt( individuals, distanceRef ) ;
93 matriceIndiv->getSizeY(), 1, 1, 1, carto::AllocatorContext::fast() ) ;
95 carto::AllocatorContext::fast() );
97 std::cout <<
"toto" << std::endl << std::endl ;
99 if( matriceIndiv->getSizeX() <= matriceIndiv->getSizeY() )
111 int nbFrame = matriceIndiv->getSizeY() ;
113 if( matriceIndiv->getSizeY() < nbFrame )
114 std::cerr <<
"Beware : not enough data to evaluate svd" << std::endl ;
117 matriceIndiv->getSizeX(), matriceIndiv->getSizeY(), 1, 1,
118 carto::AllocatorContext::fast() );
120 carto::AllocatorContext::fast() );
123 for(
int ind = 0 ; ind < matriceIndiv->getSizeX() ; ++ind )
124 for(
int t = 0 ; t < matriceIndiv->getSizeY() ; ++t )
126 val = matriceIndiv->
at( ind, t ) ;
131 double meanMean = 0. ;
134 for(
int t = 0 ; t < nbFrame ; ++t )
137 for(
int ind = 0 ; ind < centeredIndivMatrix->
getSizeX() ; ++ind )
139 centeredIndivMatrix( ind, t ) = matriceIndiv->
at(ind, t) -
_mean(t) ;
140 meanMean += centeredIndivMatrix( ind, t ) ;
143 std::cout <<
"Mean centered mean = " << meanMean <<
" (should be 0) " << std::endl ;
156 carto::AllocatorContext::fast() ) ;
159 for( y=0; y<dy; ++y )
160 for( x=0; x<dx; ++x )
162 for(
int k=0; k < centeredIndivMatrix->
getSizeX() ;++k)
163 matVarCov(x, y) += centeredIndivMatrix(k, x)
164 * centeredIndivMatrix(k, y);
165 matVarCov(x, y) /= centeredIndivMatrix->
getSizeX() - 1 ;
189 carto::AllocatorContext::fast() ) ;
190 for(
int i = 0 ; i < nbFrame ; ++i )
192 _EVect(i, j) = matVarCov(i, j) ;
201 std::cout <<
"\tLamda " << c+1 <<
"EValue = " <<
_EValues(c, c) ;
202 std::cout <<
"\tSigma2 = " <<
_Sigma2 << std::endl ;
210 carto::AllocatorContext::fast() );
216 <<
"\t_Wi.dimT = " <<
_Wi->
getSizeT() << std::endl ;
229 for( y=0; y<dy; ++y )
230 for( x=0; x<dx; ++x )
233 double val = 0.5 * ( Ci(x, y) + Ci(y, x) ) ;
234 Ci(x, y) = Ci(y, x) = val ;
237 for(
int i = 0; i < nbFrame ; ++i )
244 double s = 0.00000001 ;
247 carto::AllocatorContext::fast() );
253 double ts = s * w.
max();
257 for ( i=0; i<n; i++ )
260 if ( w( i, i ) > ts ) w( i, i ) = 1.0f / w( i, i );
267 std::cout <<
"Unkept values = " << unkept << std::endl ;
291 std::cout <<
"-0.5 * log( _detCi ) = " << -0.5 * log(
_detCi ) <<
"\t log(_PIj) = " << log(
_PIj) << std::endl ;
331 for( y=0; y<dy; ++y )
332 for( x=0; x<dx; ++x )
350 double & meanNorm )
const
354 int nbFrame = matriceIndiv->getSizeY() ;
356 if( matriceIndiv->getSizeY() < nbFrame )
357 std::cerr <<
"Beware : not enough data to evaluate svd" << std::endl ;
367 matriceIndiv->getSizeX(), matriceIndiv->getSizeY(), 1, 1,
368 carto::AllocatorContext::fast() ) ;
370 carto::AllocatorContext::fast() ) ;
372 for(
int ind = 0 ; ind < matriceIndiv->getSizeX() ; ++ind )
373 for(
int t = 0 ; t < matriceIndiv->getSizeY() ; ++t )
374 mean(t) += matriceIndiv->
at( ind, t ) ;
378 for(
int t = 0 ; t < nbFrame ; ++t )
382 for(
int ind = 0 ; ind < centeredIndivMatrix->
getSizeX() ; ++ind )
384 centeredIndivMatrix( ind, t ) = matriceIndiv->
at(ind, t) -
mean(t);
392 carto::AllocatorContext::fast() );
394 for( y=0; y<nbFrame; ++y )
395 for( x=0; x<nbFrame; ++x )
397 for(
int k=0; k < centeredIndivMatrix->
getSizeX() ;++k)
398 matVarCov(x, y) += centeredIndivMatrix(k, x)
399 * centeredIndivMatrix(k, y);
400 matVarCov(x, y) /= centeredIndivMatrix->
getSizeX() - 1 ;
414 svd.
sort(matVarCov, EValues) ;
419 Sigma2 += EValues(i, i) ;
431 std::list< Point3d > >& classes,
432 int nbOfSignificantEigenValues,
433 const std::vector<double>& PIj )
435 _classes(classes), _data(data), _PIj(PIj),
436 _nbOfSignificantEigenValues(nbOfSignificantEigenValues)
440 if( PIj.size() != 0 )
441 if( PIj.size() == classes.size() )
444 throw std::runtime_error(
"Inconsistant data : number of classes and "
445 "number of classes prior probabilities are "
449 _PIj.reserve( _classes.size() ) ;
450 for(
unsigned int c = 0 ; c < _classes.size() ; ++c )
451 _PIj.push_back( 1./_classes.size() ) ;
454 _discrElements.reserve( _classes.size() ) ;
459 _data->
getSizeT(), _classes.size(), 1, 1,
460 carto::AllocatorContext::fast() ) ;
464 for(
unsigned int c = 0 ; c < _classes.size() ; ++c )
466 if(
int(_classes[c].size()) > _data->
getSizeT() )
470 el.
doIt( _classes[c], _data ) ;
472 std::cout <<
"Noise Ref = " << _distanceRef << std::endl ;
474 el.
doIt( _classes[c], _data, _distanceRef ) ;
477 for(
int t = 0 ; t < _data->
getSizeT() ; ++t )
481 std::cout <<
"Class " << c <<
" done !" << std::endl ;
482 _discrElements.push_back( el ) ;
484 std::cerr <<
"Not enough data for element " << c << std::endl ;
490 eigenValuesWri.
write(eigenValues) ;
491 std::cout <<
"Probabilistic Pca initization completed" << std::endl ;
500 {
if( tolerance * norm2 > _discrElements[c].meanNorm() )
503 return 2 * pow( 0.5, _discrElements[c].meanNorm()
504 / (tolerance * tolerance * norm2 ) ) ;
509 ProbabilisticPca<T>::wienerFilter(
double sigma2,
double norm2,
512 double res = 1 - factor * factor * sigma2 /
norm2 ;
523 std::vector<double>& maxProbaByClass )
528 std::vector<double> res( _discrElements.size() ) ;
530 double scoreSum = 0. ;
531 for(
unsigned int c = 0 ; c < _discrElements.size() ; ++c )
535 res[c] = _discrElements[c].posteriorProbability( x, 1 ) * _PIj[c] ;
536 if( res[c] > maxProbaByClass[c] )
537 maxProbaByClass[c] = res[c] ;
541 for(
unsigned int c = 0 ; c < _discrElements.size() ; ++c )
559 std::vector<double> res( _discrElements.size() ) ;
565 for(
unsigned int c = 0 ; c < _discrElements.size() ; ++c )
567 res[c] = _discrElements[c].posteriorProbability( x, 1 ) ;
568 if( res[c] > maxProbaByClass[c] )
569 maxProbaByClass[c] = res[c] ;
584 double lnPMin = _discrElements[0].lnPosteriorProbability( x ) ;
586 for(
unsigned int c = 0 ; c < _discrElements.size() ; ++c )
588 lnP = _discrElements[c].lnPosteriorProbability( x ) ;
609 if( dynamicImage->getSizeT() != _data->getSizeT() )
611 if( segmented->getSizeX() != _data->getSizeX() || segmented->getSizeY() != _data->getSizeY()
612 || segmented->getSizeZ() != _data->getSizeZ() )
615 _data->getSizeZ() ) ;
616 segmented->setVoxelSize( _data->getVoxelSize() ) ;
620 carto::AllocatorContext::fast() ) ;
621 std::vector<int> dim = dynamicImage->getSize();
622 for( z=0; z<dim[2]; ++z )
623 for( y=0; y<dim[1]; ++y )
624 for( x=0; x<dim[0]; ++x )
626 if(
mask->at(x, y, z) )
630 for(
int t = 0 ; t < _data->getSizeT() ; ++t )
631 indiv(t) = dynamicImage->
at(x, y, z, t ) ;
632 segmented->at(x, y, z) = affectedTo( indiv ) ;
637 std::cout <<
"Probabilistic Pca classification completed" << std::endl ;
653 ( indivPriorProbabilities->getSizeX( ) == 1
654 && indivPriorProbabilities->getSizeY( ) == 1
655 && indivPriorProbabilities->getSizeZ( ) == 1 ) ;
661 std::vector<int> mdim =
mask->getSize();
662 for( z=0; z<mdim[2]; ++z )
663 for( y=0; y<mdim[1]; ++y )
664 for( x=0; x<mdim[0]; ++x )
665 if(
mask->at( x, y, z ) )
669 if( dynamicImage->getSizeT() != _data->getSizeT() )
671 if( fuzzySegmented->getSizeX() != _data->getSizeX()
672 || fuzzySegmented->getSizeY() != _data->getSizeY() ||
673 fuzzySegmented->getSizeZ() != _data->getSizeZ()
674 || fuzzySegmented->getSizeT() != int(_classes.size() ) )
677 _data->getSizeX(), _data->getSizeY(),
678 _data->getSizeZ(), _classes.size() ) );
682 std::vector<double> probabilityRepartition ;
683 std::vector<double> maxProbaByClass( _discrElements.size(), 0. ) ;
684 std::vector<double>
max( _discrElements.size(), 0. ) ;
686 carto::AllocatorContext::fast() ) ;
688 dynamicImage->getSizeY(),
689 dynamicImage->getSizeZ() );
691 std::vector<int> ddim = dynamicImage->getSize();
692 for( z=0; z<ddim[2]; ++z )
693 for( y=0; y<ddim[1]; ++y )
694 for( x=0; x<ddim[0]; ++x )
696 if(
mask->at(x, y, z) )
701 for(
int t = 0 ; t < _data->getSizeT() ; ++t )
703 indiv(t) = dynamicImage->
at(x, y, z, t ) ;
704 norm += indiv(t) * indiv(t);
708 probabilityRepartition = andersonScores(indiv,
norm,
710 for(
int c = 0 ; c < fuzzySegmented->getSizeT() ; ++c )
712 fuzzySegmented->at(x, y, z, c) = probabilityRepartition[c] ;
713 if( probabilityRepartition[c] >
max[c] )
714 max[c] = probabilityRepartition[c] ;
715 if( probabilityRepartition[c] > maxOnClass(x, y, z) )
716 maxOnClass(x, y, z) = probabilityRepartition[c] ;
721 std::cout <<
"Max on c = " ;
722 for(
int c = 0 ; c < fuzzySegmented->getSizeT() ; ++c )
723 std::cout <<
max[c] <<
" " << std::endl ;
745 std::cout <<
"Probabilistic Pca : fuzzy classification completed"
756 std::vector<double> res( _discrElements.size() ) ;
758 double scoreSum = 0. ;
759 for(
unsigned int c = 0 ; c < _discrElements.size() ; ++c )
760 scoreSum = _discrElements[c].posteriorProbability( x, 1 ) * _PIj[c] ;
void sort(carto::VolumeRef< T > &, carto::VolumeRef< T > &, carto::VolumeRef< T > *v=NULL)
sort the U and V matrices and the W vector in decreasing order
carto::VolumeRef< T > doit(carto::VolumeRef< T > &, carto::VolumeRef< T > *v=NULL)
Singular Value Decomposition.
void setReturnType(SVDReturnType rt)
void setVoxelSize(float sizex, float sizey, float sizez, float sizet)
double normFactor() const
const carto::VolumeRef< double > & mean() const
carto::VolumeRef< double > _x
double noiseVariance() const
carto::VolumeRef< double > _Wi
const carto::VolumeRef< double > & eigenValues()
carto::VolumeRef< double > _xT
carto::VolumeRef< double > _invCi
carto::VolumeRef< double > _EValues
carto::VolumeRef< double > _mean
carto::VolumeRef< double > _EVect
void doIt(const carto::rc_ptr< carto::Volume< T > > &individuals, double distanceRef=0.)
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 >())
std::vector< double > andersonScores(const carto::rc_ptr< carto::Volume< double > > &x, double px, std::vector< double > &maxProbaByClass)
double pX(const carto::rc_ptr< carto::Volume< double > > &x)
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)
std::vector< double > posteriorProbabilities(const carto::rc_ptr< carto::Volume< double > > &x, double px, std::vector< double > &maxProbaByClass)
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 >())
int affectedTo(const carto::rc_ptr< carto::Volume< double > > &x)
virtual bool write(const T &obj, bool ascii=false, const std::string *format=0)
VolumeRef< T > deepcopy() const
const T & at(long x, long y=0, long z=0, long t=0) const
float max(float x, float y)
AimsData< T > transpose(const AimsData< T > &thing)
BucketMap< Void > * mask(const BucketMap< Void > &src, const BucketMap< Void > &m, bool intersect=true)
VolumeRef< T > matrix_product(const Volume< T > &v1, const Volume< T > &v2)
AIMSDATA_API float norm(const Tensor &thing)
float norm2(const AimsVector< T, D > &v1)