Belle II Software development
test_gaussian_generators.cc
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#include <framework/utilities/ConditionalGaussGenerator.h>
10#include <framework/utilities/MultivariateNormalGenerator.h>
11
12#include <TRandom.h>
13#include <gtest/gtest.h>
14#include <cmath>
15
16using namespace Belle2;
17
18namespace {
19
21 class GaussGeneratorsTests : public ::testing::Test {
22 protected:
23
25 virtual void SetUp() { }
26
28 virtual void TearDown() { }
29
30 };
31
33 TEST_F(GaussGeneratorsTests, Generator6DTest)
34 {
35 Eigen::MatrixXd cov(6, 6);
36
37 // generate random matrix
38 for (int i = 0; i < 6; ++i)
39 for (int j = 0; j < 6; ++j)
40 cov(i, j) = gRandom->PoissonD(20) - 20;
41
42 // symmetrise it to obtain covariance
43 cov *= cov.transpose();
44
45 // some random central values
46 Eigen::VectorXd mu(6);
47 mu << 3, 0, -2, 7, -5, -1; // cppcheck-suppress constStatement
48
49 // init the generator
50 MultivariateNormalGenerator gen(mu, cov);
51
52 // calculate the mean and cov of the generated events
53 int N = 50000000;
54 Eigen::VectorXd muS = Eigen::VectorXd::Zero(6);
55 Eigen::MatrixXd covS = Eigen::MatrixXd::Zero(6, 6);
56 for (int i = 0; i < N; ++i) {
57 // generate whole random vector
58 Eigen::VectorXd x = gen.generate();
59 muS += x / N;
60 covS += (x - mu) * (x - mu).transpose() / N;
61 }
62
63 // check that mean vector and calculated cov agree with expectation
64 EXPECT_NEAR((muS - mu).squaredNorm(), 0.0, 1e-2);
65 EXPECT_NEAR((covS - cov).squaredNorm(), 0.0, 5e-2);
66
67 }
68
69
71 TEST_F(GaussGeneratorsTests, ConditionalGenerator2DTest)
72 {
73 //some random cov matrix
74 Eigen::MatrixXd cov(2, 2);
75 cov << 9, -4,
76 -4, 4; // cppcheck-suppress constStatement
77
78 // some mean
79 Eigen::VectorXd mu(2);
80 mu << 5., 9.; // cppcheck-suppress constStatement
81
82 // init the generator
83 ConditionalGaussGenerator gen(mu, cov);
84
85 // generate the events using conditional generator
86 int N = 10000000;
87 Eigen::VectorXd muS = Eigen::VectorXd::Zero(2);
88 Eigen::MatrixXd covS = Eigen::MatrixXd::Zero(2, 2);
89 for (int i = 0; i < N; ++i) {
90 // generate x0 using "external" random generator
91 double x0 = gRandom->Gaus(mu[0], sqrt(cov(0, 0)));
92
93 // generate whole random vector based on x0
94 Eigen::VectorXd x = gen.generate(x0);
95 muS += x / N;
96 covS += (x - mu) * (x - mu).transpose() / N;
97 }
98
99 // check that mean vector and calculated cov agree with expectation
100 EXPECT_NEAR((muS - mu).squaredNorm(), 0.0, 1e-3);
101 EXPECT_NEAR((covS - cov).squaredNorm(), 0.0, 1e-3);
102
103 }
104
106 TEST_F(GaussGeneratorsTests, ConditionalGenerator6DTest)
107 {
108 Eigen::MatrixXd cov(6, 6);
109
110 // generate random matrix
111 for (int i = 0; i < 6; ++i)
112 for (int j = 0; j < 6; ++j)
113 cov(i, j) = gRandom->PoissonD(20) - 20;
114
115 // symmetrise it to obtain covariance
116 cov *= cov.transpose();
117
118 // some random central values
119 Eigen::VectorXd mu(6);
120 mu << 3, 0, -2, 7, -5, -1; // cppcheck-suppress constStatement
121
122 // init the generator
123 ConditionalGaussGenerator gen(mu, cov);
124
125 // calculate the mean and cov of the generated events
126 int N = 50000000;
127 Eigen::VectorXd muS = Eigen::VectorXd::Zero(6);
128 Eigen::MatrixXd covS = Eigen::MatrixXd::Zero(6, 6);
129 for (int i = 0; i < N; ++i) {
130 // generate x0 using "external" random generator
131 double x0 = gRandom->Gaus(mu[0], sqrt(cov(0, 0)));
132
133 // generate whole random vector based on x0
134 Eigen::VectorXd x = gen.generate(x0);
135 muS += x / N;
136 covS += (x - mu) * (x - mu).transpose() / N;
137 }
138
139 // check that mean vector and calculated cov agree with expectation
140 EXPECT_NEAR((muS - mu).squaredNorm(), 0.0, 1e-2);
141 EXPECT_NEAR((covS - cov).squaredNorm(), 0.0, 5e-2);
142
143 }
144
145}
Class implementing n-dimensional random number generator from Gaussian distribution where the first c...
Class to generate normal distributed, correlated random numbers given the mean values and the covaria...
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.