Belle II Software development
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 <Math/Vector3D.h>
13#include <TRandom.h>
14#include <TVectorT.h>
15#include <TMatrixTBase.h>
16
17#include <array>
18
19namespace Belle2 {
55 public:
65 MultivariateNormalGenerator(int n, const double* mean, const double* cov)
66 {
67 setMeanCov(n, mean, cov);
68 }
73 MultivariateNormalGenerator(const Eigen::VectorXd& mean, const Eigen::MatrixXd& cov)
74 {
75 setMeanCov(mean, cov);
76 }
81 Eigen::VectorXd generate() const
82 {
83 //To get the correlated multivariate normal distribution, we multiply
84 //standard normal distributed values (mean=0, sigma=1) with a
85 //transformation matrix we obtained from an LDLT decomposition and add
86 //the mean values.
87 Eigen::VectorXd x(m_mean.rows());
88 for (int i = 0; i < m_mean.rows(); ++i) x(i) = gRandom->Gaus();
89 return m_mean + (m_transform * x);
90 }
94 void reset();
96 size_t size() const { return m_mean.rows(); }
101 void generate(double* output) const
102 {
103 Eigen::VectorXd x = generate();
104 for (int i = 0; i < x.rows(); ++i) { output[i] = x(i); }
105 }
106
113 ROOT::Math::XYZVector generateVec3() const
114 {
115 Eigen::VectorXd x = generate();
116 std::array<double, 3> tmp = {0.};
117 for (unsigned int i = 0; i < std::min(3u, (unsigned int)size()); ++i) {
118 tmp[i] = x(i);
119 }
120 return ROOT::Math::XYZVector(tmp[0], tmp[1], tmp[2]);
121 }
122
126 TVectorD generateVecT() const
127 {
128 Eigen::VectorXd x = generate();
129 TVectorD output(x.rows());
130 output.SetElements(x.data());
131 return output;
132 }
133
143 bool setMeanCov(int n, const double* mean, const double* cov);
144
150 bool setMeanCov(const Eigen::VectorXd& mean, const Eigen::MatrixXd& cov);
151
158 template<class value_type> bool setMeanCov(const TVectorT<value_type>& mean,
159 const TMatrixTBase<value_type>& cov);
160
166 template<class value_type> bool setMeanCov(const ROOT::Math::XYZVector& mean,
167 const TMatrixTBase<value_type>& cov);
168
169 private:
171 Eigen::VectorXd m_mean;
174 Eigen::MatrixXd m_transform;
175 };
176
177 template<class value_type> bool MultivariateNormalGenerator::setMeanCov(
178 const TVectorT<value_type>& mean, const TMatrixTBase<value_type>& cov)
179 {
180 Eigen::VectorXd emean(mean.GetNrows());
181 Eigen::MatrixXd ecov(cov.GetNrows(), cov.GetNcols());
182 for (int i = 0; i < mean.GetNrows(); ++i) { emean(i) = mean(i); }
183 for (int i = 0; i < cov.GetNrows(); ++i) {
184 for (int j = 0; j < cov.GetNcols(); ++j) {
185 ecov(i, j) = cov(i, j);
186 }
187 }
188 return setMeanCov(emean, ecov);
189 }
190
191 template<class value_type> bool MultivariateNormalGenerator::setMeanCov(
192 const ROOT::Math::XYZVector& mean, const TMatrixTBase<value_type>& cov)
193 {
194 TVectorT<value_type> tmean(3);
195 tmean[0] = mean.X();
196 tmean[1] = mean.Y();
197 tmean[2] = mean.Z();
198 return setMeanCov(tmean, cov);
199 }
201}
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.
ROOT::Math::XYZVector generateVec3() const
Generate a set of correlated random numbers with the previously set mean and covariance and return a ...
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.
Abstract base class for different kinds of events.