Belle II Software  release-06-01-15
MultivariateNormalGenerator.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #pragma once
10 
11 #include <Eigen/Dense>
12 #include <TRandom.h>
13 #include <TVectorT.h>
14 #include <TVector3.h>
15 #include <TMatrixTBase.h>
16 
17 namespace Belle2 {
53  public:
63  MultivariateNormalGenerator(int n, const double* mean, const double* cov)
64  {
65  setMeanCov(n, mean, cov);
66  }
71  MultivariateNormalGenerator(const Eigen::VectorXd& mean, const Eigen::MatrixXd& cov)
72  {
73  setMeanCov(mean, cov);
74  }
79  Eigen::VectorXd generate() const
80  {
81  //To get the correlated multivariate normal distribution, we multiply
82  //standard normal distributed values (mean=0, sigma=1) with a
83  //transformation matrix we obtained from an LDLT decomposition and add
84  //the mean values.
85  Eigen::VectorXd x(m_mean.rows());
86  for (int i = 0; i < m_mean.rows(); ++i) x(i) = gRandom->Gaus();
87  return m_mean + (m_transform * x);
88  }
92  void reset();
94  size_t size() const { return m_mean.rows(); }
99  void generate(double* output) const
100  {
101  Eigen::VectorXd x = generate();
102  for (int i = 0; i < x.rows(); ++i) { output[i] = x(i); }
103  }
104 
111  TVector3 generateVec3() const
112  {
113  Eigen::VectorXd x = generate();
114  TVector3 output(0, 0, 0);
115  for (unsigned int i = 0; i < std::min(3u, (unsigned int)size()); ++i) {
116  output[i] = x(i);
117  }
118  return output;
119  }
120 
124  TVectorD generateVecT() const
125  {
126  Eigen::VectorXd x = generate();
127  TVectorD output(x.rows());
128  output.SetElements(x.data());
129  return output;
130  }
131 
141  bool setMeanCov(int n, const double* mean, const double* cov);
142 
148  bool setMeanCov(const Eigen::VectorXd& mean, const Eigen::MatrixXd& cov);
149 
156  template<class value_type> bool setMeanCov(const TVectorT<value_type>& mean,
157  const TMatrixTBase<value_type>& cov);
158 
165  template<class value_type> bool setMeanCov(const TVector3& mean,
166  const TMatrixTBase<value_type>& cov);
167  private:
169  Eigen::VectorXd m_mean;
172  Eigen::MatrixXd m_transform;
173  };
174 
175  template<class value_type> bool MultivariateNormalGenerator::setMeanCov(
176  const TVectorT<value_type>& mean, const TMatrixTBase<value_type>& cov)
177  {
178  Eigen::VectorXd emean(mean.GetNrows());
179  Eigen::MatrixXd ecov(cov.GetNrows(), cov.GetNcols());
180  for (int i = 0; i < mean.GetNrows(); ++i) { emean(i) = mean(i); }
181  for (int i = 0; i < cov.GetNrows(); ++i) {
182  for (int j = 0; j < cov.GetNcols(); ++j) {
183  ecov(i, j) = cov(i, j);
184  }
185  }
186  return setMeanCov(emean, ecov);
187  }
188 
189  template<class value_type> bool MultivariateNormalGenerator::setMeanCov(
190  const TVector3& mean, const TMatrixTBase<value_type>& cov)
191  {
192  TVectorT<value_type> tmean(3);
193  for (int i = 0; i < 3; ++i) {
194  tmean[i] = mean[i];
195  }
196  return setMeanCov(tmean, cov);
197  }
199 }
Class to generate normal distributed, correlated random numbers given the mean values and the covaria...
size_t size() const
Return the number of elements to be generated on generate()
MultivariateNormalGenerator(const Eigen::VectorXd &mean, const Eigen::MatrixXd &cov)
constructor with Eigen matrix interface.
void generate(double *output) const
Generate a set of correlated random numbers with the previouly set mean and covariance and store them...
MultivariateNormalGenerator(int n, const double *mean, const double *cov)
constructor with array interface: mean and covariance are passed as double arrays where the covarianc...
Eigen::VectorXd m_mean
Member to store the mean values of the distribution.
bool setMeanCov(int n, const double *mean, const double *cov)
set the mean and covariance for the distribution with array interface: mean and covariance are passed...
Eigen::VectorXd generate() const
Generate a set of correlated random numbers with the previouly set mean and covariance.
MultivariateNormalGenerator()
default constructor to allow later initialization
void reset()
reset the generator setting the size to 0.
TVectorD generateVecT() const
Generate a set of correlated random numbers with the previouly set mean and covariance and return a T...
Eigen::MatrixXd m_transform
Member to store the transformation matrix for standard normal distributed random values.
TVector3 generateVec3() const
Generate a set of correlated random numbers with the previouly set mean and covariance and return a T...
Abstract base class for different kinds of events.