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 RandomGenerator_H
00029 #define RandomGenerator_H
00030
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/math/CMatrixTemplateNumeric.h>
00033 #include <mrpt/math/ops_matrices.h>
00034
00035 namespace mrpt
00036 {
00037
00038
00039
00040 namespace random
00041 {
00042 using namespace mrpt::utils;
00043 using namespace mrpt::math;
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 class BASE_IMPEXP CRandomGenerator
00054 {
00055 protected:
00056
00057 struct TMT19937_data
00058 {
00059 TMT19937_data() : index(0), seed_initialized(false)
00060 {}
00061 uint32_t MT[624];
00062 uint32_t index;
00063 bool seed_initialized;
00064 } m_MT19937_data;
00065
00066 void MT19937_generateNumbers();
00067 void MT19937_initializeGenerator(const uint32_t &seed);
00068
00069 public:
00070
00071
00072
00073
00074
00075 CRandomGenerator() : m_MT19937_data() { randomize(); }
00076
00077
00078 CRandomGenerator(const uint32_t seed) : m_MT19937_data() { randomize(seed); }
00079
00080 void randomize(const uint32_t seed);
00081 void randomize();
00082
00083
00084
00085
00086
00087
00088
00089
00090 uint32_t drawUniform32bit();
00091
00092
00093 double drawUniform( const double Min, const double Max) {
00094 return Min + (Max-Min)* drawUniform32bit() * 2.3283064370807973754314699618685e-10;
00095 }
00096
00097
00098
00099
00100
00101 template <class MAT>
00102 void drawUniformMatrix(
00103 MAT &matrix,
00104 const double unif_min = 0,
00105 const double unif_max = 1 )
00106 {
00107 for (size_t r=0;r<matrix.getRowCount();r++)
00108 for (size_t c=0;c<matrix.getColCount();c++)
00109 matrix.get_unsafe(r,c) = static_cast<typename MAT::value_type>( drawUniform(unif_min,unif_max) );
00110 }
00111
00112
00113
00114
00115 template <class VEC>
00116 void drawUniformVector(
00117 VEC & v,
00118 const double unif_min = 0,
00119 const double unif_max = 1 )
00120 {
00121 const size_t N = v.size();
00122 for (size_t c=0;c<N;c++)
00123 v[c] = static_cast<typename VEC::value_type>( drawUniform(unif_min,unif_max) );
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 double drawGaussian1D_normalized( double *likelihood = NULL);
00135
00136
00137
00138
00139
00140 double drawGaussian1D( const double mean, const double std ) {
00141 return mean+std*drawGaussian1D_normalized();
00142 }
00143
00144
00145
00146
00147
00148 template <class MAT>
00149 void drawGaussian1DMatrix(
00150 MAT &matrix,
00151 const double mean = 0,
00152 const double std = 1 )
00153 {
00154 for (size_t r=0;r<matrix.getRowCount();r++)
00155 for (size_t c=0;c<matrix.getColCount();c++)
00156 matrix.get_unsafe(r,c) = static_cast<typename MAT::value_type>( drawGaussian1D(mean,std) );
00157 }
00158
00159
00160
00161 CMatrixDouble drawDefinitePositiveMatrix(const size_t dim, const double std_scale = 1.0, const double diagonal_epsilon = 1e-8);
00162
00163
00164
00165
00166 template <class VEC>
00167 void drawGaussian1DVector(
00168 VEC & v,
00169 const double mean = 0,
00170 const double std = 1 )
00171 {
00172 const size_t N = v.size();
00173 for (size_t c=0;c<N;c++)
00174 v[c] = static_cast<typename VEC::value_type>( drawGaussian1D(mean,std) );
00175 }
00176
00177
00178
00179
00180
00181
00182 template <typename T>
00183 void drawGaussianMultivariate(
00184 std::vector<T> &out_result,
00185 const CMatrixTemplateNumeric<T> &cov,
00186 const std::vector<T>* mean = NULL
00187 );
00188
00189
00190
00191
00192
00193
00194
00195 template <class VECTORLIKE,class COVMATRIX>
00196 void drawGaussianMultivariate(
00197 VECTORLIKE &out_result,
00198 const COVMATRIX &cov,
00199 const VECTORLIKE* mean = NULL
00200 )
00201 {
00202 const size_t N = cov.rows();
00203 ASSERT_(cov.rows()==cov.cols())
00204 if (mean) ASSERT_EQUAL_(size_t(mean->size()),N)
00205
00206
00207 Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject> eigensolver(cov);
00208
00209 typename Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject>::MatrixType eigVecs = eigensolver.eigenvectors();
00210 typename Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject>::RealVectorType eigVals = eigensolver.eigenvalues();
00211
00212
00213
00214 eigVals = eigVals.array().sqrt();
00215 for (typename COVMATRIX::Index i=0;i<eigVecs.cols();i++)
00216 eigVecs.col(i) *= eigVals[i];
00217
00218
00219 out_result.assign(N,0);
00220
00221 for (size_t i=0;i<N;i++)
00222 {
00223 typename COVMATRIX::Scalar rnd = drawGaussian1D_normalized();
00224 for (size_t d=0;d<N;d++)
00225 out_result[d]+= eigVecs.coeff(d,i) * rnd;
00226 }
00227 if (mean)
00228 for (size_t d=0;d<N;d++)
00229 out_result[d]+= (*mean)[d];
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 template <typename VECTOR_OF_VECTORS,typename COVMATRIX>
00239 void drawGaussianMultivariateMany(
00240 VECTOR_OF_VECTORS &ret,
00241 size_t desiredSamples,
00242 const COVMATRIX &cov,
00243 const typename VECTOR_OF_VECTORS::value_type *mean = NULL )
00244 {
00245 ASSERT_EQUAL_(cov.cols(),cov.rows())
00246 if (mean) ASSERT_EQUAL_(size_t(mean->size()),size_t(cov.cols()))
00247
00248
00249 Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject> eigensolver(cov);
00250
00251 typename Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject>::MatrixType eigVecs = eigensolver.eigenvectors();
00252 typename Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject>::RealVectorType eigVals = eigensolver.eigenvalues();
00253
00254
00255
00256 eigVals = eigVals.array().sqrt();
00257 for (typename COVMATRIX::Index i=0;i<eigVecs.cols();i++)
00258 eigVecs.col(i) *= eigVals[i];
00259
00260
00261 ret.resize(desiredSamples);
00262 const size_t N = cov.cols();
00263 for (size_t k=0;k<desiredSamples;k++)
00264 {
00265 ret[k].assign(N,0);
00266 for (size_t i=0;i<N;i++)
00267 {
00268 typename COVMATRIX::Scalar rnd = drawGaussian1D_normalized();
00269 for (size_t d=0;d<N;d++)
00270 ret[k][d]+= eigVecs.coeff(d,i) * rnd;
00271 }
00272 if (mean)
00273 for (size_t d=0;d<N;d++)
00274 ret[k][d]+= (*mean)[d];
00275 }
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 template <class VEC>
00288 void permuteVector(const VEC &in_vector, VEC &out_result)
00289 {
00290 out_result = in_vector;
00291 const size_t N = out_result.size();
00292 if (N>1)
00293 std::random_shuffle( &out_result[0],&out_result[N-1] );
00294 }
00295
00296
00297
00298 };
00299
00300
00301
00302 extern BASE_IMPEXP CRandomGenerator randomGenerator;
00303
00304
00305
00306
00307 inline ptrdiff_t random_generator_for_STL(ptrdiff_t i)
00308 {
00309 return randomGenerator.drawUniform32bit() % i;
00310 }
00311
00312
00313
00314
00315
00316 template <class MAT>
00317 void matrixRandomUni(
00318 MAT &matrix,
00319 const double unif_min = 0,
00320 const double unif_max = 1 )
00321 {
00322 for (size_t r=0;r<matrix.getRowCount();r++)
00323 for (size_t c=0;c<matrix.getColCount();c++)
00324 matrix.get_unsafe(r,c) = static_cast<typename MAT::value_type>( randomGenerator.drawUniform(unif_min,unif_max) );
00325 }
00326
00327
00328
00329
00330 template <class T>
00331 void vectorRandomUni(
00332 std::vector<T> &v_out,
00333 const T& unif_min = 0,
00334 const T& unif_max = 1 )
00335 {
00336 size_t n = v_out.size();
00337 for (size_t r=0;r<n;r++)
00338 v_out[r] = randomGenerator.drawUniform(unif_min,unif_max);
00339 }
00340
00341
00342
00343
00344
00345 template <class MAT>
00346 void matrixRandomNormal(
00347 MAT &matrix,
00348 const double mean = 0,
00349 const double std = 1 )
00350 {
00351 for (size_t r=0;r<matrix.getRowCount();r++)
00352 for (size_t c=0;c<matrix.getColCount();c++)
00353 matrix.get_unsafe(r,c) = static_cast<typename MAT::value_type>( mean + std*randomGenerator.drawGaussian1D_normalized() );
00354 }
00355
00356
00357
00358
00359 template <class T>
00360 void vectorRandomNormal(
00361 std::vector<T> &v_out,
00362 const T& mean = 0,
00363 const T& std = 1 )
00364 {
00365 size_t n = v_out.size();
00366 for (size_t r=0;r<n;r++)
00367 v_out[r] = mean + std*randomGenerator.drawGaussian1D_normalized();
00368 }
00369
00370
00371
00372
00373 inline void Randomize(const uint32_t seed) {
00374 randomGenerator.randomize(seed);
00375 }
00376 inline void Randomize() {
00377 randomGenerator.randomize();
00378 }
00379
00380
00381
00382 template <class T>
00383 void randomPermutation(
00384 const std::vector<T> &in_vector,
00385 std::vector<T> &out_result)
00386 {
00387 randomGenerator.permuteVector(in_vector,out_result);
00388 }
00389
00390
00391
00392
00393
00394
00395 template <typename T>
00396 void randomNormalMultiDimensional(
00397 const CMatrixTemplateNumeric<T> &cov,
00398 std::vector<T> &out_result)
00399 {
00400 randomGenerator.drawGaussianMultivariate(out_result,cov);
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 template <typename T>
00414 void randomNormalMultiDimensionalMany(
00415 const CMatrixTemplateNumeric<T> &cov,
00416 size_t desiredSamples,
00417 std::vector< std::vector<T> > &ret,
00418 std::vector<T> *samplesLikelihoods = NULL)
00419 {
00420 randomGenerator.drawGaussianMultivariateMany(ret,desiredSamples,cov,static_cast<const std::vector<T>*>(NULL),samplesLikelihoods);
00421 }
00422
00423
00424
00425
00426
00427 template <typename T,size_t N>
00428 void randomNormalMultiDimensionalMany(
00429 const CMatrixFixedNumeric<T,N,N> &cov,
00430 size_t desiredSamples,
00431 std::vector< std::vector<T> > &ret )
00432 {
00433 randomGenerator.drawGaussianMultivariateMany(ret,desiredSamples,cov);
00434 }
00435
00436
00437
00438
00439
00440 template <typename T,size_t N>
00441 void randomNormalMultiDimensional(
00442 const CMatrixFixedNumeric<T,N,N> &cov,
00443 std::vector<T> &out_result)
00444 {
00445 randomGenerator.drawGaussianMultivariate(out_result,cov);
00446 }
00447
00448
00449 }
00450
00451 }
00452
00453 #endif