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 |
|
|
|