// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk> // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
template<typename MatrixType> void eigensolver(const MatrixType& m)
{ /* this test covers the following files: EigenSolver.h
*/
Index rows = m.rows();
Index cols = m.cols();
template<int> void eigensolver_generic_extra()
{
{ // regression test for bug 793
MatrixXd a(3,3);
a << 0, 0, 1,
1, 1, 1,
1, 1e+200, 1;
Eigen::EigenSolver<MatrixXd> eig(a); double scale = 1e-200; // scale to avoid overflow during the comparisons
VERIFY_IS_APPROX(a * eig.pseudoEigenvectors()*scale, eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix()*scale);
VERIFY_IS_APPROX(a * eig.eigenvectors()*scale, eig.eigenvectors() * eig.eigenvalues().asDiagonal()*scale);
}
{ // check a case where all eigenvalues are null.
MatrixXd a(2,2);
a << 1, 1,
-1, -1;
Eigen::EigenSolver<MatrixXd> eig(a);
VERIFY_IS_APPROX(eig.pseudoEigenvectors().squaredNorm(), 2.);
VERIFY_IS_APPROX((a * eig.pseudoEigenvectors()).norm()+1., 1.);
VERIFY_IS_APPROX((eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix()).norm()+1., 1.);
VERIFY_IS_APPROX((a * eig.eigenvectors()).norm()+1., 1.);
VERIFY_IS_APPROX((eig.eigenvectors() * eig.eigenvalues().asDiagonal()).norm()+1., 1.);
}
// regression test for bug 933
{
{
VectorXd coeffs(5); coeffs << 1, -3, -175, -225, 2250;
MatrixXd C = make_companion(coeffs);
EigenSolver<MatrixXd> eig(C);
CALL_SUBTEST( check_eigensolver_for_given_mat(eig,C) );
}
{ // this test is tricky because it requires high accuracy in smallest eigenvalues
VectorXd coeffs(5); coeffs << 6.154671e-15, -1.003870e-10, -9.819570e-01, 3.995715e+03, 2.211511e+08;
MatrixXd C = make_companion(coeffs);
EigenSolver<MatrixXd> eig(C);
CALL_SUBTEST( check_eigensolver_for_given_mat(eig,C) );
Index n = C.rows(); for(Index i=0;i<n;++i)
{ typedef std::complex<double> Complex;
MatrixXcd ac = C.cast<Complex>();
ac.diagonal().array() -= eig.eigenvalues()(i);
VectorXd sv = ac.jacobiSvd().singularValues(); // comparing to sv(0) is not enough here to catch the "bug", // the hard-coded 1.0 is important!
VERIFY_IS_MUCH_SMALLER_THAN(sv(n-1), 1.0);
}
}
} // regression test for bug 1557
{ // this test is interesting because it contains zeros on the diagonal.
MatrixXd A_bug1557(3,3);
A_bug1557 << 0, 0, 0, 1, 0, 0.5887907064808635127, 0, 1, 0;
EigenSolver<MatrixXd> eig(A_bug1557);
CALL_SUBTEST( check_eigensolver_for_given_mat(eig,A_bug1557) );
}
EIGEN_DECLARE_TEST(eigensolver_generic)
{ int s = 0; for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( eigensolver(Matrix4f()) );
s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
CALL_SUBTEST_2( eigensolver(MatrixXd(s,s)) );
TEST_SET_BUT_UNUSED_VARIABLE(s)
// some trivial but implementation-wise tricky cases
CALL_SUBTEST_2( eigensolver(MatrixXd(1,1)) );
CALL_SUBTEST_2( eigensolver(MatrixXd(2,2)) );
CALL_SUBTEST_3( eigensolver(Matrix<double,1,1>()) );
CALL_SUBTEST_4( eigensolver(Matrix2d()) );
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.