UnscentedTransformationHarness.cpp

Go to the documentation of this file.
00001 #include "indii/ml/filter/UnscentedTransformation.hpp"
00002 #include "indii/ml/filter/UnscentedTransformationModel.hpp"
00003 #include "indii/ml/aux/GaussianPdf.hpp"
00004 #include "indii/ml/aux/vector.hpp"
00005 #include "indii/ml/aux/matrix.hpp"
00006 
00007 #include "gsl/gsl_statistics_double.h"
00008 #include "gsl/gsl_rng.h"
00009 
00010 #include <iostream>
00011 #include <fstream>
00012 
00013 using namespace std;
00014 using namespace indii::ml::filter;
00015 
00016 namespace aux = indii::ml::aux;
00017 
00018 /**
00019  * @file UnscentedTransformationHarness.cpp
00020  *
00021  * Tests of UnscentedTransformation.
00022  *
00023  * @section sanity Sanity test
00024  *
00025  * This is a sanity check of the unscented transformation. A random
00026  * multivariate Gaussian distribution is generated. The unscented
00027  * transformation is then used to propagate it through the trivial
00028  * #sanityModel.
00029  *
00030  * Results are as follows:
00031  *
00032  * @include UnscentedTransformationHarness_sanity.out
00033  *
00034  * @section linear Linear test
00035  *
00036  * Propagation through #linearModel.
00037  *
00038  * Results are as follows:
00039  *
00040  * @include UnscentedTransformationHarness_linear.out
00041  *
00042  * @section nonlinear Nonlinear test
00043  *
00044  * Propagation through #nonlinearModel.
00045  *
00046  * Results are as follows:
00047  *
00048  * @include UnscentedTransformationHarness_nonlinear.out
00049  */
00050 
00051 /**
00052  * Dimensionality of the Gaussian.
00053  */
00054 unsigned int M = 10;
00055 
00056 /**
00057  * Number of samples to take for sampling output distribution.
00058  */
00059 unsigned int N = 10000;
00060 
00061 /**
00062  * Sanity check function \f$f(x) = x\f$ for testing.
00063  */
00064 class SanityModel : public UnscentedTransformationModel<> {
00065 public:
00066   virtual aux::vector propagate(const aux::vector& x, unsigned int delta = 0) {
00067     return x;
00068   }
00069 } sanityModel;
00070 
00071 /**
00072  * Linear function \f$f(x) = 3x\f$ for testing.
00073  */
00074 class LinearModel : public UnscentedTransformationModel<> {
00075 public:
00076   virtual aux::vector propagate(const aux::vector& x, unsigned int delta = 0) {
00077     return 3.0 * x;
00078   }
00079 } linearModel;
00080 
00081 /**
00082  * Nonlinear function \f$f(x) = x^2\f$ for testing.
00083  */
00084 class NonlinearModel : public UnscentedTransformationModel<> {
00085 public:
00086   virtual aux::vector propagate(const aux::vector& x, unsigned int delta = 0) {
00087     return element_prod(x, x);
00088   }
00089 } nonlinearModel;
00090 
00091 /**
00092  * Run tests.
00093  */
00094 int main(int argc, const char* argv[]) {
00095   aux::vector mu(M);  // true mean
00096   aux::symmetric_matrix sigma(M);  // true covariance
00097   aux::lower_triangular_matrix tmp(M,M);  // to construct Cholesky decomp sigma
00098   aux::vector smu(M);  // sample mean
00099   aux::symmetric_matrix ssigma(M);  // sample covariance
00100 
00101   aux::vector sample(M);
00102   double data[M][N];
00103   unsigned int i, j;
00104 
00105   /* set up true distribution */
00106   gsl_rng_env_setup();
00107   gsl_rng* rng = gsl_rng_alloc(gsl_rng_default);
00108   gsl_rng_set(rng, time(NULL));
00109 
00110   for (i = 0; i < M; i++) {
00111     mu(i) = gsl_rng_uniform(rng) * 10.0 - 5.0;
00112   }
00113   for (i = 0; i < M; i++) {
00114     for (j = 0; j <= i; j++) {
00115       tmp(i,j) = gsl_rng_uniform(rng) * 5.0;
00116     }
00117   }
00118   noalias(sigma) = prod(tmp, trans(tmp)); // ensures cholesky decomposition
00119   aux::GaussianPdf x(mu, sigma);
00120 
00121   /* prepare for tests */
00122   aux::GaussianPdf y(x.getDimensions());
00123   UnscentedTransformation<> sanity(sanityModel);
00124   UnscentedTransformation<> linear(linearModel);
00125   UnscentedTransformation<> nonlinear(nonlinearModel);
00126 
00127   /* sanity test */
00128   ofstream fsanity("results/UnscentedTransformationHarness_sanity.out");
00129   fsanity << "mean(x)" << endl << mu << endl;
00130   fsanity << "cov(x)" << endl << sigma << endl;
00131 
00132   /* sample */
00133   for (i = 0; i < N; i++) {
00134     sample = sanityModel.propagate(x.sample());
00135 
00136     for (j = 0; j < M; j++) {
00137       data[j][i] = sample(j);
00138     }
00139   }
00140   for (i = 0; i < M; i++) {
00141     smu(i) = gsl_stats_mean(data[i], 1, N);
00142   }
00143   for (i = 0; i < M; i++) {
00144     for (j = 0; j < M; j++) {
00145       ssigma(i,j) = gsl_stats_covariance(data[i], 1, data[j], 1, N);
00146     }
00147   }
00148   fsanity << "sample mean(f(x))" << endl << smu << endl;
00149   fsanity << "sample cov(f(x))" << endl << ssigma << endl;
00150 
00151   /* unscented */
00152   y = sanity.transform(x, 1);
00153   fsanity << "unscented mean(f(x))" << endl << y.getExpectation() << endl;
00154   fsanity << "unscented cov(f(x))" << endl << y.getCovariance() << endl;
00155 
00156   fsanity.close();
00157 
00158   /* linear test */
00159   ofstream flinear("results/UnscentedTransformationHarness_linear.out");
00160   flinear << "mean(x)" << endl << mu << endl;
00161   flinear << "cov(x)" << endl << sigma << endl;
00162 
00163   /* sample */
00164   for (i = 0; i < N; i++) {
00165     sample = linearModel.propagate(x.sample());
00166 
00167     for (j = 0; j < M; j++) {
00168       data[j][i] = sample(j);
00169     }
00170   }
00171   for (i = 0; i < M; i++) {
00172     smu(i) = gsl_stats_mean(data[i], 1, N);
00173   }
00174   for (i = 0; i < M; i++) {
00175     for (j = 0; j < M; j++) {
00176       ssigma(i,j) = gsl_stats_covariance(data[i], 1, data[j], 1, N);
00177     }
00178   }
00179   flinear << "sample mean(f(x))" << endl << smu << endl;
00180   flinear << "sample covariance(f(x))" << endl << ssigma << endl;
00181 
00182   /* unscented */
00183   y = linear.transform(x, 1);
00184   flinear << "unscented mean(f(x))" << endl << y.getExpectation() << endl;
00185   flinear << "unscented cov(f(x))" << endl << y.getCovariance() << endl;
00186 
00187   flinear.close();
00188 
00189   /* nonlinear test */
00190   ofstream fnonlinear("results/UnscentedTransformationHarness_nonlinear.out");
00191   fnonlinear << "mean(x)" << endl << mu << endl;
00192   fnonlinear << "cov(x)" << endl << sigma << endl;
00193 
00194   /* sample */
00195   for (i = 0; i < N; i++) {
00196     sample = nonlinearModel.propagate(x.sample());
00197 
00198     for (j = 0; j < M; j++) {
00199       data[j][i] = sample(j);
00200     }
00201   }
00202   for (i = 0; i < M; i++) {
00203     smu(i) = gsl_stats_mean(data[i], 1, N);
00204   }
00205   for (i = 0; i < M; i++) {
00206     for (j = 0; j < M; j++) {
00207       ssigma(i,j) = gsl_stats_covariance(data[i], 1, data[j], 1, N);
00208     }
00209   }
00210   fnonlinear << "sample mean(f(x))" << endl << smu << endl;
00211   fnonlinear << "sample cov(f(x))" << endl << ssigma << endl;
00212 
00213   /* unscented */
00214   y = nonlinear.transform(x, 1);
00215   fnonlinear << "unscented mean(f(x))" << endl << y.getExpectation() << endl;
00216   fnonlinear << "unscented cov(f(x))" << endl << y.getCovariance() << endl;
00217   fnonlinear.close();
00218 }

Generated on Wed Dec 17 15:05:50 2008 for dysii Filtering Test Suite by  doxygen 1.5.3