// ------------------------------------------------------------------------- // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) // ------------------------------------------------------------------------- #ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__ITERATIVEGAUSSIANMODELESTIMATOR__HXX__ #define __CPPLUGINS__EXTENSIONS__ALGORITHMS__ITERATIVEGAUSSIANMODELESTIMATOR__HXX__ #include #include #include #include // ------------------------------------------------------------------------- template< class S, unsigned int D > void cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, D >:: UpdateModel( ) { if( this->m_Updated ) return; this->m_Cov.set_size( D, D ); this->m_Mean.set_size( D, 1 ); // Compute covariance matrix and mean vector unsigned long N = this->m_Samples.size( ); this->m_Mean = this->m_S1; if( N > 0 ) this->m_Mean /= S( N ); if( N > 1 ) { this->m_Cov = this->m_S2; this->m_Cov -= ( this->m_S1 * this->m_S1.transpose( ) ) / S( N ); this->m_Cov /= S( N - 1 ); } else this->m_Cov.fill( S( 0 ) ); // Compute inverse and determinant S det = vnl_determinant( this->m_Cov ); if( !( det > S( 0 ) ) ) { this->m_InvCov.set_size( D, D ); this->m_InvCov.fill( S( 0 ) ); this->m_DensityCoeff = S( 0 ); } else { this->m_InvCov = vnl_inverse( this->m_Cov ); double _2piD = std::pow( double( 2 ) * double( vnl_math::pi ), D ); this->m_DensityCoeff = S( 1 ) / S( std::sqrt( _2piD * double( det ) ) ); } // fi // Compute minimum and maximum probabilities from input samples static S sample[ D ]; for( unsigned long i = 0; i < this->m_Samples.size( ); ++i ) { for( unsigned int d = 0; d < D; ++d ) sample[ d ] = this->m_Samples[ i ][ d ][ 0 ]; S p = this->Probability( sample ); if( i == 0 ) { this->m_MinimumProbability = p; this->m_MaximumProbability = p; } else { if( p < this->m_MinimumProbability ) this->m_MinimumProbability = p; if( this->m_MaximumProbability < p ) this->m_MaximumProbability = p; } // fi } // rof this->m_Updated = true; } // ------------------------------------------------------------------------- template< class S, unsigned int D > template< class V > S cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, D >:: Probability( const V& sample ) const { TMatrix c( D, 1 ); for( unsigned int d = 0; d < D; ++d ) c[ d ][ 0 ] = S( sample[ d ] ) - this->m_Mean[ d ][ 0 ]; if( S( 0 ) < this->m_DensityCoeff ) { // Covariance is NOT null double v = double( ( c.transpose( ) * ( this->m_InvCov * c ) )[ 0 ][ 0 ] ); v /= double( 2 ); return( S( std::exp( -v ) ) ); } else { // Covariance is null bool equal = true; for( unsigned int d = 0; d < D && equal; ++d ) equal &= !( S( 0 ) < S( std::fabs( double( c[ d ][ 0 ] ) ) ) ); return( ( equal )? S( 1 ): S( 0 ) ); } // fi } // ------------------------------------------------------------------------- template< class S, unsigned int D > S cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, D >:: Probability( const S& s_x, const S& s_y, ... ) const { static S sample[ D ]; std::va_list args_lst; va_start( args_lst, s_y ); sample[ 0 ] = s_x; sample[ 1 ] = s_y; for( unsigned int d = 2; d < D; ++d ) sample[ d ] = S( va_arg( args_lst, double ) ); va_end( args_lst ); return( this->Probability( sample ) ); } // ------------------------------------------------------------------------- template< class S, unsigned int D > template< class V, class M > void cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, D >:: GetModel( V& m, M& E ) const { for( unsigned int i = 0; i < D; ++i ) { m[ i ] = double( this->m_Mean[ i ][ 0 ] ); for( unsigned int j = 0; j < D; ++j ) E[ i ][ j ] = double( this->m_Cov[ i ][ j ] ); } // rof } // ------------------------------------------------------------------------- template< class S, unsigned int D > void cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, D >:: Clear( ) { this->m_Updated = false; this->m_Samples.clear( ); this->m_S1.set_size( D, 1 ); this->m_S2.set_size( D, D ); this->m_S1.fill( S( 0 ) ); this->m_S2.fill( S( 0 ) ); this->Modified( ); } // ------------------------------------------------------------------------- template< class S, unsigned int D > template< class V > void cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, D >:: AddSample( const V& sample ) { TMatrix s( D, 1 ); for( unsigned int d = 0; d < D; ++d ) s[ d ][ 0 ] = S( sample[ d ] ); this->m_Samples.push_back( s ); this->m_S1 += s; this->m_S2 += s * s.transpose( ); this->m_Updated = false; this->Modified( ); } // ------------------------------------------------------------------------- template< class S, unsigned int D > void cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, D >:: AddSample( const S& s_x, const S& s_y, ... ) { static S sample[ D ]; std::va_list args_lst; va_start( args_lst, s_y ); sample[ 0 ] = s_x; sample[ 1 ] = s_y; for( unsigned int d = 2; d < D; ++d ) sample[ d ] = S( va_arg( args_lst, double ) ); va_end( args_lst ); this->AddSample( sample ); } // ------------------------------------------------------------------------- template< class S, unsigned int D > cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, D >:: IterativeGaussianModelEstimator( ) : Superclass( ) { this->Clear( ); } // ------------------------------------------------------------------------- template< class S, unsigned int D > cpPlugins::Extensions::Algorithms::IterativeGaussianModelEstimator< S, D >:: ~IterativeGaussianModelEstimator( ) { } #endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__ITERATIVEGAUSSIANMODELESTIMATOR__HXX__ // eof - $RCSfile$