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