eigenvalues.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2022 INRIA
3 //
4 
5 #include <iostream>
6 
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()
pinocchio::computeLargestEigenvector
void computeLargestEigenvector(const MatrixLike &mat, const Eigen::PlainObjectBase< VectorLike > &_eigenvector_est, const int max_it=10, const typename MatrixLike::Scalar rel_tol=1e-8)
Compute the lagest eigenvector of a given matrix according to a given eigenvector estimate.
Definition: eigenvalues.hpp:138
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(test_identity)
Definition: eigenvalues.cpp:21
pinocchio::retrieveLargestEigenvalue
VectorLike::Scalar retrieveLargestEigenvalue(const Eigen::MatrixBase< VectorLike > &eigenvector)
Compute the lagest eigenvalue of a given matrix. This is taking the eigenvector computed by the funct...
Definition: eigenvalues.hpp:206
simulation-contact-dynamics.A
A
Definition: simulation-contact-dynamics.py:110
eigenvalues.hpp
CppAD::max
AD< Scalar > max(const AD< Scalar > &x, const AD< Scalar > &y)
Definition: autodiff/cppad.hpp:181
pinocchio
Main pinocchio namespace.
Definition: timings.cpp:27
isApprox
bool isApprox(const Box &s1, const Box &s2, const FCL_REAL tol)


pinocchio
Author(s):
autogenerated on Fri Nov 1 2024 02:41:43