Main MRPT website > C++ reference
MRPT logo
transform_gaussian.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef  transform_gaussian_H
00029 #define  transform_gaussian_H
00030 
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/math/math_frwds.h>
00033 #include <mrpt/math/CMatrixTemplateNumeric.h>
00034 #include <mrpt/math/CMatrixFixedNumeric.h>
00035 #include <mrpt/math/ops_matrices.h>
00036 #include <mrpt/math/jacobians.h>
00037 #include <mrpt/random.h>
00038 
00039 namespace mrpt
00040 {
00041         namespace math
00042         {
00043                 /** @addtogroup  gausspdf_transform_grp Gaussian PDF transformation functions
00044                   *  \ingroup mrpt_base_grp
00045                   * @{ */
00046 
00047                 /** Scaled unscented transformation (SUT) for estimating the Gaussian distribution of a variable Y=f(X) for an arbitrary function f() provided by the user.
00048                   *  The user must supply the function in "functor" which takes points in the X space and returns the mapped point in Y, optionally using an extra, constant parameter ("fixed_param") which remains constant.
00049                   *
00050                   *  The parameters alpha, K and beta are the common names of the SUT method, and the default values are those recommended in most papers.
00051                   *
00052                   * \param elem_do_wrap2pi If !=NULL; it must point to an array of "bool" of size()==dimension of each element, stating if it's needed to do a wrap to [-pi,pi] to each dimension.
00053                   * \sa The example in MRPT/samples/unscented_transform_test
00054                   * \sa transform_gaussian_montecarlo, transform_gaussian_linear
00055                   */
00056                 template <class VECTORLIKE1,class MATLIKE1, class USERPARAM,class VECTORLIKE2,class VECTORLIKE3,class MATLIKE2>
00057                 void transform_gaussian_unscented(
00058                         const VECTORLIKE1 &x_mean,
00059                         const MATLIKE1    &x_cov,
00060                         void  (*functor)(const VECTORLIKE1 &x,const USERPARAM &fixed_param, VECTORLIKE3 &y),
00061                         const USERPARAM &fixed_param,
00062                         VECTORLIKE2 &y_mean,
00063                         MATLIKE2    &y_cov,
00064                         const bool *elem_do_wrap2pi = NULL,
00065                         const double alpha = 1e-3,
00066                         const double K = 0,
00067                         const double beta = 2.0
00068                         )
00069                 {
00070                         MRPT_START
00071                         const size_t Nx = x_mean.size(); // Dimensionality of inputs X
00072                         const double lambda = alpha*alpha*(Nx+K)-Nx;
00073                         const double c = Nx+lambda;
00074 
00075                         // Generate weights:
00076                         const double Wi = 0.5/c;
00077                         vector_double  W_mean(1+2*Nx,Wi),W_cov(1+2*Nx,Wi);
00078                         W_mean[0] = lambda/c;
00079                         W_cov[0]  = W_mean[0]+(1-alpha*alpha+beta);
00080 
00081                         // Generate X_i samples:
00082                         MATLIKE1 L;
00083                         const bool valid = x_cov.chol(L);
00084                         if (!valid) throw std::runtime_error("transform_gaussian_unscented: Singular covariance matrix in Cholesky.");
00085                         L*= sqrt(c);
00086 
00087                         // Propagate the samples X_i -> Y_i:
00088                         // We don't need to store the X sigma points: just use one vector to compute all the Y sigma points:
00089                         typename mrpt::aligned_containers<VECTORLIKE3>::vector_t Y(1+2*Nx); // 2Nx+1 sigma points
00090                         VECTORLIKE1 X = x_mean;
00091                         functor(X,fixed_param,Y[0]);
00092                         VECTORLIKE1 delta; // i'th row of L:
00093                         delta.resize(Nx);
00094                         size_t row=1;
00095                         for (size_t i=0;i<Nx;i++)
00096                         {
00097                                 L.extractRowAsCol(i,delta);
00098                                 X=x_mean;X-=delta;
00099                                 functor(X,fixed_param,Y[row++]);
00100                                 X=x_mean;X+=delta;
00101                                 functor(X,fixed_param,Y[row++]);
00102                         }
00103 
00104                         // Estimate weighted cov & mean:
00105                         mrpt::math::covariancesAndMeanWeighted(Y, y_cov,y_mean,&W_mean,&W_cov,elem_do_wrap2pi);
00106                         MRPT_END
00107                 }
00108 
00109                 /** Simple Montecarlo-base estimation of the Gaussian distribution of a variable Y=f(X) for an arbitrary function f() provided by the user.
00110                   *  The user must supply the function in "functor" which takes points in the X space and returns the mapped point in Y, optionally using an extra, constant parameter ("fixed_param") which remains constant.
00111                   * \param out_samples_y If !=NULL, this vector will contain, upon return, the sequence of random samples generated and propagated through the functor().
00112                   * \sa The example in MRPT/samples/unscented_transform_test
00113                   * \sa transform_gaussian_unscented, transform_gaussian_linear
00114                   */
00115                 template <class VECTORLIKE1,class MATLIKE1, class USERPARAM,class VECTORLIKE2,class VECTORLIKE3,class MATLIKE2>
00116                 void transform_gaussian_montecarlo(
00117                         const VECTORLIKE1 &x_mean,
00118                         const MATLIKE1    &x_cov,
00119                         void  (*functor)(const VECTORLIKE1 &x,const USERPARAM &fixed_param,VECTORLIKE3 &y),
00120                         const USERPARAM &fixed_param,
00121                         VECTORLIKE2 &y_mean,
00122                         MATLIKE2    &y_cov,
00123                         const size_t  num_samples = 1000,
00124                         typename mrpt::aligned_containers<VECTORLIKE3>::vector_t   *out_samples_y = NULL
00125                         )
00126                 {
00127                         MRPT_START
00128                         typename mrpt::aligned_containers<VECTORLIKE1>::vector_t samples_x;
00129                         mrpt::random::randomGenerator.drawGaussianMultivariateMany(samples_x,num_samples,x_cov,&x_mean);
00130                         typename mrpt::aligned_containers<VECTORLIKE3>::vector_t samples_y(num_samples);
00131                         for (size_t i=0;i<num_samples;i++)
00132                                 functor(samples_x[i],fixed_param,samples_y[i]);
00133                         mrpt::math::covariancesAndMean(samples_y,y_cov,y_mean);
00134                         if (out_samples_y) { out_samples_y->clear(); samples_y.swap(*out_samples_y); }
00135                         MRPT_END
00136                 }
00137 
00138                 /** First order uncertainty propagation estimator of the Gaussian distribution of a variable Y=f(X) for an arbitrary function f() provided by the user.
00139                   *  The user must supply the function in "functor" which takes points in the X space and returns the mapped point in Y, optionally using an extra, constant parameter ("fixed_param") which remains constant.
00140                   *  The Jacobians are estimated numerically using the vector of small increments "x_increments".
00141                   * \sa The example in MRPT/samples/unscented_transform_test
00142                   * \sa transform_gaussian_unscented, transform_gaussian_montecarlo
00143                   */
00144                 template <class VECTORLIKE1,class MATLIKE1, class USERPARAM,class VECTORLIKE2,class VECTORLIKE3,class MATLIKE2>
00145                 void transform_gaussian_linear(
00146                         const VECTORLIKE1 &x_mean,
00147                         const MATLIKE1    &x_cov,
00148                         void  (*functor)(const VECTORLIKE1 &x,const USERPARAM &fixed_param,VECTORLIKE3 &y),
00149                         const USERPARAM &fixed_param,
00150                         VECTORLIKE2 &y_mean,
00151                         MATLIKE2    &y_cov,
00152                         const VECTORLIKE1 &x_increments
00153                         )
00154                 {
00155                         MRPT_START
00156                         // Mean: simple propagation:
00157                         functor(x_mean,fixed_param,y_mean);
00158                         // Cov: COV = H C Ht
00159                         Eigen::Matrix<double,VECTORLIKE3::RowsAtCompileTime,VECTORLIKE1::RowsAtCompileTime> H;
00160                         mrpt::math::jacobians::jacob_numeric_estimate(x_mean,functor,x_increments,fixed_param,H);
00161                         H.multiply_HCHt(x_cov, y_cov);
00162                         MRPT_END
00163                 }
00164 
00165                 /** @} */
00166 
00167         } // End of MATH namespace
00168 
00169 } // End of namespace
00170 
00171 
00172 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011