1 // This file is part of Eigen, a lightweight C++ template library
4 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2010 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>
16 /* Check that two column vectors are approximately equal upto permutations,
17 by checking that the k-th power sums are equal for k = 1, ..., vec1.rows() */
18 template<typename VectorType
>
19 void verify_is_approx_upto_permutation(const VectorType
& vec1
, const VectorType
& vec2
)
21 typedef typename NumTraits
<typename
VectorType::Scalar
>::Real RealScalar
;
23 VERIFY(vec1
.cols() == 1);
24 VERIFY(vec2
.cols() == 1);
25 VERIFY(vec1
.rows() == vec2
.rows());
26 for (int k
= 1; k
<= vec1
.rows(); ++k
)
28 VERIFY_IS_APPROX(vec1
.array().pow(RealScalar(k
)).sum(), vec2
.array().pow(RealScalar(k
)).sum());
33 template<typename MatrixType
> void eigensolver(const MatrixType
& m
)
35 typedef typename
MatrixType::Index Index
;
36 /* this test covers the following files:
37 ComplexEigenSolver.h, and indirectly ComplexSchur.h
39 Index rows
= m
.rows();
40 Index cols
= m
.cols();
42 typedef typename
MatrixType::Scalar Scalar
;
43 typedef typename NumTraits
<Scalar
>::Real RealScalar
;
45 MatrixType a
= MatrixType::Random(rows
,cols
);
46 MatrixType symmA
= a
.adjoint() * a
;
48 ComplexEigenSolver
<MatrixType
> ei0(symmA
);
49 VERIFY_IS_EQUAL(ei0
.info(), Success
);
50 VERIFY_IS_APPROX(symmA
* ei0
.eigenvectors(), ei0
.eigenvectors() * ei0
.eigenvalues().asDiagonal());
52 ComplexEigenSolver
<MatrixType
> ei1(a
);
53 VERIFY_IS_EQUAL(ei1
.info(), Success
);
54 VERIFY_IS_APPROX(a
* ei1
.eigenvectors(), ei1
.eigenvectors() * ei1
.eigenvalues().asDiagonal());
55 // Note: If MatrixType is real then a.eigenvalues() uses EigenSolver and thus
56 // another algorithm so results may differ slightly
57 verify_is_approx_upto_permutation(a
.eigenvalues(), ei1
.eigenvalues());
59 ComplexEigenSolver
<MatrixType
> ei2
;
60 ei2
.setMaxIterations(ComplexSchur
<MatrixType
>::m_maxIterationsPerRow
* rows
).compute(a
);
61 VERIFY_IS_EQUAL(ei2
.info(), Success
);
62 VERIFY_IS_EQUAL(ei2
.eigenvectors(), ei1
.eigenvectors());
63 VERIFY_IS_EQUAL(ei2
.eigenvalues(), ei1
.eigenvalues());
65 ei2
.setMaxIterations(1).compute(a
);
66 VERIFY_IS_EQUAL(ei2
.info(), NoConvergence
);
67 VERIFY_IS_EQUAL(ei2
.getMaxIterations(), 1);
70 ComplexEigenSolver
<MatrixType
> eiNoEivecs(a
, false);
71 VERIFY_IS_EQUAL(eiNoEivecs
.info(), Success
);
72 VERIFY_IS_APPROX(ei1
.eigenvalues(), eiNoEivecs
.eigenvalues());
74 // Regression test for issue #66
75 MatrixType z
= MatrixType::Zero(rows
,cols
);
76 ComplexEigenSolver
<MatrixType
> eiz(z
);
77 VERIFY((eiz
.eigenvalues().cwiseEqual(0)).all());
79 MatrixType id
= MatrixType::Identity(rows
, cols
);
80 VERIFY_IS_APPROX(id
.operatorNorm(), RealScalar(1));
84 // Test matrix with NaN
85 a(0,0) = std::numeric_limits
<typename
MatrixType::RealScalar
>::quiet_NaN();
86 ComplexEigenSolver
<MatrixType
> eiNaN(a
);
87 VERIFY_IS_EQUAL(eiNaN
.info(), NoConvergence
);
91 template<typename MatrixType
> void eigensolver_verify_assert(const MatrixType
& m
)
93 ComplexEigenSolver
<MatrixType
> eig
;
94 VERIFY_RAISES_ASSERT(eig
.eigenvectors());
95 VERIFY_RAISES_ASSERT(eig
.eigenvalues());
97 MatrixType a
= MatrixType::Random(m
.rows(),m
.cols());
98 eig
.compute(a
, false);
99 VERIFY_RAISES_ASSERT(eig
.eigenvectors());
102 void test_eigensolver_complex()
105 for(int i
= 0; i
< g_repeat
; i
++) {
106 CALL_SUBTEST_1( eigensolver(Matrix4cf()) );
107 s
= internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
/4);
108 CALL_SUBTEST_2( eigensolver(MatrixXcd(s
,s
)) );
109 CALL_SUBTEST_3( eigensolver(Matrix
<std::complex<float>, 1, 1>()) );
110 CALL_SUBTEST_4( eigensolver(Matrix3f()) );
112 CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4cf()) );
113 s
= internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
/4);
114 CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXcd(s
,s
)) );
115 CALL_SUBTEST_3( eigensolver_verify_assert(Matrix
<std::complex<float>, 1, 1>()) );
116 CALL_SUBTEST_4( eigensolver_verify_assert(Matrix3f()) );
118 // Test problem size constructors
119 CALL_SUBTEST_5(ComplexEigenSolver
<MatrixXf
> tmp(s
));
121 TEST_SET_BUT_UNUSED_VARIABLE(s
)