GCC Code Coverage Report


Directory: ./
File: unittest/eigenvalues.cpp
Date: 2024-08-27 18:20:05
Exec Total Coverage
Lines: 0 38 0.0%
Branches: 0 284 0.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2022 INRIA
3 //
4
5 #include <iostream>
6
7 #include <pinocchio/math/eigenvalues.hpp>
8
9 #include <boost/variant.hpp> // to avoid C99 warnings
10
11 #include <boost/test/unit_test.hpp>
12 #include <boost/utility/binary.hpp>
13
14 #include <Eigen/Eigenvalues>
15 #include <algorithm>
16
17 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
18
19 using namespace pinocchio;
20
21 BOOST_AUTO_TEST_CASE(test_identity)
22 {
23 const Eigen::DenseIndex mat_size = 20;
24 const Eigen::MatrixXd identity_mat = Eigen::MatrixXd::Identity(mat_size, mat_size);
25
26 auto eigen_vec = computeLargestEigenvector(identity_mat);
27 auto eigen_val = retrieveLargestEigenvalue(eigen_vec);
28 BOOST_CHECK(std::fabs(eigen_val - 1.) <= 1e-4);
29 }
30
31 BOOST_AUTO_TEST_CASE(test_random_matrix)
32 {
33 const Eigen::DenseIndex mat_size = 10;
34 const int num_tests = 1000;
35 const int num_it_max = 10;
36 const int num_it_max_finer = 100 * num_it_max;
37
38 for (int k = 0; k < num_tests; ++k)
39 {
40 const Eigen::MatrixXd A = Eigen::MatrixXd::Random(mat_size, mat_size);
41 const Eigen::MatrixXd sym_mat = (A * A.transpose());
42
43 const Eigen::EigenSolver<Eigen::MatrixXd> eigen_solver(sym_mat, true);
44 BOOST_CHECK(eigen_solver.info() == Eigen::Success);
45
46 // Sort eigenvalues
47 Eigen::VectorXd sorted_eigen_values = eigen_solver.eigenvalues().real();
48 std::sort(sorted_eigen_values.data(), sorted_eigen_values.data() + sorted_eigen_values.size());
49
50 const double eigen_val_ref = sorted_eigen_values[sorted_eigen_values.size() - 1];
51
52 auto eigen_vec = computeLargestEigenvector(sym_mat, num_it_max);
53 auto eigen_val = retrieveLargestEigenvalue(eigen_vec);
54
55 bool test_relative_eigen_val =
56 std::fabs(eigen_val - eigen_val_ref) / (std::max)(eigen_val, eigen_val_ref) <= 1e-2;
57 bool test_eigen_vec = (sym_mat * eigen_vec).isApprox(eigen_val * eigen_vec, 1e-2);
58
59 if (!test_relative_eigen_val || !test_eigen_vec)
60 {
61 auto eigen_vec_finer = computeLargestEigenvector(sym_mat, num_it_max_finer);
62 auto eigen_val_finer = retrieveLargestEigenvalue(eigen_vec_finer);
63
64 test_relative_eigen_val =
65 std::fabs(eigen_val_finer - eigen_val_ref) / (std::max)(eigen_val_finer, eigen_val_ref)
66 <= 1e-2;
67 test_eigen_vec =
68 (sym_mat * eigen_vec_finer).isApprox(eigen_val_finer * eigen_vec_finer, 1e-2);
69 std::cout << "res: " << (sym_mat * eigen_vec - eigen_val * eigen_vec).norm() << std::endl;
70 std::cout << "eigen_val: " << eigen_val << std::endl;
71 std::cout << "eigen_val_finer: " << eigen_val_finer << std::endl;
72 std::cout << "eigen_val_ref: " << eigen_val_ref << std::endl;
73 std::cout << "res finer: "
74 << (sym_mat * eigen_vec_finer - eigen_val_finer * eigen_vec_finer).norm()
75 << std::endl;
76 }
77 BOOST_CHECK(test_relative_eigen_val);
78 BOOST_CHECK(test_eigen_vec);
79 }
80 }
81
82 BOOST_AUTO_TEST_SUITE_END()
83