eigensolver_generic.cpp
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
6 //
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/.
10 
11 #include "main.h"
12 #include <limits>
13 #include <Eigen/Eigenvalues>
14 
15 template<typename EigType,typename MatType>
16 void check_eigensolver_for_given_mat(const EigType &eig, const MatType& a)
17 {
20  typedef typename std::complex<RealScalar> Complex;
21  Index n = a.rows();
22  VERIFY_IS_EQUAL(eig.info(), Success);
23  VERIFY_IS_APPROX(a * eig.pseudoEigenvectors(), eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix());
24  VERIFY_IS_APPROX(a.template cast<Complex>() * eig.eigenvectors(),
25  eig.eigenvectors() * eig.eigenvalues().asDiagonal());
26  VERIFY_IS_APPROX(eig.eigenvectors().colwise().norm(), RealVectorType::Ones(n).transpose());
27  VERIFY_IS_APPROX(a.eigenvalues(), eig.eigenvalues());
28 }
29 
30 template<typename MatrixType> void eigensolver(const MatrixType& m)
31 {
32  /* this test covers the following files:
33  EigenSolver.h
34  */
35  Index rows = m.rows();
36  Index cols = m.cols();
37 
38  typedef typename MatrixType::Scalar Scalar;
39  typedef typename NumTraits<Scalar>::Real RealScalar;
40  typedef typename std::complex<RealScalar> Complex;
41 
42  MatrixType a = MatrixType::Random(rows,cols);
43  MatrixType a1 = MatrixType::Random(rows,cols);
44  MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;
45 
46  EigenSolver<MatrixType> ei0(symmA);
49  VERIFY_IS_APPROX((symmA.template cast<Complex>()) * (ei0.pseudoEigenvectors().template cast<Complex>()),
50  (ei0.pseudoEigenvectors().template cast<Complex>()) * (ei0.eigenvalues().asDiagonal()));
51 
54 
60  if (rows > 2) {
61  ei2.setMaxIterations(1).compute(a);
64  }
65 
66  EigenSolver<MatrixType> eiNoEivecs(a, false);
67  VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);
68  VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());
69  VERIFY_IS_APPROX(ei1.pseudoEigenvalueMatrix(), eiNoEivecs.pseudoEigenvalueMatrix());
70 
71  MatrixType id = MatrixType::Identity(rows, cols);
72  VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));
73 
74  if (rows > 2 && rows < 20)
75  {
76  // Test matrix with NaN
77  a(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
78  EigenSolver<MatrixType> eiNaN(a);
80  }
81 
82  // regression test for bug 1098
83  {
84  EigenSolver<MatrixType> eig(a.adjoint() * a);
85  eig.compute(a.adjoint() * a);
86  }
87 
88  // regression test for bug 478
89  {
90  a.setZero();
94  VERIFY((ei3.eigenvectors().transpose()*ei3.eigenvectors().transpose()).eval().isIdentity());
95  }
96 }
97 
98 template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m)
99 {
105 
106  MatrixType a = MatrixType::Random(m.rows(),m.cols());
107  eig.compute(a, false);
110 }
111 
112 
113 template<typename CoeffType>
115 make_companion(const CoeffType& coeffs)
116 {
117  Index n = coeffs.size()-1;
119  res.setZero();
120  res.row(0) = -coeffs.tail(n) / coeffs(0);
121  res.diagonal(-1).setOnes();
122  return res;
123 }
124 
125 template<int>
127 {
128  {
129  // regression test for bug 793
130  MatrixXd a(3,3);
131  a << 0, 0, 1,
132  1, 1, 1,
133  1, 1e+200, 1;
135  double scale = 1e-200; // scale to avoid overflow during the comparisons
137  VERIFY_IS_APPROX(a * eig.eigenvectors()*scale, eig.eigenvectors() * eig.eigenvalues().asDiagonal()*scale);
138  }
139  {
140  // check a case where all eigenvalues are null.
141  MatrixXd a(2,2);
142  a << 1, 1,
143  -1, -1;
145  VERIFY_IS_APPROX(eig.pseudoEigenvectors().squaredNorm(), 2.);
146  VERIFY_IS_APPROX((a * eig.pseudoEigenvectors()).norm()+1., 1.);
147  VERIFY_IS_APPROX((eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix()).norm()+1., 1.);
148  VERIFY_IS_APPROX((a * eig.eigenvectors()).norm()+1., 1.);
149  VERIFY_IS_APPROX((eig.eigenvectors() * eig.eigenvalues().asDiagonal()).norm()+1., 1.);
150  }
151 
152  // regression test for bug 933
153  {
154  {
155  VectorXd coeffs(5); coeffs << 1, -3, -175, -225, 2250;
156  MatrixXd C = make_companion(coeffs);
159  }
160  {
161  // this test is tricky because it requires high accuracy in smallest eigenvalues
162  VectorXd coeffs(5); coeffs << 6.154671e-15, -1.003870e-10, -9.819570e-01, 3.995715e+03, 2.211511e+08;
163  MatrixXd C = make_companion(coeffs);
166  Index n = C.rows();
167  for(Index i=0;i<n;++i)
168  {
169  typedef std::complex<double> Complex;
170  MatrixXcd ac = C.cast<Complex>();
171  ac.diagonal().array() -= eig.eigenvalues()(i);
172  VectorXd sv = ac.jacobiSvd().singularValues();
173  // comparing to sv(0) is not enough here to catch the "bug",
174  // the hard-coded 1.0 is important!
175  VERIFY_IS_MUCH_SMALLER_THAN(sv(n-1), 1.0);
176  }
177  }
178  }
179  // regression test for bug 1557
180  {
181  // this test is interesting because it contains zeros on the diagonal.
182  MatrixXd A_bug1557(3,3);
183  A_bug1557 << 0, 0, 0, 1, 0, 0.5887907064808635127, 0, 1, 0;
184  EigenSolver<MatrixXd> eig(A_bug1557);
186  }
187 
188  // regression test for bug 1174
189  {
190  Index n = 12;
191  MatrixXf A_bug1174(n,n);
192  A_bug1174 << 262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0, 786432,
193  262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0, 786432,
194  262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0, 786432,
195  262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0, 786432,
196  0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0,
197  0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0,
198  0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0,
199  0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0,
200  0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0,
201  0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0,
202  0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0,
203  0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0;
204  EigenSolver<MatrixXf> eig(A_bug1174);
206  }
207 }
208 
209 EIGEN_DECLARE_TEST(eigensolver_generic)
210 {
211  int s = 0;
212  for(int i = 0; i < g_repeat; i++) {
213  CALL_SUBTEST_1( eigensolver(Matrix4f()) );
214  s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
215  CALL_SUBTEST_2( eigensolver(MatrixXd(s,s)) );
217 
218  // some trivial but implementation-wise tricky cases
219  CALL_SUBTEST_2( eigensolver(MatrixXd(1,1)) );
220  CALL_SUBTEST_2( eigensolver(MatrixXd(2,2)) );
222  CALL_SUBTEST_4( eigensolver(Matrix2d()) );
223  }
224 
226  s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
227  CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXd(s,s)) );
230 
231  // Test problem size constructors
233 
234  // regression test for bug 410
236  {
237  MatrixXd A(1,1);
238  A(0,0) = std::sqrt(-1.); // is Not-a-Number
241  }
242  );
243 
244  CALL_SUBTEST_2( eigensolver_generic_extra<0>() );
245 
247 }
Point2 a1
Definition: testPose2.cpp:769
Matrix3f m
MatrixType pseudoEigenvalueMatrix() const
Returns the block-diagonal matrix in the pseudo-eigendecomposition.
Definition: EigenSolver.h:324
SCALAR Scalar
Definition: bench_gemm.cpp:46
#define VERIFY_RAISES_ASSERT(a)
Definition: main.h:340
const MatrixType & pseudoEigenvectors() const
Returns the pseudo-eigenvectors of given matrix.
Definition: EigenSolver.h:199
#define CALL_SUBTEST_4(FUNC)
EIGEN_DEVICE_FUNC Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > & setZero(Index size)
EigenSolver & compute(const EigenBase< InputType > &matrix, bool computeEigenvectors=true)
Computes eigendecomposition of given matrix.
#define VERIFY_IS_NOT_EQUAL(a, b)
Definition: main.h:387
void eigensolver_verify_assert(const MatrixType &m)
Performs a real Schur decomposition of a square matrix.
Definition: RealSchur.h:54
#define CALL_SUBTEST_3(FUNC)
int n
MatrixXf MatrixType
BiCGSTAB< SparseMatrix< double > > solver
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:232
Index getMaxIterations()
Returns the maximum number of iterations.
Definition: EigenSolver.h:295
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:48
EIGEN_DEVICE_FUNC Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > & setOnes(Index size)
std::complex< RealScalar > Complex
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
#define VERIFY_IS_APPROX(a, b)
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:386
#define CALL_SUBTEST_1(FUNC)
ComputationInfo info() const
Definition: EigenSolver.h:281
static int g_repeat
Definition: main.h:169
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
EIGEN_DECLARE_TEST(eigensolver_generic)
SelfAdjointEigenSolver< PlainMatrixType > eig(mat, computeVectors?ComputeEigenvectors:EigenvaluesOnly)
Array< double, 1, 3 > e(1./3., 0.5, 2.)
RealScalar s
EigenSolver & setMaxIterations(Index maxIters)
Sets the maximum number of iterations allowed.
Definition: EigenSolver.h:288
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:47
#define VERIFY_IS_MUCH_SMALLER_THAN(a, b)
Definition: main.h:390
Matrix< Scalar, Dynamic, Dynamic > C
Definition: bench_gemm.cpp:50
EigenvectorsType eigenvectors() const
Returns the eigenvectors of given matrix.
Definition: EigenSolver.h:345
#define TEST_SET_BUT_UNUSED_VARIABLE(X)
Definition: main.h:121
#define CALL_SUBTEST_5(FUNC)
#define CALL_SUBTEST(FUNC)
Definition: main.h:399
Matrix< typename CoeffType::Scalar, Dynamic, Dynamic > make_companion(const CoeffType &coeffs)
#define VERIFY(a)
Definition: main.h:380
#define EIGEN_TEST_MAX_SIZE
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics scale
#define CALL_SUBTEST_2(FUNC)
internal::nested_eval< T, 1 >::type eval(const T &xpr)
Jet< T, N > sqrt(const Jet< T, N > &f)
Definition: jet.h:418
const EigenvalueType & eigenvalues() const
Returns the eigenvalues of given matrix.
Definition: EigenSolver.h:244
Computes eigenvalues and eigenvectors of general matrices.
Definition: EigenSolver.h:64
The matrix class, also used for vectors and row-vectors.
void check_eigensolver_for_given_mat(const EigType &eig, const MatType &a)
void eigensolver(const MatrixType &m)
void eigensolver_generic_extra()


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:12