forked from RobotLocomotion/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
random.h
81 lines (66 loc) · 2.87 KB
/
random.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#pragma once
#include <memory>
#include <random>
#include <Eigen/Core>
#include "drake/common/copyable_unique_ptr.h"
#include "drake/common/drake_assert.h"
#include "drake/common/drake_copyable.h"
#include "drake/common/eigen_types.h"
#include "drake/common/extract_double.h"
namespace drake {
/// Defines Drake's canonical implementation of the UniformRandomBitGenerator
/// C++ concept (as well as a few conventional extras beyond the concept, e.g.,
/// seeds). This uses the 32-bit Mersenne Twister mt19937 by Matsumoto and
/// Nishimura, 1998. For more information, see
/// https://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
class RandomGenerator {
public:
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(RandomGenerator)
using result_type = std::mt19937::result_type;
/// Creates a generator using the `default_seed`. Actual creation of the
/// generator is deferred until first use so this constructor is fast and
/// does not allocate any heap memory.
RandomGenerator() = default;
/// Creates a generator using given `seed`.
explicit RandomGenerator(result_type seed) : generator_(CreateEngine(seed)) {}
static constexpr result_type min() { return Engine::min(); }
static constexpr result_type max() { return Engine::max(); }
/// Generates a pseudo-random value.
result_type operator()() {
// Use lazy construction here, so that the default constructor can be fast.
if (generator_ == nullptr) {
generator_ = CreateEngine(default_seed);
}
return (*generator_)();
}
static constexpr result_type default_seed = std::mt19937::default_seed;
private:
using Engine = std::mt19937;
static std::unique_ptr<Engine> CreateEngine(result_type seed);
copyable_unique_ptr<Engine> generator_;
};
/// Drake supports explicit reasoning about a few carefully chosen random
/// distributions.
enum class RandomDistribution {
kUniform = 0, ///< Vector elements are independent and uniformly distributed
/// ∈ [0.0, 1.0).
kGaussian = 1, ///< Vector elements are independent and drawn from a
/// mean-zero, unit-variance normal (Gaussian) distribution.
kExponential = 2, ///< Vector elements are independent and drawn from an
/// exponential distribution with λ=1.0.
};
/**
* Calculates the density (probability density function) of the multivariate
* distribution.
* @param distribution The distribution type.
* @param x The value of the sampled vector.
* @tparam_nonsymbolic_scalar
*
* @note When instantiating this function, the user needs to explicitly pass in
* the scalar type, for example CalcProbabilityDensity<double>(...), the
* compiler might have problem to deduce the scalar type automatically.
*/
template <typename T>
T CalcProbabilityDensity(RandomDistribution distribution,
const Eigen::Ref<const VectorX<T>>& x);
} // namespace drake