Main MRPT website > C++ reference for MRPT 1.5.9
RandomGenerators.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 #ifndef RandomGenerator_H
10 #define RandomGenerator_H
11 
12 #include <mrpt/utils/utils_defs.h>
14 
15 namespace mrpt
16 {
17  namespace math { template <class T> class CMatrixTemplateNumeric; } // Frwd. decl.
18 
19  /** A namespace of pseudo-random numbers genrators of diferent distributions. The central class in this namespace is mrpt::random::CRandomGenerator
20  * \ingroup mrpt_base_grp
21  */
22  namespace random
23  {
24  /** A thred-safe pseudo random number generator, based on an internal MT19937 randomness generator.
25  * The base algorithm for randomness is platform-independent. See http://en.wikipedia.org/wiki/Mersenne_twister
26  *
27  * For real thread-safety, each thread must create and use its own instance of this class.
28  *
29  * Single-thread programs can use the static object mrpt::random::randomGenerator
30  * \ingroup mrpt_base_grp
31  */
33  {
34  protected:
35  /** Data used internally by the MT19937 PRNG algorithm. */
37  {
38  TMT19937_data() : index(0), seed_initialized(false)
39  {}
40  uint32_t MT[624];
43  } m_MT19937_data;
44 
47 
48  void MT19937_generateNumbers();
49  void MT19937_initializeGenerator(const uint32_t &seed);
50 
51  public:
52 
53  /** @name Initialization
54  @{ */
55 
56  /** Default constructor: initialize random seed based on current time */
57  CRandomGenerator() : m_MT19937_data(),m_std_gauss_set(false) { randomize(); }
58 
59  /** Constructor for providing a custom random seed to initialize the PRNG */
60  CRandomGenerator(const uint32_t seed) : m_MT19937_data() { randomize(seed); }
61 
62  void randomize(const uint32_t seed); //!< Initialize the PRNG from the given random seed
63  void randomize(); //!< Randomize the generators, based on current time
64 
65  /** @} */
66 
67  /** @name Uniform pdf
68  @{ */
69 
70  /** Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, in the whole range of 32-bit integers.
71  * See: http://en.wikipedia.org/wiki/Mersenne_twister */
72  uint32_t drawUniform32bit();
73 
74  /** Returns a uniformly distributed pseudo-random number by joining two 32bit numbers from \a drawUniform32bit() */
75  uint64_t drawUniform64bit();
76 
77  /** You can call this overloaded method with either 32 or 64bit unsigned ints for the sake of general coding. */
78  void drawUniformUnsignedInt(uint32_t &ret_number) { ret_number=drawUniform32bit(); }
79  void drawUniformUnsignedInt(uint64_t &ret_number) { ret_number=drawUniform64bit(); }
80 
81  /** Return a uniform unsigned integer in the range [min_val,max_val] (both inclusive) */
82  template <typename T, typename U,typename V>
83  void drawUniformUnsignedIntRange(T &ret_number,const U min_val,const V max_val)
84  {
85  const T range = max_val-min_val+1;
86  T rnd;
87  drawUniformUnsignedInt(rnd);
88  ret_number=min_val+ (rnd%range);
89  }
90 
91  /** Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, scaled to the selected range. */
92  double drawUniform( const double Min, const double Max) {
93  return Min + (Max-Min)* drawUniform32bit() * 2.3283064370807973754314699618685e-10; // 0xFFFFFFFF ^ -1
94  }
95 
96  /** Fills the given matrix with independent, uniformly distributed samples.
97  * Matrix classes can be mrpt::math::CMatrixTemplateNumeric or mrpt::math::CMatrixFixedNumeric
98  * \sa drawUniform
99  */
100  template <class MAT>
102  MAT &matrix,
103  const double unif_min = 0,
104  const double unif_max = 1 )
105  {
106  for (size_t r=0;r<matrix.getRowCount();r++)
107  for (size_t c=0;c<matrix.getColCount();c++)
108  matrix.get_unsafe(r,c) = static_cast<typename MAT::Scalar>( drawUniform(unif_min,unif_max) );
109  }
110 
111  /** Fills the given vector with independent, uniformly distributed samples.
112  * \sa drawUniform
113  */
114  template <class VEC>
116  VEC & v,
117  const double unif_min = 0,
118  const double unif_max = 1 )
119  {
120  const size_t N = v.size();
121  for (size_t c=0;c<N;c++)
122  v[c] = static_cast<typename mrpt::math::ContainerType<VEC>::element_t>( drawUniform(unif_min,unif_max) );
123  }
124 
125  /** @} */
126 
127  /** @name Normal/Gaussian pdf
128  @{ */
129 
130  /** Generate a normalized (mean=0, std=1) normally distributed sample.
131  * \param likelihood If desired, pass a pointer to a double which will receive the likelihood of the given sample to have been obtained, that is, the value of the normal pdf at the sample value.
132  */
133  double drawGaussian1D_normalized( double *likelihood = NULL);
134 
135  /** Generate a normally distributed pseudo-random number.
136  * \param mean The mean value of desired normal distribution
137  * \param std The standard deviation value of desired normal distribution
138  */
139  double drawGaussian1D( const double mean, const double std ) {
140  return mean+std*drawGaussian1D_normalized();
141  }
142 
143  /** Fills the given matrix with independent, 1D-normally distributed samples.
144  * Matrix classes can be mrpt::math::CMatrixTemplateNumeric or mrpt::math::CMatrixFixedNumeric
145  * \sa drawGaussian1D
146  */
147  template <class MAT>
149  MAT &matrix,
150  const double mean = 0,
151  const double std = 1 )
152  {
153  for (size_t r=0;r<matrix.getRowCount();r++)
154  for (size_t c=0;c<matrix.getColCount();c++)
155  matrix.get_unsafe(r,c) = static_cast<typename MAT::Scalar>( drawGaussian1D(mean,std) );
156  }
157 
158  /** Generates a random definite-positive matrix of the given size, using the formula C = v*v^t + epsilon*I, with "v" being a vector of gaussian random samples.
159  */
160  mrpt::math::CMatrixDouble drawDefinitePositiveMatrix(const size_t dim, const double std_scale = 1.0, const double diagonal_epsilon = 1e-8);
161 
162  /** Fills the given vector with independent, 1D-normally distributed samples.
163  * \sa drawGaussian1D
164  */
165  template <class VEC>
167  VEC & v,
168  const double mean = 0,
169  const double std = 1 )
170  {
171  const size_t N = v.size();
172  for (size_t c=0;c<N;c++)
173  v[c] = static_cast<typename mrpt::math::ContainerType<VEC>::element_t>( drawGaussian1D(mean,std) );
174  }
175 
176  /** Generate multidimensional random samples according to a given covariance matrix.
177  * Mean is assumed to be zero if mean==NULL.
178  * \exception std::exception On invalid covariance matrix
179  * \sa drawGaussianMultivariateMany
180  */
181  template <typename T>
182  void drawGaussianMultivariate(
183  std::vector<T> &out_result,
185  const std::vector<T>* mean = NULL
186  );
187 
188 
189  /** Generate multidimensional random samples according to a given covariance matrix.
190  * Mean is assumed to be zero if mean==NULL.
191  * \exception std::exception On invalid covariance matrix
192  * \sa drawGaussianMultivariateMany
193  */
194  template <class VECTORLIKE,class COVMATRIX>
196  VECTORLIKE &out_result,
197  const COVMATRIX &cov,
198  const VECTORLIKE* mean = NULL
199  )
200  {
201  const size_t N = cov.rows();
202  ASSERT_(cov.rows()==cov.cols())
203  if (mean) ASSERT_EQUAL_(size_t(mean->size()),N)
204 
205  // Compute eigenvalues/eigenvectors of cov:
206  Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject> eigensolver(cov);
207 
208  typename Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject>::MatrixType eigVecs = eigensolver.eigenvectors();
209  typename Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject>::RealVectorType eigVals = eigensolver.eigenvalues();
210 
211  // Scale eigenvectors with eigenvalues:
212  // D.Sqrt(); Z = Z * D; (for each column)
213  eigVals = eigVals.array().sqrt();
214  for (typename COVMATRIX::Index i=0;i<eigVecs.cols();i++)
215  eigVecs.col(i) *= eigVals[i];
216 
217  // Set size of output vector:
218  out_result.assign(N,0);
219 
220  for (size_t i=0;i<N;i++)
221  {
222  typename COVMATRIX::Scalar rnd = drawGaussian1D_normalized();
223  for (size_t d=0;d<N;d++)
224  out_result[d]+= eigVecs.coeff(d,i) * rnd;
225  }
226  if (mean)
227  for (size_t d=0;d<N;d++)
228  out_result[d]+= (*mean)[d];
229  }
230 
231  /** Generate a given number of multidimensional random samples according to a given covariance matrix.
232  * \param cov The covariance matrix where to draw the samples from.
233  * \param desiredSamples The number of samples to generate.
234  * \param ret The output list of samples
235  * \param mean The mean, or zeros if mean==NULL.
236  */
237  template <typename VECTOR_OF_VECTORS,typename COVMATRIX>
239  VECTOR_OF_VECTORS &ret,
240  size_t desiredSamples,
241  const COVMATRIX &cov,
242  const typename VECTOR_OF_VECTORS::value_type *mean = NULL )
243  {
244  ASSERT_EQUAL_(cov.cols(),cov.rows())
245  if (mean) ASSERT_EQUAL_(size_t(mean->size()),size_t(cov.cols()))
246 
247  // Compute eigenvalues/eigenvectors of cov:
248  Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject> eigensolver(cov);
249 
250  typename Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject>::MatrixType eigVecs = eigensolver.eigenvectors();
251  typename Eigen::SelfAdjointEigenSolver<typename COVMATRIX::PlainObject>::RealVectorType eigVals = eigensolver.eigenvalues();
252 
253  // Scale eigenvectors with eigenvalues:
254  // D.Sqrt(); Z = Z * D; (for each column)
255  eigVals = eigVals.array().sqrt();
256  for (typename COVMATRIX::Index i=0;i<eigVecs.cols();i++)
257  eigVecs.col(i) *= eigVals[i];
258 
259  // Set size of output vector:
260  ret.resize(desiredSamples);
261  const size_t N = cov.cols();
262  for (size_t k=0;k<desiredSamples;k++)
263  {
264  ret[k].assign(N,0);
265  for (size_t i=0;i<N;i++)
266  {
267  typename COVMATRIX::Scalar rnd = drawGaussian1D_normalized();
268  for (size_t d=0;d<N;d++)
269  ret[k][d]+= eigVecs.coeff(d,i) * rnd;
270  }
271  if (mean)
272  for (size_t d=0;d<N;d++)
273  ret[k][d]+= (*mean)[d];
274  }
275  }
276 
277 
278  /** @} */
279 
280 
281  /** @name Miscellaneous
282  @{ */
283 
284  /** Returns a random permutation of a vector: all the elements of the input vector are in the output but at random positions.
285  */
286  template <class VEC>
287  void permuteVector(const VEC &in_vector, VEC &out_result)
288  {
289  out_result = in_vector;
290  const size_t N = out_result.size();
291  if (N>1)
292  std::random_shuffle( &out_result[0],&out_result[N-1] );
293  }
294 
295  /** @} */
296 
297  }; // end of CRandomGenerator --------------------------------------------------------------
298 
299 
300  /** A static instance of a CRandomGenerator class, for use in single-thread applications */
301  extern BASE_IMPEXP CRandomGenerator randomGenerator;
302 
303 
304  /** A random number generator for usage in STL algorithms expecting a function like this (eg, random_shuffle):
305  */
307  {
308  return randomGenerator.drawUniform32bit() % i;
309  }
310 
311  /** Fills the given matrix with independent, uniformly distributed samples.
312  * Matrix classes can be mrpt::math::CMatrixTemplateNumeric or mrpt::math::CMatrixFixedNumeric
313  * \sa matrixRandomNormal
314  */
315  template <class MAT>
317  MAT &matrix,
318  const double unif_min = 0,
319  const double unif_max = 1 )
320  {
321  for (size_t r=0;r<matrix.getRowCount();r++)
322  for (size_t c=0;c<matrix.getColCount();c++)
323  matrix.get_unsafe(r,c) = static_cast<typename MAT::Scalar>( randomGenerator.drawUniform(unif_min,unif_max) );
324  }
325 
326  /** Fills the given matrix with independent, uniformly distributed samples.
327  * \sa vectorRandomNormal
328  */
329  template <class T>
331  std::vector<T> &v_out,
332  const T& unif_min = 0,
333  const T& unif_max = 1 )
334  {
335  size_t n = v_out.size();
336  for (size_t r=0;r<n;r++)
337  v_out[r] = randomGenerator.drawUniform(unif_min,unif_max);
338  }
339 
340  /** Fills the given matrix with independent, normally distributed samples.
341  * Matrix classes can be mrpt::math::CMatrixTemplateNumeric or mrpt::math::CMatrixFixedNumeric
342  * \sa matrixRandomUni
343  */
344  template <class MAT>
346  MAT &matrix,
347  const double mean = 0,
348  const double std = 1 )
349  {
350  for (size_t r=0;r<matrix.getRowCount();r++)
351  for (size_t c=0;c<matrix.getColCount();c++)
352  matrix.get_unsafe(r,c) = static_cast<typename MAT::Scalar>( mean + std*randomGenerator.drawGaussian1D_normalized() );
353  }
354 
355  /** Generates a random vector with independent, normally distributed samples.
356  * \sa matrixRandomUni
357  */
358  template <class T>
360  std::vector<T> &v_out,
361  const T& mean = 0,
362  const T& std = 1 )
363  {
364  size_t n = v_out.size();
365  for (size_t r=0;r<n;r++)
367  }
368 
369  /** Randomize the generators.
370  * A seed can be providen, or a current-time based seed can be used (default)
371  */
372  inline void Randomize(const uint32_t seed) {
374  }
375  inline void Randomize() {
377  }
378 
379  /** Returns a random permutation of a vector: all the elements of the input vector are in the output but at random positions.
380  */
381  template <class T>
383  const std::vector<T> &in_vector,
384  std::vector<T> &out_result)
385  {
386  randomGenerator.permuteVector(in_vector,out_result);
387  }
388 
389 
390  /** Generate multidimensional random samples according to a given covariance matrix.
391  * \exception std::exception On invalid covariance matrix
392  * \sa randomNormalMultiDimensionalMany
393  */
394  template <typename T>
397  std::vector<T> &out_result)
398  {
400  }
401 
402  /** Generate a given number of multidimensional random samples according to a given covariance matrix.
403  * \param cov The covariance matrix where to draw the samples from.
404  * \param desiredSamples The number of samples to generate.
405  * \param samplesLikelihoods If desired, set to a valid pointer to a vector, where it will be stored the likelihoods of having obtained each sample: the product of the gaussian-pdf for each independent variable.
406  * \param ret The output list of samples
407  *
408  * \exception std::exception On invalid covariance matrix
409  *
410  * \sa randomNormalMultiDimensional
411  */
412  template <typename T>
415  size_t desiredSamples,
416  std::vector< std::vector<T> > &ret,
417  std::vector<T> *samplesLikelihoods = NULL)
418  {
419  randomGenerator.drawGaussianMultivariateMany(ret,desiredSamples,cov,static_cast<const std::vector<T>*>(NULL),samplesLikelihoods);
420  }
421 
422  /** Generate multidimensional random samples according to a given covariance matrix.
423  * \exception std::exception On invalid covariance matrix
424  * \sa randomNormalMultiDimensional
425  */
426  template <typename T,typename MATRIXLIKE>
428  const MATRIXLIKE &cov,
429  size_t desiredSamples,
430  std::vector< std::vector<T> > &ret )
431  {
433  }
434 
435  /** Generate multidimensional random samples according to a given covariance matrix.
436  * \exception std::exception On invalid covariance matrix
437  * \sa randomNormalMultiDimensionalMany
438  */
439  template <typename T,typename MATRIXLIKE>
441  const MATRIXLIKE &cov,
442  std::vector<T> &out_result)
443  {
445  }
446 
447 
448  }// End of namespace
449 
450 } // End of namespace
451 
452 #endif
#define ASSERT_EQUAL_(__A, __B)
uint32_t drawUniform32bit()
Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, in the whole range of 32-bit integers.
double drawUniform(const double Min, const double Max)
Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, scaled to the selected range.
GLsizei range
Definition: glext.h:5281
void permuteVector(const VEC &in_vector, VEC &out_result)
Returns a random permutation of a vector: all the elements of the input vector are in the output but ...
void drawUniformUnsignedInt(uint32_t &ret_number)
You can call this overloaded method with either 32 or 64bit unsigned ints for the sake of general cod...
GLuint GLenum matrix
Definition: glext.h:6092
void drawGaussian1DVector(VEC &v, const double mean=0, const double std=1)
Fills the given vector with independent, 1D-normally distributed samples.
void randomNormalMultiDimensional(const mrpt::math::CMatrixTemplateNumeric< T > &cov, std::vector< T > &out_result)
Generate multidimensional random samples according to a given covariance matrix.
BASE_IMPEXP CRandomGenerator randomGenerator
A static instance of a CRandomGenerator class, for use in single-thread applications.
void randomize(const uint32_t seed)
Initialize the PRNG from the given random seed.
GLenum GLsizei n
Definition: glext.h:4618
void drawGaussian1DMatrix(MAT &matrix, const double mean=0, const double std=1)
Fills the given matrix with independent, 1D-normally distributed samples.
STL namespace.
A thred-safe pseudo random number generator, based on an internal MT19937 randomness generator...
void randomPermutation(const std::vector< T > &in_vector, std::vector< T > &out_result)
Returns a random permutation of a vector: all the elements of the input vector are in the output but ...
void drawUniformUnsignedIntRange(T &ret_number, const U min_val, const V max_val)
Return a uniform unsigned integer in the range [min_val,max_val] (both inclusive) ...
double drawGaussian1D_normalized(double *likelihood=NULL)
Generate a normalized (mean=0, std=1) normally distributed sample.
void drawGaussianMultivariateMany(VECTOR_OF_VECTORS &ret, size_t desiredSamples, const COVMATRIX &cov, const typename VECTOR_OF_VECTORS::value_type *mean=NULL)
Generate a given number of multidimensional random samples according to a given covariance matrix...
double drawGaussian1D(const double mean, const double std)
Generate a normally distributed pseudo-random number.
void drawUniformMatrix(MAT &matrix, const double unif_min=0, const double unif_max=1)
Fills the given matrix with independent, uniformly distributed samples.
Eigen::Matrix< typename MATRIX::Scalar, MATRIX::ColsAtCompileTime, MATRIX::ColsAtCompileTime > cov(const MATRIX &v)
Computes the covariance matrix from a list of samples in an NxM matrix, where each row is a sample...
Definition: ops_matrices.h:135
GLuint index
Definition: glext.h:3891
const GLubyte * c
Definition: glext.h:5590
Data used internally by the MT19937 PRNG algorithm.
void drawGaussianMultivariate(VECTORLIKE &out_result, const COVMATRIX &cov, const VECTORLIKE *mean=NULL)
Generate multidimensional random samples according to a given covariance matrix.
void Randomize(const uint32_t seed)
Randomize the generators.
void vectorRandomNormal(std::vector< T > &v_out, const T &mean=0, const T &std=1)
Generates a random vector with independent, normally distributed samples.
CRandomGenerator(const uint32_t seed)
Constructor for providing a custom random seed to initialize the PRNG.
ptrdiff_t random_generator_for_STL(ptrdiff_t i)
A random number generator for usage in STL algorithms expecting a function like this (eg...
_W64 int ptrdiff_t
Definition: glew.h:133
void randomNormalMultiDimensionalMany(const mrpt::math::CMatrixTemplateNumeric< T > &cov, size_t desiredSamples, std::vector< std::vector< T > > &ret, std::vector< T > *samplesLikelihoods=NULL)
Generate a given number of multidimensional random samples according to a given covariance matrix...
unsigned __int64 uint64_t
Definition: rptypes.h:52
const GLdouble * v
Definition: glext.h:3603
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLdouble GLdouble GLdouble r
Definition: glext.h:3618
void matrixRandomNormal(MAT &matrix, const double mean=0, const double std=1)
Fills the given matrix with independent, normally distributed samples.
void matrixRandomUni(MAT &matrix, const double unif_min=0, const double unif_max=1)
Fills the given matrix with independent, uniformly distributed samples.
#define ASSERT_(f)
CRandomGenerator()
Default constructor: initialize random seed based on current time.
CONTAINER::value_type element_t
Definition: math_frwds.h:85
void vectorRandomUni(std::vector< T > &v_out, const T &unif_min=0, const T &unif_max=1)
Fills the given matrix with independent, uniformly distributed samples.
void drawGaussianMultivariate(std::vector< T > &out_result, const mrpt::math::CMatrixTemplateNumeric< T > &cov, const std::vector< T > *mean=NULL)
Generate multidimensional random samples according to a given covariance matrix.
unsigned __int32 uint32_t
Definition: rptypes.h:49
void drawUniformVector(VEC &v, const double unif_min=0, const double unif_max=1)
Fills the given vector with independent, uniformly distributed samples.
double Scalar
Definition: KmUtils.h:41
EIGEN_STRONG_INLINE double mean() const
Computes the mean of the entire matrix.
void drawUniformUnsignedInt(uint64_t &ret_number)



Page generated by Doxygen 1.8.14 for MRPT 1.5.9 Git: 690a4699f Wed Apr 15 19:29:53 2020 +0200 at miƩ abr 15 19:30:12 CEST 2020