/** * @file PDFMultinomial.cpp * @brief Normal Distribution / Gaussian PDF * @author Erik Rodner * @date 01/29/2008 */ #include #include #include "vislearning/math/pdf/PDFMultinomial.h" #include "vislearning/math/pdf/gslRandomNumberGenerator.h" using namespace OBJREC; using namespace std; // refactor-nice.pl: check this substitution // old: using namespace ice; using namespace NICE; PDFMultinomial::PDFMultinomial( int dimension ) : theta(dimension) { assert ( dimension > 0 ); N = 1; for ( int i = 0 ; i < dimension ; i++ ) theta[i] = 1.0 / dimension; } // refactor-nice.pl: check this substitution // old: PDFMultinomial::PDFMultinomial ( const Vector & _theta, int _N ) PDFMultinomial::PDFMultinomial ( const NICE::Vector & _theta, int _N ) : theta(_theta), N(_N) { } PDFMultinomial::~PDFMultinomial() { } // refactor-nice.pl: check this substitution // old: double PDFMultinomial::getNLogDensity ( const Vector & x ) const double PDFMultinomial::getNLogDensity ( const NICE::Vector & x ) const { #ifdef NICE_USELIB_GSL assert ( x.size() == theta.size() ); unsigned int *ix = new unsigned int[x.size()]; double r = gsl_ran_multinomial_lnpdf ( theta.size(), theta.getDataPointerConst(), ix ); delete [] ix; return r; #else #warning "PDFMultinomial::getNLogDensity: this function needs the GNU Scientific Library" fprintf (stderr, "PDFMultinomial::getNLogDensity: this function needs the GNU Scientific Library\n"); exit(-1); return 0.0; #endif } // refactor-nice.pl: check this substitution // old: double PDFMultinomial::getProb ( const Vector & x ) const double PDFMultinomial::getProb ( const NICE::Vector & x ) const { #ifdef NICE_USELIB_GSL assert ( x.size() == theta.size() ); unsigned int *ix = new unsigned int[theta.size()]; double r = gsl_ran_multinomial_pdf ( theta.size(), theta.getDataPointerConst(), ix ); delete [] ix; return r; #else #warning "PDFMultinomial::getProb: this function needs the GNU Scientific Library" fprintf (stderr, "PDFMultinomial::getProb: this function needs the GNU Scientific Library\n"); exit(-1); return 0.0; #endif } int PDFMultinomial::getDimension () const { return theta.size(); } int PDFMultinomial::sample () const { #ifdef NICE_USELIB_GSL if ( theta.size() == 1 ) return 0; initGSLRandom(); double r = gsl_rng_uniform(randomGSL); NICE::Vector cumDist ( theta.size() ); cumDist[0] = theta[0]; for ( int i = 1 ; i < theta.size() ; i++ ) { if ( r < cumDist[i-1] ) return i-1; cumDist[i] += cumDist[i-1] + theta[i]; } return theta.size()-1; #else #warning "PDFMultinomial::sample: this function needs the GNU Scientific Library" fprintf (stderr, "PDFMultinomial::sample: this function needs the GNU Scientific Library\n"); exit(-1); return 0; #endif } void PDFMultinomial::sample ( VVector & samples, int count ) const { #ifdef NICE_USELIB_GSL initGSLRandom(); unsigned int *ix = new unsigned int[theta.size()]; for ( int i = 0 ; i < count ; i++ ) { NICE::Vector x ( theta.size() ); gsl_ran_multinomial (randomGSL, theta.size(), N, theta.getDataPointerConst(), ix ); for ( int j = 0 ; j < theta.size() ; j++ ) x[j] = ix[j]; samples.push_back ( x ); } delete [] ix; #else #warning "PDFMultinomial::sample: this function needs the GNU Scientific Library" fprintf (stderr, "PDFMultinomial::sample: this function needs the GNU Scientific Library\n"); exit(-1); #endif } double PDFMultinomial::getDiscreteProbability ( int index ) const { assert ( (index >= 0) && (index < (int)theta.size()) ); return theta[index]; }