/** * @file PDFParzenMulti.cpp * @brief Normal Distribution / Gaussian PDF * @author Erik Rodner * @date 01/29/2008 */ #include #include #include #include "vislearning/math/pdf/PDFParzenMulti.h" using namespace OBJREC; const double sqrt_2_m_pi = sqrt(2*M_PI); using namespace std; using namespace NICE; PDFParzenMulti::PDFParzenMulti( const VVector & _samples, const NICE::Matrix & _kernelInvCov ) : samples(_samples), kernelInvCov(_kernelInvCov) { assert(_samples.size()); det = NICE::det(kernelInvCov); dimension = _samples[0].size(); constant = 0.5 * ( dimension * log (2*M_PI) - log(det) ); } PDFParzenMulti::~PDFParzenMulti() { } double PDFParzenMulti::kernel ( const NICE::Vector & v ) const { double bilinear_result = 0.0; for ( size_t k = 0 ; k < kernelInvCov.rows() ; k++ ) for ( size_t l = k+1; l < kernelInvCov.cols(); l++ ) bilinear_result += 2 * kernelInvCov(k,l) * v[k] * v[l]; for ( size_t k = 0 ; k < kernelInvCov.rows(); k++ ) bilinear_result += kernelInvCov(k,k) * v[k] * v[k]; return exp( 0.5 * ( - bilinear_result ) ); } double PDFParzenMulti::getNLogDensity ( const NICE::Vector & x ) const { assert ( samples.size() > 0 ); if ( x.size() != samples[0].size() ) fthrow(Exception, "Dimensions " << x.size() << " (x) and " << samples[0].size() << " do not match."); double result = 0.0; for ( size_t k = 0 ; k < samples.size() ; k++ ) { Vector n ( samples[k] ); n -= x; result += kernel(n); } result /= (samples.size()); return - log(result) + constant; } int PDFParzenMulti::getDimension () const { assert ( samples.size() > 0 ); return dimension; }