1 // This file is part of Eigen, a lightweight C++ template library
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
13 #include <Eigen/Eigenvalues>
15 template<typename MatrixType
> void eigensolver(const MatrixType
& m
)
17 typedef typename
MatrixType::Index Index
;
18 /* this test covers the following files:
21 Index rows
= m
.rows();
22 Index cols
= m
.cols();
24 typedef typename
MatrixType::Scalar Scalar
;
25 typedef typename NumTraits
<Scalar
>::Real RealScalar
;
26 typedef Matrix
<RealScalar
, MatrixType::RowsAtCompileTime
, 1> RealVectorType
;
27 typedef typename
std::complex<typename NumTraits
<typename
MatrixType::Scalar
>::Real
> Complex
;
29 MatrixType a
= MatrixType::Random(rows
,cols
);
30 MatrixType a1
= MatrixType::Random(rows
,cols
);
31 MatrixType symmA
= a
.adjoint() * a
+ a1
.adjoint() * a1
;
33 EigenSolver
<MatrixType
> ei0(symmA
);
34 VERIFY_IS_EQUAL(ei0
.info(), Success
);
35 VERIFY_IS_APPROX(symmA
* ei0
.pseudoEigenvectors(), ei0
.pseudoEigenvectors() * ei0
.pseudoEigenvalueMatrix());
36 VERIFY_IS_APPROX((symmA
.template cast
<Complex
>()) * (ei0
.pseudoEigenvectors().template cast
<Complex
>()),
37 (ei0
.pseudoEigenvectors().template cast
<Complex
>()) * (ei0
.eigenvalues().asDiagonal()));
39 EigenSolver
<MatrixType
> ei1(a
);
40 VERIFY_IS_EQUAL(ei1
.info(), Success
);
41 VERIFY_IS_APPROX(a
* ei1
.pseudoEigenvectors(), ei1
.pseudoEigenvectors() * ei1
.pseudoEigenvalueMatrix());
42 VERIFY_IS_APPROX(a
.template cast
<Complex
>() * ei1
.eigenvectors(),
43 ei1
.eigenvectors() * ei1
.eigenvalues().asDiagonal());
44 VERIFY_IS_APPROX(ei1
.eigenvectors().colwise().norm(), RealVectorType::Ones(rows
).transpose());
45 VERIFY_IS_APPROX(a
.eigenvalues(), ei1
.eigenvalues());
47 EigenSolver
<MatrixType
> ei2
;
48 ei2
.setMaxIterations(RealSchur
<MatrixType
>::m_maxIterationsPerRow
* rows
).compute(a
);
49 VERIFY_IS_EQUAL(ei2
.info(), Success
);
50 VERIFY_IS_EQUAL(ei2
.eigenvectors(), ei1
.eigenvectors());
51 VERIFY_IS_EQUAL(ei2
.eigenvalues(), ei1
.eigenvalues());
53 ei2
.setMaxIterations(1).compute(a
);
54 VERIFY_IS_EQUAL(ei2
.info(), NoConvergence
);
55 VERIFY_IS_EQUAL(ei2
.getMaxIterations(), 1);
58 EigenSolver
<MatrixType
> eiNoEivecs(a
, false);
59 VERIFY_IS_EQUAL(eiNoEivecs
.info(), Success
);
60 VERIFY_IS_APPROX(ei1
.eigenvalues(), eiNoEivecs
.eigenvalues());
61 VERIFY_IS_APPROX(ei1
.pseudoEigenvalueMatrix(), eiNoEivecs
.pseudoEigenvalueMatrix());
63 MatrixType id
= MatrixType::Identity(rows
, cols
);
64 VERIFY_IS_APPROX(id
.operatorNorm(), RealScalar(1));
68 // Test matrix with NaN
69 a(0,0) = std::numeric_limits
<typename
MatrixType::RealScalar
>::quiet_NaN();
70 EigenSolver
<MatrixType
> eiNaN(a
);
71 VERIFY_IS_EQUAL(eiNaN
.info(), NoConvergence
);
75 template<typename MatrixType
> void eigensolver_verify_assert(const MatrixType
& m
)
77 EigenSolver
<MatrixType
> eig
;
78 VERIFY_RAISES_ASSERT(eig
.eigenvectors());
79 VERIFY_RAISES_ASSERT(eig
.pseudoEigenvectors());
80 VERIFY_RAISES_ASSERT(eig
.pseudoEigenvalueMatrix());
81 VERIFY_RAISES_ASSERT(eig
.eigenvalues());
83 MatrixType a
= MatrixType::Random(m
.rows(),m
.cols());
84 eig
.compute(a
, false);
85 VERIFY_RAISES_ASSERT(eig
.eigenvectors());
86 VERIFY_RAISES_ASSERT(eig
.pseudoEigenvectors());
89 void test_eigensolver_generic()
92 for(int i
= 0; i
< g_repeat
; i
++) {
93 CALL_SUBTEST_1( eigensolver(Matrix4f()) );
94 s
= internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
/4);
95 CALL_SUBTEST_2( eigensolver(MatrixXd(s
,s
)) );
97 // some trivial but implementation-wise tricky cases
98 CALL_SUBTEST_2( eigensolver(MatrixXd(1,1)) );
99 CALL_SUBTEST_2( eigensolver(MatrixXd(2,2)) );
100 CALL_SUBTEST_3( eigensolver(Matrix
<double,1,1>()) );
101 CALL_SUBTEST_4( eigensolver(Matrix2d()) );
104 CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4f()) );
105 s
= internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
/4);
106 CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXd(s
,s
)) );
107 CALL_SUBTEST_3( eigensolver_verify_assert(Matrix
<double,1,1>()) );
108 CALL_SUBTEST_4( eigensolver_verify_assert(Matrix2d()) );
110 // Test problem size constructors
111 CALL_SUBTEST_5(EigenSolver
<MatrixXf
> tmp(s
));
113 // regression test for bug 410
117 A(0,0) = std::sqrt(-1.);
118 Eigen::EigenSolver
<MatrixXd
> solver(A
);
120 V(0,0) = solver
.eigenvectors()(0,0).real();
124 TEST_SET_BUT_UNUSED_VARIABLE(s
)