00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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/matrices_metaprogramming.h>
00037 #include <mrpt/math/jacobians.h>
00038 #include <mrpt/random.h>
00039
00040 namespace mrpt
00041 {
00042 namespace math
00043 {
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
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();
00072 const double lambda = alpha*alpha*(Nx+K)-Nx;
00073 const double c = Nx+lambda;
00074
00075
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
00082 MAT_TYPE_SAMESIZE_OF(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
00088
00089 std::vector<VECTORLIKE3> Y(1+2*Nx);
00090 VECTORLIKE1 X = x_mean;
00091 functor(X,fixed_param,Y[0]);
00092 VECTORLIKE1 delta;
00093 delta.resize(Nx);
00094 size_t row=1;
00095 for (size_t i=0;i<Nx;i++)
00096 {
00097 L.extractRow(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
00105 mrpt::math::covariancesAndMeanWeighted(Y, y_cov,y_mean,&W_mean,&W_cov,elem_do_wrap2pi);
00106 MRPT_END
00107 }
00108
00109
00110
00111
00112
00113
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 std::vector<VECTORLIKE3> *out_samples_y = NULL
00125 )
00126 {
00127 MRPT_START
00128 std::vector<VECTORLIKE1> samples_x;
00129 mrpt::random::randomGenerator.drawGaussianMultivariateMany(samples_x,num_samples,x_cov,&x_mean);
00130 std::vector<VECTORLIKE3> 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
00139
00140
00141
00142
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
00157 functor(x_mean,fixed_param,y_mean);
00158
00159 MAT_TYPE_JACOBIAN_OF(VECTORLIKE1,VECTORLIKE3) 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 }
00168
00169 }
00170
00171
00172 #endif