test9.cpp

Go to the documentation of this file.
00001 #include "indii/ml/aux/GaussianMixturePdf.hpp"
00002 #include "indii/ml/aux/GaussianPdf.hpp"
00003 #include "indii/ml/aux/DensityTreePdf.hpp"
00004 #include "indii/ml/aux/DiracMixturePdf.hpp"
00005 #include "indii/ml/aux/vector.hpp"
00006 #include "indii/ml/aux/matrix.hpp"
00007 #include "indii/ml/aux/Random.hpp"
00008 
00009 #include <gsl/gsl_statistics_double.h>
00010 
00011 #include <iostream>
00012 #include <fstream>
00013 
00014 using namespace std;
00015 
00016 namespace aux = indii::ml::aux;
00017 
00018 /**
00019  * @file test9.cpp
00020  *
00021  * Test of DensityTreePdf.
00022  *
00023  * This test:
00024  *
00025  * @li creates a random multivariate Gaussian mixture,
00026  * @li samples from this mixture and constructs a density tree,
00027  * @li compares the mean and covariance of the density tree with that of
00028  * the original mixture.
00029  * @li directly samples from the density tree and compares the mean and
00030  * covariance of this sample set with that of the original mixture.
00031  * @li importance samples from the density tree using a single Gaussian fit
00032  * to the original mixture and compares the mean and covariance of this
00033  * sample set with that of the original mixture.
00034  *
00035  * Results are as follows:
00036  *
00037  * @include test9.out
00038  *
00039  * \image html test9_mixture.png "Original Gaussian mixture"
00040  * \image latex test9_mixture.eps "Original Gaussian mixture"
00041  * \image html test9_tree.png "Density tree approximation"
00042  * \image latex test9_tree.eps "Density tree approximation"
00043  */
00044 
00045 /**
00046  * Dimensionality of the distribution.
00047  */
00048 unsigned int M = 2;
00049 
00050 /**
00051  * Number of components in the Gaussian mixture.
00052  */
00053 unsigned int COMPONENTS = 4;
00054 
00055 /**
00056  * Number of samples to take.
00057  */
00058 unsigned int P = 1000000;
00059 
00060 /**
00061  * Resolution of plots.
00062  */
00063 unsigned int RES = 200;
00064 
00065 /**
00066  * Create random Gaussian distribution.
00067  *
00068  * @param M Dimensionality of the Gaussian.
00069  * @param minMean Minimum value of any component of the mean.
00070  * @param maxMean Maximum value of any component of the mean.
00071  * @param minCov Minimum value of any component of the covariance.
00072  * @param maxCov Maximum value of any component of the covariance.
00073  *
00074  * @return Gaussian with given dimensionality, with mean and
00075  * covariance randomly generated uniformly from within the given
00076  * bounds.
00077  */
00078 aux::GaussianPdf createRandomGaussian(const unsigned int M,
00079     const double minMean = -1.0, const double maxMean = 1.0,
00080     const double minCov = -1.0, const double maxCov = 1.0) {
00081   aux::vector mu(M);
00082   aux::symmetric_matrix sigma(M);
00083   aux::lower_triangular_matrix L(M,M);
00084 
00085   unsigned int i, j;
00086 
00087   /* mean */
00088   for (i = 0; i < M; i++) {
00089     mu(i) = aux::Random::uniform(minMean, maxMean);
00090   }
00091 
00092   /* covariance */
00093   for (i = 0; i < M; i++) {
00094     for (j = 0; j <= i; j++) {
00095       L(i,j) = aux::Random::uniform(minCov, maxCov);
00096     }
00097   }
00098   sigma = prod(L, trans(L)); // ensures cholesky decomposable
00099 
00100   return aux::GaussianPdf(mu, sigma);
00101 }
00102 
00103 /**
00104  * Run tests.
00105  */
00106 int main(int argc, const char* argv[]) {
00107   unsigned int i, j;
00108 
00109   /* create distribution */
00110   aux::GaussianMixturePdf mixture(M);
00111   for (i = 0; i < COMPONENTS; i++) {
00112     mixture.addComponent(createRandomGaussian(M),
00113         aux::Random::uniform(0.5,1.0));
00114   }
00115 
00116   /* sample from distribution */
00117   aux::DiracMixturePdf mixtureSamples(mixture, P);
00118 
00119   /* construct density tree */
00120   aux::DensityTreeFactory factory(sqrt(P), 0.5*log(P)/log(2), 0.0,
00121       aux::DensityTreeFactory::SPLIT_VARIANCE);
00122   aux::DensityTreePdf tree(mixtureSamples, factory);
00123 
00124   /* sample from density tree */
00125   aux::DiracMixturePdf treeSamples(tree, P);
00126 
00127   /* importance sample from density tree */
00128   aux::GaussianPdf importance(mixture.getExpectation(),
00129       mixture.getCovariance());
00130   aux::DiracMixturePdf treeImportanceSamples(M);
00131   double treeDensity, importanceDensity;
00132   aux::vector sample(M);
00133   for (i = 0; i < P; i++) {
00134     sample = importance.sample();
00135     importanceDensity = importance.densityAt(sample);
00136     treeDensity = tree.densityAt(sample);
00137     treeImportanceSamples.addComponent(sample, treeDensity/importanceDensity);
00138   }
00139 
00140   cout << "Mixture mean" << endl <<
00141       mixture.getExpectation() << endl;
00142   cout << "Mixture covariance" << endl <<
00143       mixture.getCovariance() << endl;
00144   cout << "Sample mean" << endl <<
00145       mixtureSamples.getExpectation() << endl;
00146   cout << "Sample covariance" << endl <<
00147       mixtureSamples.getCovariance() << endl;
00148   cout << "Density tree mean" << endl <<
00149       tree.getExpectation() << endl;
00150   cout << "Density tree covariance" << endl <<
00151       tree.getCovariance() << endl;
00152   cout << "Density tree sample mean" << endl <<
00153       treeSamples.getExpectation() << endl;
00154   cout << "Density tree sample covariance" << endl <<
00155       treeSamples.getCovariance() << endl;
00156   cout << "Density tree importance sample mean" << endl <<
00157       treeImportanceSamples.getExpectation() << endl;
00158   cout << "Density tree importance sample covariance" << endl <<
00159       treeImportanceSamples.getCovariance() << endl;
00160       
00161   /* output for plots */
00162   ofstream fMixture("results/test9_mixture.out");
00163   ofstream fTree("results/test9_tree.out");
00164   const aux::vector& lower = tree.getLower();
00165   const aux::vector& upper = tree.getUpper();
00166   aux::vector coord(M);
00167   double x, y, density;
00168   
00169   for (i = 0; i < RES; i++) {
00170     x = lower(0) + (upper(0) - lower(0)) * i / RES;
00171     coord(0) = x;
00172     for (j = 0; j < RES; j++) {
00173       y = lower(1) + (upper(1) - lower(1)) * j / RES;
00174       coord(1) = y;
00175       
00176       density = mixture.densityAt(coord);
00177       fMixture << x << '\t' << y << '\t' << density << endl;
00178       
00179       density = tree.densityAt(coord);
00180       fTree << x << '\t' << y << '\t' << density << endl;
00181     }
00182     
00183     /* end isolines */
00184     fMixture << endl;
00185     fTree << endl;
00186   }
00187  
00188   return 0; 
00189 }
00190 

Generated on Wed Mar 5 16:36:30 2008 for dysii Probability Distributions Test Suite by  doxygen 1.5.2