Main MRPT website > C++ reference for MRPT 1.4.0
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-2016, 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
14
15namespace 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];
41 uint32_t index;
43 } m_MT19937_data;
44
47
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>
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 */
306 inline ptrdiff_t random_generator_for_STL(ptrdiff_t i)
307 {
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
A thred-safe pseudo random number generator, based on an internal MT19937 randomness generator.
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.
void drawUniformUnsignedInt(uint64_t &ret_number)
double drawGaussian1D_normalized(double *likelihood=NULL)
Generate a normalized (mean=0, std=1) normally distributed sample.
void randomize(const uint32_t seed)
Initialize the PRNG from the given random seed.
void drawUniformMatrix(MAT &matrix, const double unif_min=0, const double unif_max=1)
Fills the given matrix with independent, uniformly distributed samples.
double drawGaussian1D(const double mean, const double std)
Generate a normally distributed pseudo-random number.
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.
void drawUniformVector(VEC &v, const double unif_min=0, const double unif_max=1)
Fills the given vector with independent, uniformly distributed samples.
CRandomGenerator(const uint32_t seed)
Constructor for providing a custom random seed to initialize the PRNG.
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...
void drawGaussian1DMatrix(MAT &matrix, const double mean=0, const double std=1)
Fills the given matrix with independent, 1D-normally distributed samples.
double drawUniform(const double Min, const double Max)
Generate a uniformly distributed pseudo-random number using the MT19937 algorithm,...
CRandomGenerator()
Default constructor: initialize random seed based on current time.
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 ...
mrpt::math::CMatrixDouble drawDefinitePositiveMatrix(const size_t dim, const double std_scale=1.0, const double diagonal_epsilon=1e-8)
Generates a random definite-positive matrix of the given size, using the formula C = v*v^t + epsilon*...
void drawGaussian1DVector(VEC &v, const double mean=0, const double std=1)
Fills the given vector with independent, 1D-normally distributed samples.
void MT19937_initializeGenerator(const uint32_t &seed)
void randomize()
Randomize the generators, based on current time.
void drawGaussianMultivariate(VECTORLIKE &out_result, const COVMATRIX &cov, const VECTORLIKE *mean=NULL)
Generate multidimensional random samples according to a given covariance matrix.
uint32_t drawUniform32bit()
Generate a uniformly distributed pseudo-random number using the MT19937 algorithm,...
uint64_t drawUniform64bit()
Returns a uniformly distributed pseudo-random number by joining two 32bit numbers from drawUniform32b...
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)
EIGEN_STRONG_INLINE double mean() const
Computes the mean of the entire matrix.
#define ASSERT_EQUAL_(__A, __B)
Definition: mrpt_macros.h:264
#define ASSERT_(f)
Definition: mrpt_macros.h:261
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
void randomNormalMultiDimensional(const mrpt::math::CMatrixTemplateNumeric< T > &cov, std::vector< T > &out_result)
Generate multidimensional random samples according to a given covariance matrix.
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.
BASE_IMPEXP CRandomGenerator randomGenerator
A static instance of a CRandomGenerator class, for use in single-thread applications.
ptrdiff_t random_generator_for_STL(ptrdiff_t i)
A random number generator for usage in STL algorithms expecting a function like this (eg,...
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.
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 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.
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 ...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
STL namespace.
CONTAINER::value_type element_t
Definition: math_frwds.h:85
Data used internally by the MT19937 PRNG algorithm.



Page generated by Doxygen 1.9.4 for MRPT 1.4.0 SVN: at Sun Aug 14 11:34:44 UTC 2022