Belle II Software  release-05-01-25
decorrelationMatrix.cc
1 /*************************************************************************
2 * BASF2 (Belle Analysis Framework 2) *
3 * Copyright(C) 2015 - Belle II Collaboration *
4 * *
5 * Author: The Belle II Collaboration *
6 * Contributors: Thomas Madlener *
7 * *
8 * This software is provided "as is" without any warranty. *
9 **************************************************************************/
10 
11 #include <gtest/gtest.h>
12 
13 #include <tracking/trackFindingVXD/filterTools/DecorrelationMatrix.h>
14 #include <tracking/trackFindingVXD/filterTools/DecorrelationMatrixHelper.h>
15 
16 #include <Eigen/Dense>
17 
18 #include <fstream>
19 #include <cstdio>
20 
21 using namespace std;
22 using namespace Belle2;
23 
24 namespace VXDTFFilterTest {
25 
27  using TestMatrix = Eigen::Matrix<double, 3, 3, Eigen::RowMajor>;
28 
30  const std::vector<double> v1 = {
31  0.537667139546100,
32  1.833885014595086,
33  -2.258846861003648,
34  0.862173320368121,
35  0.318765239858981,
36  -1.307688296305273,
37  -0.433592022305684,
38  0.342624466538650,
39  3.578396939725760,
40  2.769437029884877
41  };
42 
44  const std::vector<double> v2 = {
45  -1.349886940156521,
46  3.034923466331855,
47  0.725404224946106,
48  -0.063054873189656,
49  0.714742903826096,
50  -0.204966058299775,
51  -0.124144348216312,
52  1.489697607785465,
53  1.409034489800479,
54  1.417192413429614
55  };
56 
58  const std::vector<double> v3 = {
59  0.671497133608080,
60  -1.207486922685038,
61  0.717238651328838,
62  1.630235289164729,
63  0.488893770311789,
64  1.034693009917860,
65  0.726885133383238,
66  -0.303440924786016,
67  0.293871467096658,
68  -0.787282803758638
69  };
70 
72  class DecorrelationMatrixTest : public ::testing::Test {
73  protected:
79  virtual void SetUp()
80  {
81  m_testData = {{v1, v2, v3}};
82 
83  TestMatrix tmpMatrix;
84  // cpp check does not like commas
85  tmpMatrix << 3.132492133948475, 0.974827954209597, -0.761264020048923,
86  0.974827954209597, 1.486186070946439, -0.840189849104485,
87  // cppcheck-suppress constStatement
88  -0.761264020048923, -0.840189849104485, 0.739017883637750;
89 
90  // MATLAB calculates the empirical covariance matrix with a prefactor (n-1)^-1, but we do with a prefactor of n^-1 so this has
91  // to be corrected (n=3 in the test cases)
92  m_covMatrix = (double)(v3.size() - 1) / (double)v3.size() * tmpMatrix;
93  }
94 
96  std::array<std::vector<double>, 3> m_testData;
97 
100 
102  TestMatrix m_identity = TestMatrix::Identity();
103  };
104 
107  {
108  EXPECT_EQ(3, m_testData.size());
109  for (const auto& vec : m_testData) { EXPECT_EQ(10, vec.size()); }
110  }
111 
113  TEST_F(DecorrelationMatrixTest, TestConstructor)
114  {
115  DecorrelationMatrix<3> matrix{};
116  const auto& internalMatrix = matrix.getMatrix();
117 
118  for (auto i = 0; i < internalMatrix.outerSize(); ++i) {
119  for (auto j = 0; j < internalMatrix.innerSize(); ++j) {
120  EXPECT_DOUBLE_EQ(m_identity(i, j), internalMatrix(i, j));
121  }
122  }
123  }
124 
126  TEST_F(DecorrelationMatrixTest, TestCalculateDecorrMatrix)
127  {
128  DecorrelationMatrix<3> matrix{};
129  matrix.calculateDecorrMatrix(m_testData);
130 
131  // test that the size of the input and the output vector does not change
132  std::vector<double> testVec = { m_testData[0][0], m_testData[1][0], m_testData[2][0] };
133  auto outputVec = matrix.decorrelate(testVec);
134  EXPECT_EQ(testVec.size(), outputVec.size());
135 
136  // test that the covariance matrix of the decorrelated test data is indeed the identity (at least numerically)
137  auto outputData = matrix.decorrelate(m_testData);
138  auto covMat = calculateCovMatrix(outputData);
139  for (auto i = 0; i < covMat.outerSize(); ++i) {
140  for (auto j = 0; j < covMat.innerSize(); ++j) {
141  if (i == j) {
142  EXPECT_FLOAT_EQ(m_identity(i, j), covMat(i, j)); // the diagonal should be ones, even with considering numerics
143  } else {
144  EXPECT_NEAR(m_identity(i, j), covMat(i, j), 1e-15); // EXPECT_FLOAT_EQ is to stringent for the numerical calculations
145  }
146  }
147  }
148 
149  // COULDDO: test non-normalized version as well
150  }
151 
153  TEST_F(DecorrelationMatrixTest, TestCaluclateCovMatrix)
154  {
155  // test if the correct covariance matrix gets calculated
156  const TestMatrix covMat = calculateCovMatrix(m_testData);
157  EXPECT_EQ(covMat.outerSize(), 3);
158  EXPECT_EQ(covMat.innerSize(), 3);
159  for (auto i = 0; i < covMat.outerSize(); ++i) {
160  for (auto j = 0; j < covMat.innerSize(); ++j) {
161  EXPECT_DOUBLE_EQ(m_covMatrix(i, j), covMat(i, j));
162  }
163  }
164 
165  // check if an identity matrix is returned if the input is incorrect
166  auto badTestData = m_testData;
167  badTestData[0].erase(badTestData[0].begin()); // remove first element from the first vector in the array
168  const TestMatrix badMat = calculateCovMatrix(badTestData);
169  EXPECT_EQ(3, badMat.outerSize());
170  EXPECT_EQ(3, badMat.innerSize());
171  EXPECT_TRUE(badMat == m_identity);
172  }
173 
177  TEST_F(DecorrelationMatrixTest, TestDecorrelationMatrixIO)
178  {
179  const char* filename = "tmp_matrix_testoutput.dat";
180 
181  ofstream ofs(filename);
182  DecorrelationMatrix<3> covMatrix(m_covMatrix);
183  ofs << covMatrix.print() << std::endl;
184  ofs.close();
185 
186  ifstream ifs(filename);
187  DecorrelationMatrix<3> inMatrix{};
188  EXPECT_TRUE(inMatrix.readFromStream(ifs));
189  ifs.close();
190 
191  const TestMatrix& inMat = inMatrix.getMatrix();
192  for (auto i = 0; i < m_covMatrix.outerSize(); ++i) {
193  for (auto j = 0; j < m_covMatrix.innerSize(); ++j) {
194  EXPECT_DOUBLE_EQ(m_covMatrix(i, j), inMat(i, j));
195  }
196  }
197 
198  ASSERT_EQ(0, remove(filename)); // assert that the temporarily created file gets deleted again
199  }
200 }
Belle2::DecorrelationMatrix
Class holding a Matrix that can be used to decorrelate input data to Machine Learning classifiers.
Definition: DecorrelationMatrix.h:46
Belle2::DecorrelationMatrix::print
std::string print() const
print the matrix to a string.
Definition: DecorrelationMatrix.h:171
VXDTFFilterTest::v2
const std::vector< double > v2
MATLAB generated random vector.
Definition: decorrelationMatrix.cc:44
VXDTFFilterTest::TestMatrix
Eigen::Matrix< double, 3, 3, Eigen::RowMajor > TestMatrix
typedef for less typing effort
Definition: decorrelationMatrix.cc:27
VXDTFFilterTest::DecorrelationMatrixTest::m_covMatrix
TestMatrix m_covMatrix
covariance matrix of the data as calculated via MATLAB
Definition: decorrelationMatrix.cc:99
VXDTFFilterTest::v3
const std::vector< double > v3
MATLAB generated random vector.
Definition: decorrelationMatrix.cc:58
VXDTFFilterTest::v1
const std::vector< double > v1
MATLAB generated random vector.
Definition: decorrelationMatrix.cc:30
VXDTFFilterTest::DecorrelationMatrixTest
Test Class.
Definition: decorrelationMatrix.cc:72
VXDTFFilterTest::DecorrelationMatrixTest::m_testData
std::array< std::vector< double >, 3 > m_testData
data that is used in the tests
Definition: decorrelationMatrix.cc:96
VXDTFFilterTest
helper struct for testing purposes providing the necessary coordinate accessors NOTE: this is only te...
Definition: TestSpacePoint.h:6
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TEST_F
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:65
Belle2::DecorrelationMatrix::calculateDecorrMatrix
void calculateDecorrMatrix(std::array< std::vector< double >, Ndims > inputData, bool normalise=true)
calculate the transformation matrix that when applied to the input data yields linearly uncorrelated ...
Definition: DecorrelationMatrix.h:108
Belle2::calculateCovMatrix
const Eigen::Matrix< double, Ndims, Ndims, Eigen::RowMajor > calculateCovMatrix(std::array< std::vector< double >, Ndims > inputData)
calculates the empirical covariance matrix from the inputData.
Definition: DecorrelationMatrixHelper.h:47
VXDTFFilterTest::DecorrelationMatrixTest::SetUp
virtual void SetUp()
Fills the data into the internal data structure that is used for testing.
Definition: decorrelationMatrix.cc:79