Line data Source code
1 : /**
2 : * Unit tests for the Linear Algebra module's Eigen class
3 : */
4 : #include <cstdlib>
5 : #include <gtest/gtest.h>
6 : #include <iostream>
7 : #include <openGPMP/linalg/eigen.hpp>
8 : #include <stdexcept>
9 : #include <vector>
10 :
11 : const double TOLERANCE = 1e-3;
12 :
13 4 : TEST(EigenTest, PowerIteration) {
14 : std::vector<std::vector<double>> squareMat = {{2.0, -1.0, 0.0},
15 : {-1.0, 2.0, -1.0},
16 6 : {0.0, -1.0, 2.0}};
17 1 : gpmp::linalg::Eigen eigenSquare(squareMat);
18 :
19 1 : double eigenvalueSquare = eigenSquare.power_iter(1000, TOLERANCE);
20 :
21 1 : EXPECT_NEAR(eigenvalueSquare, 3.414, TOLERANCE);
22 1 : }
23 :
24 4 : TEST(EigenTest, QRAlgorithm) {
25 : std::vector<std::vector<double>> squareMat = {{2.0, -1.0, 0.0},
26 : {-1.0, 2.0, -1.0},
27 6 : {0.0, -1.0, 2.0}};
28 1 : gpmp::linalg::Eigen eigenSquare(squareMat);
29 :
30 : // execute QR algorithm method
31 : std::vector<double> eigenvaluesSquare =
32 1 : eigenSquare.qr_algorithm(1000, TOLERANCE);
33 :
34 : // sort eigenvalues in ascending order for comparison
35 1 : std::sort(eigenvaluesSquare.begin(), eigenvaluesSquare.end());
36 :
37 1 : EXPECT_NEAR(eigenvaluesSquare[0], 1.069, TOLERANCE);
38 1 : EXPECT_NEAR(eigenvaluesSquare[1], 1.673, TOLERANCE);
39 1 : EXPECT_NEAR(eigenvaluesSquare[2], 2.236, TOLERANCE);
40 1 : }
41 :
42 4 : TEST(EigenTest, Determinant) {
43 : // Test square matrix
44 : std::vector<std::vector<double>> squareMat = {{2.0, -1.0, 0.0},
45 : {-1.0, 2.0, -1.0},
46 6 : {0.0, -1.0, 2.0}};
47 1 : gpmp::linalg::Eigen eigenSquare(squareMat);
48 :
49 : // execute determinant method
50 1 : double detSquare = eigenSquare.determinant();
51 :
52 : // determinant of the matrix is the product of its eigenvalues
53 1 : double expectedDetSquare = 4;
54 :
55 1 : EXPECT_NEAR(detSquare, expectedDetSquare, TOLERANCE);
56 1 : }
57 :
58 4 : TEST(EigenTest, Sensitivity) {
59 : // Test square matrix
60 : std::vector<std::vector<double>> squareMat = {{2.0, -1.0, 0.0},
61 : {-1.0, 2.0, -1.0},
62 6 : {0.0, -1.0, 2.0}};
63 1 : gpmp::linalg::Eigen eigenSquare(squareMat);
64 :
65 : // Perturbation value
66 1 : double perturbation = 1e-5;
67 :
68 : // Execute sensitivity method
69 1 : std::vector<double> sensitivity = eigenSquare.sensitivity(perturbation);
70 :
71 : // Expected sensitivity for each eigenvalue (analytically computed)
72 1 : std::vector<double> expectedSensitivity = {0.894, 0.717, 0.801};
73 :
74 : // Assert sensitivity
75 1 : ASSERT_EQ(sensitivity.size(), expectedSensitivity.size());
76 4 : for (size_t i = 0; i < sensitivity.size(); ++i) {
77 3 : EXPECT_NEAR(sensitivity[i], expectedSensitivity[i], TOLERANCE);
78 : }
79 1 : }
|