5 #ifndef __pinocchio_math_eigenvalues_hpp__
6 #define __pinocchio_math_eigenvalues_hpp__
8 #include "pinocchio/math/fwd.hpp"
16 template<
typename _Vector>
19 typedef typename PINOCCHIO_EIGEN_PLAIN_TYPE(_Vector) Vector;
20 typedef typename Vector::Scalar Scalar;
23 const Eigen::DenseIndex size,
const int max_it = 10,
const Scalar rel_tol = Scalar(1e-8))
24 : principal_eigen_vector(size)
25 , lowest_eigen_vector(size)
29 , eigen_vector_prev(size)
34 template<
typename MatrixLike>
35 void run(
const MatrixLike & mat)
37 PINOCCHIO_CHECK_INPUT_ARGUMENT(max_it >= 1);
38 PINOCCHIO_CHECK_INPUT_ARGUMENT(rel_tol > Scalar(0));
39 Scalar eigenvalue_est = principal_eigen_vector.norm();
41 for (it = 0; it < max_it; ++it)
43 const Scalar eigenvalue_est_prev = eigenvalue_est;
44 principal_eigen_vector /= eigenvalue_est;
45 eigen_vector_prev = principal_eigen_vector;
46 principal_eigen_vector.noalias() = mat * eigen_vector_prev;
48 eigenvalue_est = principal_eigen_vector.norm();
50 convergence_criteria = math::fabs(eigenvalue_est_prev - eigenvalue_est);
51 if (check_expression_if_real<Scalar, false>(
53 <= rel_tol * math::max(math::fabs(eigenvalue_est_prev), math::fabs(eigenvalue_est))))
57 largest_eigen_value = eigenvalue_est;
60 template<
typename MatrixLike,
typename VectorLike>
61 void run(
const MatrixLike & mat,
const Eigen::PlainObjectBase<VectorLike> & eigenvector_est)
63 principal_eigen_vector = eigenvector_est;
67 template<
typename MatrixLike>
68 void lowest(
const MatrixLike & mat,
const bool compute_largest =
true)
70 PINOCCHIO_CHECK_INPUT_ARGUMENT(max_it >= 1);
71 PINOCCHIO_CHECK_INPUT_ARGUMENT(rel_tol > Scalar(0));
76 Scalar eigenvalue_est = lowest_eigen_vector.norm();
78 for (it = 0; it < max_it; ++it)
80 const Scalar eigenvalue_est_prev = eigenvalue_est;
81 lowest_eigen_vector /= eigenvalue_est;
82 eigen_vector_prev = lowest_eigen_vector;
83 lowest_eigen_vector.noalias() = mat * eigen_vector_prev;
84 lowest_eigen_vector -= largest_eigen_value * eigen_vector_prev;
86 eigenvalue_est = lowest_eigen_vector.norm();
88 convergence_criteria = math::fabs(eigenvalue_est_prev - eigenvalue_est);
89 if (check_expression_if_real<Scalar, false>(
91 <= rel_tol * math::max(math::fabs(eigenvalue_est_prev), math::fabs(eigenvalue_est))))
95 lowest_eigen_value = largest_eigen_value - eigenvalue_est;
98 template<
typename MatrixLike,
typename VectorLike>
100 const MatrixLike & mat,
101 const Eigen::PlainObjectBase<VectorLike> & largest_eigenvector_est,
102 const Eigen::PlainObjectBase<VectorLike> & lowest_eigenvector_est,
103 const bool compute_largest =
true)
105 principal_eigen_vector = largest_eigenvector_est;
106 lowest_eigen_vector = lowest_eigenvector_est;
107 lowest(mat, compute_largest);
112 const Scalar normalized_value = Scalar(1) / math::sqrt(Scalar(principal_eigen_vector.size()));
113 principal_eigen_vector.fill(normalized_value);
114 lowest_eigen_vector.fill(normalized_value);
116 largest_eigen_value = std::numeric_limits<Scalar>::min();
117 lowest_eigen_value = std::numeric_limits<Scalar>::max();
120 Vector principal_eigen_vector;
121 Vector lowest_eigen_vector;
122 Scalar largest_eigen_value;
123 Scalar lowest_eigen_value;
127 Scalar convergence_criteria;
130 Vector eigen_vector_prev;
137 template<
typename MatrixLike,
typename VectorLike>
139 const MatrixLike & mat,
140 const Eigen::PlainObjectBase<VectorLike> & _eigenvector_est,
141 const int max_it = 10,
142 const typename MatrixLike::Scalar rel_tol = 1e-8)
145 algo.run(mat, _eigenvector_est.derived());
146 _eigenvector_est.const_cast_derived() = algo.principal_eigen_vector;
152 template<
typename MatrixLike>
153 Eigen::Matrix<typename MatrixLike::Scalar, MatrixLike::RowsAtCompileTime, 1>
155 const MatrixLike & mat,
const int max_it = 10,
const typename MatrixLike::Scalar rel_tol = 1e-8)
157 typedef Eigen::Matrix<typename MatrixLike::Scalar, MatrixLike::RowsAtCompileTime, 1> Vector;
160 return algo.principal_eigen_vector;
167 template<
typename MatrixLike,
typename VectorLike1,
typename VectorLike2>
169 const MatrixLike & mat,
170 const Eigen::PlainObjectBase<VectorLike1> & largest_eigenvector_est,
171 const Eigen::PlainObjectBase<VectorLike2> & lowest_eigenvector_est,
172 const bool compute_largest =
true,
173 const int max_it = 10,
174 const typename MatrixLike::Scalar rel_tol = 1e-8)
178 mat, largest_eigenvector_est.derived(), lowest_eigenvector_est.derived(), compute_largest);
179 largest_eigenvector_est.const_cast_derived() = algo.principal_eigen_vector;
180 lowest_eigenvector_est.const_cast_derived() = algo.lowest_eigen_vector;
186 template<
typename MatrixLike>
187 Eigen::Matrix<typename MatrixLike::Scalar, MatrixLike::RowsAtCompileTime, 1>
189 const MatrixLike & mat,
190 const bool compute_largest =
true,
191 const int max_it = 10,
192 const typename MatrixLike::Scalar rel_tol = 1e-8)
194 typedef Eigen::Matrix<typename MatrixLike::Scalar, MatrixLike::RowsAtCompileTime, 1> Vector;
196 algo.lowest(mat, compute_largest);
197 return algo.lowest_eigen_vector;
204 template<
typename VectorLike>
205 typename VectorLike::Scalar
208 return eigenvector.norm();
Main pinocchio namespace.
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.
void computeLowestEigenvector(const MatrixLike &mat, const Eigen::PlainObjectBase< VectorLike1 > &largest_eigenvector_est, const Eigen::PlainObjectBase< VectorLike2 > &lowest_eigenvector_est, const bool compute_largest=true, 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.
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...
Compute the largest eigenvalues and the associated principle eigenvector via power iteration.