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];
43 } m_MT19937_data;
44
47
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 */
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 {
432 randomGenerator.drawGaussianMultivariateMany(ret,desiredSamples,cov);
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
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 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.
unsigned long uint32_t
Definition: pstdint.h:216
CONTAINER::value_type element_t
Definition: math_frwds.h:85
Data used internally by the MT19937 PRNG algorithm.



Page generated by Doxygen 1.9.6 for MRPT 1.4.0 SVN: at Wed Mar 22 06:16:42 UTC 2023