DMP_BBO library
DistributionGaussian.cpp
Go to the documentation of this file.
1 
25 
26 #include <iomanip>
27 
28 #include <boost/random.hpp>
29 #include <boost/random/variate_generator.hpp>
30 #include <boost/random/normal_distribution.hpp>
31 
32 #include <eigen3/Eigen/Core>
33 #include <eigen3/Eigen/Eigenvalues>
34 
36 
37 
38 using namespace std;
39 using namespace Eigen;
40 
41 namespace DmpBbo {
42 
43 // Initialize random number generator
44 boost::mt19937 DistributionGaussian::rng = boost::mt19937(getpid() + time(0));
45 
46 // Initialize uni-variate unit normal distribution
47 boost::variate_generator<boost::mt19937&, boost::normal_distribution<> >
48 *DistributionGaussian::normal_distribution_unit
49  = new boost::variate_generator<boost::mt19937&, boost::normal_distribution<> >(
50  rng,
51  boost::normal_distribution<>(0, 1)
52  );
53 
54 
55 DistributionGaussian::DistributionGaussian(const VectorXd& mean, const MatrixXd& covar)
56 {
57  mean_ = mean;
58  set_covar(covar);
59 }
60 
61 DistributionGaussian* DistributionGaussian::clone(void) const
62 {
63  return new DistributionGaussian(mean(),covar());
64 }
65 
66 void DistributionGaussian::set_mean(const VectorXd& mean)
67 {
68  assert(mean.size()==mean_.size());
69  mean_ = mean;
70 }
71 
72 double DistributionGaussian::maxEigenValue(void) const
73 {
74  if (max_eigen_value_<0.0)
75  {
76  SelfAdjointEigenSolver<MatrixXd> eigensolver(covar_);
77  if (eigensolver.info() == Success)
78  {
79  // Get the eigenvalues
80  VectorXd eigen_values = eigensolver.eigenvalues();
81  max_eigen_value_ = eigen_values.maxCoeff();
82  }
83  }
84  return max_eigen_value_;
85 }
86 
87 
88 
89 void DistributionGaussian::set_covar(const MatrixXd& covar) {
90  assert(covar.cols()==covar.rows());
91  assert(covar.rows()==mean_.size());
92  covar_ = covar;
93  covar_decomposed_ = MatrixXd::Zero(0,0);
94  max_eigen_value_ = -1.0;
95 }
96 
97 void DistributionGaussian::generateSamples(int n_samples, MatrixXd& samples) const
98 {
99  if (covar_decomposed_.size()==0)
100  {
101  // Now perform the Cholesky decomposition, which makes it easier to generate samples.
102  MatrixXd A(covar_.llt().matrixL());
103  covar_decomposed_ = A;
104  // Remark: it would have been better to do this in the constructor and set_covar,
105  // but I couldn't get it to work with boost::serialization (I tried hard)
106  }
107 
108 
109  int n_dims = mean_.size();
110  samples.resize(n_samples,n_dims);
111 
112  // http://en.wikipedia.org/wiki/Multivariate_normal_distribution#Drawing_values_from_the_distribution
113  VectorXd z(n_dims);
114  for (int i_sample=0; i_sample<n_samples; i_sample++)
115  {
116  // Generate vector with samples from standard normal distribution N(0,1)
117  for (int i_dim=0; i_dim<n_dims; i_dim++)
118  z(i_dim) = (*normal_distribution_unit)();
119 
120  // Compute x = mu + Az
121  samples.row(i_sample) = mean_ + covar_decomposed_*z;
122  }
123 }
124 
125 
126 std::ostream& operator<<(std::ostream& output, const DistributionGaussian& distribution)
127 {
128  output << "N([" << toString(distribution.mean_) << "], ["<< toString(distribution.covar_) << "])";
129  return output;
130 }
131 
132 
133 }
DistributionGaussian class header file.
std::ostream & operator<<(std::ostream &output, const DistributionGaussian &distribution)
A class for representing a Gaussian distribution.
std::string toString(const Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > &matrix)
Convert an Eigen matrix to a string.
Header file for serialization of Eigen matrices.