test10.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/KDTree.hpp"
00004 #include "indii/ml/aux/GaussianKernel.hpp"
00005 #include "indii/ml/aux/PNorm.hpp"
00006 #include "indii/ml/aux/DiracMixturePdf.hpp"
00007 #include "indii/ml/aux/vector.hpp"
00008 #include "indii/ml/aux/matrix.hpp"
00009 #include "indii/ml/aux/Random.hpp"
00010 
00011 #include <gsl/gsl_statistics_double.h>
00012 
00013 #include <iostream>
00014 #include <fstream>
00015 
00016 using namespace std;
00017 
00018 namespace aux = indii::ml::aux;
00019 
00020 /**
00021  * @file test10.cpp
00022  *
00023  * Test of KDTree.
00024  *
00025  * This test:
00026  *
00027  * @li creates a random multivariate Gaussian mixture,
00028  * @li samples from this mixture and constructs a KD tree,
00029  *
00030  * Results are as follows:
00031  *
00032  * @include test10.out
00033  *
00034  * \image html test10_mixture.png "Original Gaussian mixture"
00035  * \image latex test10_mixture.eps "Original Gaussian mixture"
00036  * \image html test10_tree.png "KD tree approximation"
00037  * \image latex test10_tree.eps "KD tree approximation"
00038  */
00039 
00040 /**
00041  * Dimensionality of the distribution.
00042  */
00043 unsigned int M = 2;
00044 
00045 /**
00046  * Number of components in the Gaussian mixture.
00047  */
00048 unsigned int COMPONENTS = 4;
00049 
00050 /**
00051  * Number of samples to take.
00052  */
00053 unsigned int P = 10000;
00054 
00055 /**
00056  * Resolution of plots.
00057  */
00058 unsigned int RES = 200;
00059 
00060 /**
00061  * Scaling parameter.
00062  */
00063 double H = 16.0 / sqrt(P);
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::gaussian((maxCov + minCov) / 2.0,
00096           (maxCov - minCov) / 2.0);
00097     }
00098   }
00099   sigma = prod(L, trans(L)); // ensures cholesky decomposable
00100 
00101   return aux::GaussianPdf(mu, sigma);
00102 }
00103 
00104 /**
00105  * Run tests.
00106  */
00107 int main(int argc, const char* argv[]) {
00108   //int seed = static_cast<int>(aux::Random::uniform(0, 1000000));
00109   //std::cerr << "seed = " << seed << std::endl;
00110   //aux::Random::seed(seed);
00111   aux::Random::seed(781634);
00112 
00113   unsigned int i, j;
00114 
00115   /* create distribution */
00116   aux::GaussianMixturePdf mixture(M);
00117   for (i = 0; i < COMPONENTS; i++) {
00118     mixture.addComponent(createRandomGaussian(M),
00119         aux::Random::uniform(0.5,1.0));
00120   }
00121 
00122   /* sample from distribution */
00123   aux::DiracMixturePdf mixtureSamples(mixture, P);
00124 
00125   /* construct KD tree */
00126   aux::KDTree<> tree(mixtureSamples);
00127   aux::GaussianKernel K(M, H);
00128   aux::PNorm<2> N;
00129 
00130   /* sample from norm and kernel */
00131   aux::DiracMixturePdf kernelSamples(M);
00132   for (i = 0; i < P; i++) {
00133     kernelSamples.addComponent(aux::DiracPdf(N.sample(M)));
00134   }
00135 
00136   /* sample from KD tree */
00137   aux::DiracMixturePdf treeSamples(M);
00138   for (i = 0; i < P; i++) {
00139     treeSamples.addComponent(tree.sample(N, K));
00140   }
00141 
00142   /* importance sample from density tree */
00143   aux::GaussianPdf importance(mixture.getExpectation(),
00144       mixture.getCovariance());
00145   aux::DiracMixturePdf treeImportanceSamples(M);
00146   double treeDensity, importanceDensity;
00147   aux::vector sample(M);
00148 
00149   for (i = 0; i < P; i++) {
00150     sample = importance.sample();
00151     importanceDensity = importance.densityAt(sample);
00152     treeDensity = tree.densityAt(sample, N, K);
00153     treeImportanceSamples.addComponent(sample, treeDensity/importanceDensity);
00154   }
00155 
00156   cout << "Mixture mean" << endl <<
00157       mixture.getExpectation() << endl;
00158   cout << "Mixture covariance" << endl <<
00159       mixture.getCovariance() << endl;
00160   cout << "Sample mean" << endl <<
00161       mixtureSamples.getExpectation() << endl;
00162   cout << "Sample covariance" << endl <<
00163       mixtureSamples.getCovariance() << endl;
00164   //cout << "KD tree mean" << endl <<
00165   //    tree.getExpectation() << endl;
00166   //cout << "KD tree covariance" << endl <<
00167   //    tree.getCovariance() << endl;
00168   cout << "Kernel & norm sample mean" << endl <<
00169       kernelSamples.getExpectation() << endl;
00170   cout << "Kernel & norm sample covariance" << endl <<
00171       kernelSamples.getCovariance() << endl;
00172   cout << "KD tree sample mean" << endl <<
00173       treeSamples.getExpectation() << endl;
00174   cout << "KD tree sample covariance" << endl <<
00175       treeSamples.getCovariance() << endl;
00176   cout << "KD tree importance sample mean" << endl <<
00177       treeImportanceSamples.getExpectation() << endl;
00178   cout << "KD tree importance sample covariance" << endl <<
00179       treeImportanceSamples.getCovariance() << endl;
00180       
00181   /* calculate bounds */
00182   aux::vector lower(M), upper(M);
00183   aux::DiracMixturePdf::weighted_component_const_iterator iter, end;
00184   double s;
00185 
00186   iter = mixtureSamples.getComponents().begin();
00187   end = mixtureSamples.getComponents().end();
00188   assert (iter != end);
00189   noalias(lower) = iter->x;
00190   noalias(upper) = lower;
00191   iter++;
00192   while (iter != end) {
00193     for (i = 0; i < M; i++) {
00194       s = iter->x(i);
00195       if (s < lower(i)) {
00196         lower(i) = s;
00197       } else if (s > upper(i)) {
00198         upper(i) = s;
00199       }
00200     }
00201     iter++;
00202   }
00203 
00204   /* output for plots */
00205   ofstream fMixture("results/test10_mixture.out");
00206   ofstream fTree("results/test10_tree.out");
00207   aux::vector coord(M);
00208   double x, y, density;
00209   
00210   for (i = 0; i < RES; i++) {
00211     x = lower(0) + (upper(0) - lower(0)) * i / RES;
00212     coord(0) = x;
00213     for (j = 0; j < RES; j++) {
00214       y = lower(1) + (upper(1) - lower(1)) * j / RES;
00215       coord(1) = y;
00216       
00217       density = mixture.densityAt(coord);
00218       fMixture << x << '\t' << y << '\t' << density << endl;
00219       
00220       density = tree.densityAt(coord, N, K);
00221       fTree << x << '\t' << y << '\t' << density << endl;
00222     }
00223     
00224     /* end isolines */
00225     fMixture << endl;
00226     fTree << endl;
00227   }
00228  
00229   return 0; 
00230 }
00231 

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