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