test7.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/vector.hpp"
00004 #include "indii/ml/aux/matrix.hpp"
00005 #include "indii/ml/aux/parallel.hpp"
00006 #include "indii/ml/aux/Random.hpp"
00007 
00008 #include "boost/mpi/environment.hpp"
00009 #include "boost/mpi/communicator.hpp"
00010 
00011 #include <gsl/gsl_statistics_double.h>
00012 
00013 #include <iostream>
00014 
00015 using namespace std;
00016 
00017 namespace aux = indii::ml::aux;
00018 
00019 /**
00020  * @file test7.cpp
00021  *
00022  * Test of GaussianMixturePdf with distributed storage.
00023  *
00024  * This test creates a random multivariate Gaussian mixture with
00025  * components distributed across several nodes. It goes on to test the
00026  * various distributed methods to ensure invariance of the
00027  * distribution under these manipulations.
00028  *
00029  * Results follow.
00030  *
00031  * @include test7.out
00032  */
00033 
00034 /**
00035  * Dimensionality of the Gaussian mixture.
00036  */
00037 unsigned int M = 10;
00038 
00039 /**
00040  * Number of components in the Gaussian mixture.
00041  */
00042 unsigned int COMPONENTS = 50;
00043 
00044 /**
00045  * Number of samples to take.
00046  */
00047 unsigned int N = 10000;
00048 
00049 /**
00050  * Create random Gaussian distribution.
00051  *
00052  * @param M Dimensionality of the Gaussian.
00053  * @param minMean Minimum value of any component of the mean.
00054  * @param maxMean Maximum value of any component of the mean.
00055  * @param minCov Minimum value of any component of the covariance.
00056  * @param maxCov Maximum value of any component of the covariance.
00057  *
00058  * @return Gaussian with given dimensionality, with mean and
00059  * covariance randomly generated uniformly from within the given
00060  * bounds.
00061  */
00062 aux::GaussianPdf createRandomGaussian(const unsigned int M,
00063     const double minMean = -5.0, const double maxMean = 5.0,
00064     const double minCov = 0.0, const double maxCov = 5.0) {
00065   aux::vector mu(M);
00066   aux::symmetric_matrix sigma(M);
00067 
00068   unsigned int i, j;
00069 
00070   /* mean */
00071   for (i = 0; i < M; i++) {
00072     mu(i) = aux::Random::uniform(minMean, maxMean);
00073   }
00074 
00075   /* covariance */
00076   for (i = 0; i < M; i++) {
00077     for (j = 0; j <= i; j++) {
00078       sigma(i,j) = aux::Random::uniform(sqrt(minCov) / M, sqrt(maxCov) / M);
00079     }
00080   }
00081   sigma = prod(sigma, trans(sigma)); // ensures cholesky decomposable
00082 
00083   return aux::GaussianPdf(mu, sigma);
00084 }
00085 
00086 /**
00087  * Determines whether a vector is the zero vector.
00088  */
00089 bool isZero(const aux::vector& x) {
00090   unsigned int i;
00091   for (i = 0; i < x.size(); i++) {
00092     if (x(i) != 0.0) {
00093       return false;
00094     }
00095   }
00096   return true;
00097 }
00098 
00099 /**
00100  * Determine whether a matrix is the zero matrix.
00101  */
00102 bool isZero(const aux::matrix& A) {
00103   unsigned int i, j;
00104   for (i = 0; i < A.size1(); i++) {
00105     for (j = 0; j < A.size2(); j++) {
00106       if (A(i,j) != 0.0) {
00107   return false;
00108       }
00109     }
00110   }
00111   return true;
00112 }
00113 
00114 /**
00115  * Run tests.
00116  */
00117 int main(int argc, char* argv[]) {
00118   boost::mpi::environment env(argc, argv);
00119   boost::mpi::communicator world;
00120   const int rank = world.rank();
00121   
00122   unsigned int i;
00123   bool passed;
00124 
00125   aux::vector mu(M);  // true mean
00126   aux::symmetric_matrix sigma(M);  // true covariance
00127   aux::vector dmu(M);  // distributed mean
00128   aux::symmetric_matrix dsigma(M);  // distributed covariance
00129   aux::vector rdmu(M);  // rotated distributed mean
00130   aux::symmetric_matrix rdsigma(M);  // rotated distributed covariance
00131   aux::vector nmu(M);  // normalised distributed mean
00132   aux::symmetric_matrix nsigma(M);  // normalised distributed covariance
00133 
00134   /* create local distribution */
00135   aux::GaussianMixturePdf pdf(M);
00136   if (rank == 0) {
00137     for (i = 0; i < COMPONENTS; i++) {
00138       pdf.add(createRandomGaussian(M), aux::Random::uniform(0.0,1.0));
00139     }
00140     noalias(mu) = pdf.getExpectation();
00141     noalias(sigma) = pdf.getCovariance();
00142   }
00143   world.barrier();
00144   cout << rank << ": " << pdf.getSize() << " components, " <<
00145       pdf.getTotalWeight() << " weight" << endl;
00146 
00147   /* distribute across nodes */
00148   if (rank == 0) {
00149     cout << endl << "redistributeBySize() ";
00150   }
00151   world.barrier();
00152   pdf.redistributeBySize();
00153 
00154   noalias(dmu) = pdf.getDistributedExpectation();
00155   noalias(dsigma) = pdf.getDistributedCovariance();
00156 
00157   if (rank == 0) {
00158     passed = true;
00159     passed &= isZero(mu - dmu);
00160     passed &= isZero(sigma - dsigma);
00161     if (passed) {
00162       cout << "passed";
00163     } else {
00164       cout << "failed, difference is:" << endl;
00165       cout << mu - dmu << endl;
00166       cout << sigma - dsigma << endl;
00167     }
00168     cout << endl;
00169   }
00170   world.barrier();
00171   cout << rank << ": " << pdf.getSize() << " components, " <<
00172       pdf.getTotalWeight() << " weight" << endl;
00173 
00174   /* redistribute across nodes */
00175   if (rank == 0) {
00176     cout << endl << "redistributeByWeight() ";
00177   }
00178   world.barrier();
00179   pdf.redistributeByWeight();
00180 
00181   noalias(dmu) = pdf.getDistributedExpectation();
00182   noalias(dsigma) = pdf.getDistributedCovariance();
00183 
00184   if (rank == 0) {
00185     passed = true;
00186     passed &= isZero(mu - dmu);
00187     passed &= isZero(sigma - dsigma);
00188     if (passed) {
00189       cout << "passed";
00190     } else {
00191       cout << "failed, difference is:" << endl;
00192       cout << mu - dmu << endl;
00193       cout << sigma - dsigma << endl;
00194     }
00195     cout << endl;
00196   }
00197   world.barrier();
00198   cout << rank << ": " << pdf.getSize() << " components, " <<
00199       pdf.getTotalWeight() << " weight" << endl;
00200 
00201   /* rotate */
00202   if (rank == 0) {
00203     cout << endl << "rotate() ";
00204   }
00205   world.barrier();
00206   aux::rotate(pdf);
00207 
00208   noalias(rdmu) = pdf.getDistributedExpectation();
00209   noalias(rdsigma) = pdf.getDistributedCovariance();
00210 
00211   if (rank == 0) {
00212     passed = true;
00213     passed &= isZero(dmu - rdmu);
00214     passed &= isZero(dsigma - rdsigma);
00215     if (passed) {
00216       cout << "passed";
00217     } else {
00218       cout << "failed, difference is:" << endl;
00219       cout << dmu - rdmu << endl;
00220       cout << dsigma - rdsigma << endl;
00221     }
00222     cout << endl;
00223   }
00224   world.barrier();
00225   cout << rank << ": " << pdf.getSize() << " components, " <<
00226       pdf.getTotalWeight() << " weight" << endl;
00227 
00228   /* normalise */
00229   if (rank == 0) {
00230     cout << endl << "distributedNormalise() ";
00231   }
00232   world.barrier();
00233   pdf.distributedNormalise();
00234 
00235   noalias(nmu) = pdf.getDistributedExpectation();
00236   noalias(nsigma) = pdf.getDistributedCovariance();
00237 
00238   if (rank == 0) {
00239     passed = true;
00240     passed &= isZero(rdmu - nmu);
00241     passed &= isZero(rdsigma - nsigma);
00242     if (passed) {
00243       cout << "passed";
00244     } else {
00245       cout << "failed, difference is:" << endl;
00246       cout << rdmu - nmu << endl;
00247       cout << rdsigma - nsigma << endl;
00248     }
00249     cout << endl;
00250   }
00251   world.barrier();
00252   cout << rank << ": " << pdf.getSize() << " components, " <<
00253       pdf.getTotalWeight() << " weight" << endl;
00254 }
00255 

Generated on Wed Dec 17 15:01:30 2008 for dysii Probability Distributions Test Suite by  doxygen 1.5.3