eigensolver_generic.cpp File Reference
#include "main.h"
#include <limits>
#include <Eigen/Eigenvalues>

Functions

template<typename EigType , typename MatType >
void check_eigensolver_for_given_mat (const EigType &eig, const MatType &a)
 
template<typename MatrixType >
void eigensolver (const MatrixType &m)
 
template<typename MatrixType >
void eigensolver_verify_assert (const MatrixType &m)
 
template<typename CoeffType >
Matrix< typename CoeffType::Scalar, Dynamic, Dynamic > make_companion (const CoeffType &coeffs)
 
template<int >
void eigensolver_generic_extra ()
 
 EIGEN_DECLARE_TEST (eigensolver_generic)
 

Function Documentation

◆ check_eigensolver_for_given_mat()

template<typename EigType , typename MatType >
void check_eigensolver_for_given_mat ( const EigType &  eig,
const MatType &  a 
)
16  {
19  typedef typename std::complex<RealScalar> Complex;
20  Index n = a.rows();
21  VERIFY_IS_EQUAL(eig.info(), Success);
22  VERIFY_IS_APPROX(a * eig.pseudoEigenvectors(), eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix());
23  VERIFY_IS_APPROX(a.template cast<Complex>() * eig.eigenvectors(),
24  eig.eigenvectors() * eig.eigenvalues().asDiagonal());
25  VERIFY_IS_APPROX(eig.eigenvectors().colwise().norm(), RealVectorType::Ones(n).transpose());
26  VERIFY_IS_APPROX(a.eigenvalues(), eig.eigenvalues());
27 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
std::complex< RealScalar > Complex
Definition: common.h:71
@ Success
Definition: Constants.h:440
#define VERIFY_IS_APPROX(a, b)
Definition: integer_types.cpp:13
const Scalar * a
Definition: level2_cplx_impl.h:32
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:367
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217

References a, n, Eigen::Success, VERIFY_IS_APPROX, and VERIFY_IS_EQUAL.

Referenced by eigensolver(), and eigensolver_generic_extra().

◆ EIGEN_DECLARE_TEST()

EIGEN_DECLARE_TEST ( eigensolver_generic  )
198  {
199  int s = 0;
200  for (int i = 0; i < g_repeat; i++) {
201  CALL_SUBTEST_1(eigensolver(Matrix4f()));
202  s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
203  CALL_SUBTEST_2(eigensolver(MatrixXd(s, s)));
205 
206  // some trivial but implementation-wise tricky cases
207  CALL_SUBTEST_2(eigensolver(MatrixXd(1, 1)));
208  CALL_SUBTEST_2(eigensolver(MatrixXd(2, 2)));
210  CALL_SUBTEST_4(eigensolver(Matrix2d()));
211  }
212 
214  s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
218 
219  // Test problem size constructors
221 
222  // regression test for bug 410
224  MatrixXd A(1, 1);
225  A(0, 0) = std::sqrt(-1.); // is Not-a-Number
228  });
229 
230  CALL_SUBTEST_2(eigensolver_generic_extra<0>());
231 
233 }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
BiCGSTAB< SparseMatrix< double > > solver
Definition: BiCGSTAB_simple.cpp:5
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:47
#define EIGEN_TEST_MAX_SIZE
Definition: boostmultiprec.cpp:16
Computes eigenvalues and eigenvectors of general matrices.
Definition: EigenSolver.h:68
void eigensolver_verify_assert(const MatrixType &m)
Definition: eigensolver_generic.cpp:97
void eigensolver(const MatrixType &m)
Definition: eigensolver_generic.cpp:30
@ NumericalIssue
Definition: Constants.h:442
RealScalar s
Definition: level1_cplx_impl.h:130
Eigen::Matrix< Scalar, Dynamic, Dynamic, ColMajor > tmp
Definition: level3_impl.h:365
#define TEST_SET_BUT_UNUSED_VARIABLE(X)
Definition: main.h:139
static int g_repeat
Definition: main.h:191
#define CALL_SUBTEST_3(FUNC)
Definition: split_test_helper.h:16
#define CALL_SUBTEST_1(FUNC)
Definition: split_test_helper.h:4
#define CALL_SUBTEST_5(FUNC)
Definition: split_test_helper.h:28
#define CALL_SUBTEST_2(FUNC)
Definition: split_test_helper.h:10
#define CALL_SUBTEST_4(FUNC)
Definition: split_test_helper.h:22

References CALL_SUBTEST_1, CALL_SUBTEST_2, CALL_SUBTEST_3, CALL_SUBTEST_4, CALL_SUBTEST_5, EIGEN_TEST_MAX_SIZE, eigensolver(), eigensolver_verify_assert(), Eigen::g_repeat, i, Eigen::NumericalIssue, s, solver, sqrt(), TEST_SET_BUT_UNUSED_VARIABLE, tmp, and VERIFY_IS_EQUAL.

◆ eigensolver()

template<typename MatrixType >
void eigensolver ( const MatrixType m)
30  {
31  /* this test covers the following files:
32  EigenSolver.h
33  */
34  Index rows = m.rows();
35  Index cols = m.cols();
36 
37  typedef typename MatrixType::Scalar Scalar;
38  typedef typename NumTraits<Scalar>::Real RealScalar;
39  typedef typename std::complex<RealScalar> Complex;
40 
41  MatrixType a = MatrixType::Random(rows, cols);
42  MatrixType a1 = MatrixType::Random(rows, cols);
43  MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;
44 
45  EigenSolver<MatrixType> ei0(symmA);
46  VERIFY_IS_EQUAL(ei0.info(), Success);
47  VERIFY_IS_APPROX(symmA * ei0.pseudoEigenvectors(), ei0.pseudoEigenvectors() * ei0.pseudoEigenvalueMatrix());
48  VERIFY_IS_APPROX((symmA.template cast<Complex>()) * (ei0.pseudoEigenvectors().template cast<Complex>()),
49  (ei0.pseudoEigenvectors().template cast<Complex>()) * (ei0.eigenvalues().asDiagonal()));
50 
53 
57  VERIFY_IS_EQUAL(ei2.eigenvectors(), ei1.eigenvectors());
58  VERIFY_IS_EQUAL(ei2.eigenvalues(), ei1.eigenvalues());
59  if (rows > 2) {
60  ei2.setMaxIterations(1).compute(a);
63  }
64 
65  EigenSolver<MatrixType> eiNoEivecs(a, false);
66  VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);
67  VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());
68  VERIFY_IS_APPROX(ei1.pseudoEigenvalueMatrix(), eiNoEivecs.pseudoEigenvalueMatrix());
69 
70  MatrixType id = MatrixType::Identity(rows, cols);
71  VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));
72 
73  if (rows > 2 && rows < 20) {
74  // Test matrix with NaN
75  a(0, 0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
77  VERIFY_IS_NOT_EQUAL(eiNaN.info(), Success);
78  }
79 
80  // regression test for bug 1098
81  {
82  EigenSolver<MatrixType> eig(a.adjoint() * a);
83  eig.compute(a.adjoint() * a);
84  }
85 
86  // regression test for bug 478
87  {
88  a.setZero();
90  VERIFY_IS_EQUAL(ei3.info(), Success);
91  VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(), RealScalar(1));
92  VERIFY((ei3.eigenvectors().transpose() * ei3.eigenvectors().transpose()).eval().isIdentity());
93  }
94 }
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
SCALAR Scalar
Definition: bench_gemm.cpp:45
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
const EigenvalueType & eigenvalues() const
Returns the eigenvalues of given matrix.
Definition: EigenSolver.h:246
ComputationInfo info() const
Definition: EigenSolver.h:283
EigenSolver & setMaxIterations(Index maxIters)
Sets the maximum number of iterations allowed.
Definition: EigenSolver.h:289
EigenvectorsType eigenvectors() const
Returns the eigenvectors of given matrix.
Definition: EigenSolver.h:344
EigenSolver & compute(const EigenBase< InputType > &matrix, bool computeEigenvectors=true)
Computes eigendecomposition of given matrix.
Index getMaxIterations()
Returns the maximum number of iterations.
Definition: EigenSolver.h:295
Performs a real Schur decomposition of a square matrix.
Definition: RealSchur.h:58
void check_eigensolver_for_given_mat(const EigType &eig, const MatType &a)
Definition: eigensolver_generic.cpp:16
@ NoConvergence
Definition: Constants.h:444
int * m
Definition: level2_cplx_impl.h:294
#define VERIFY_IS_NOT_EQUAL(a, b)
Definition: main.h:368
#define VERIFY(a)
Definition: main.h:362
#define CALL_SUBTEST(FUNC)
Definition: main.h:382
#define VERIFY_IS_MUCH_SMALLER_THAN(a, b)
Definition: main.h:371

References a, CALL_SUBTEST, check_eigensolver_for_given_mat(), cols, Eigen::EigenSolver< MatrixType_ >::compute(), Eigen::EigenSolver< MatrixType_ >::eigenvalues(), Eigen::EigenSolver< MatrixType_ >::eigenvectors(), Eigen::EigenSolver< MatrixType_ >::getMaxIterations(), Eigen::EigenSolver< MatrixType_ >::info(), m, Eigen::NoConvergence, Eigen::EigenSolver< MatrixType_ >::pseudoEigenvalueMatrix(), Eigen::EigenSolver< MatrixType_ >::pseudoEigenvectors(), rows, Eigen::EigenSolver< MatrixType_ >::setMaxIterations(), Eigen::Success, VERIFY, VERIFY_IS_APPROX, VERIFY_IS_EQUAL, VERIFY_IS_MUCH_SMALLER_THAN, and VERIFY_IS_NOT_EQUAL.

Referenced by EIGEN_DECLARE_TEST().

◆ eigensolver_generic_extra()

template<int >
void eigensolver_generic_extra ( )
121  {
122  {
123  // regression test for bug 793
124  MatrixXd a(3, 3);
125  a << 0, 0, 1, 1, 1, 1, 1, 1e+200, 1;
127  double scale = 1e-200; // scale to avoid overflow during the comparisons
128  VERIFY_IS_APPROX(a * eig.pseudoEigenvectors() * scale,
129  eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix() * scale);
130  VERIFY_IS_APPROX(a * eig.eigenvectors() * scale, eig.eigenvectors() * eig.eigenvalues().asDiagonal() * scale);
131  }
132  {
133  // check a case where all eigenvalues are null.
134  MatrixXd a(2, 2);
135  a << 1, 1, -1, -1;
137  VERIFY_IS_APPROX(eig.pseudoEigenvectors().squaredNorm(), 2.);
138  VERIFY_IS_APPROX((a * eig.pseudoEigenvectors()).norm() + 1., 1.);
139  VERIFY_IS_APPROX((eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix()).norm() + 1., 1.);
140  VERIFY_IS_APPROX((a * eig.eigenvectors()).norm() + 1., 1.);
141  VERIFY_IS_APPROX((eig.eigenvectors() * eig.eigenvalues().asDiagonal()).norm() + 1., 1.);
142  }
143 
144  // regression test for bug 933
145  {
146  {
147  VectorXd coeffs(5);
148  coeffs << 1, -3, -175, -225, 2250;
149  MatrixXd C = make_companion(coeffs);
152  }
153  {
154  // this test is tricky because it requires high accuracy in smallest eigenvalues
155  VectorXd coeffs(5);
156  coeffs << 6.154671e-15, -1.003870e-10, -9.819570e-01, 3.995715e+03, 2.211511e+08;
157  MatrixXd C = make_companion(coeffs);
160  Index n = C.rows();
161  for (Index i = 0; i < n; ++i) {
162  typedef std::complex<double> Complex;
163  MatrixXcd ac = C.cast<Complex>();
164  ac.diagonal().array() -= eig.eigenvalues()(i);
165  VectorXd sv = ac.jacobiSvd().singularValues();
166  // comparing to sv(0) is not enough here to catch the "bug",
167  // the hard-coded 1.0 is important!
168  VERIFY_IS_MUCH_SMALLER_THAN(sv(n - 1), 1.0);
169  }
170  }
171  }
172  // regression test for bug 1557
173  {
174  // this test is interesting because it contains zeros on the diagonal.
175  MatrixXd A_bug1557(3, 3);
176  A_bug1557 << 0, 0, 0, 1, 0, 0.5887907064808635127, 0, 1, 0;
177  EigenSolver<MatrixXd> eig(A_bug1557);
179  }
180 
181  // regression test for bug 1174
182  {
183  Index n = 12;
184  MatrixXf A_bug1174(n, n);
185  A_bug1174 << 262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0, 786432, 262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0,
186  786432, 262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0, 786432, 262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0,
187  786432, 0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0, 0, 262144, 262144, 0, 0,
188  262144, 262144, 262144, 262144, 262144, 262144, 0, 0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144,
189  262144, 262144, 0, 0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0, 0, 262144,
190  262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0, 0, 262144, 262144, 0, 0, 262144, 262144,
191  262144, 262144, 262144, 262144, 0, 0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0,
192  0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0;
193  EigenSolver<MatrixXf> eig(A_bug1174);
195  }
196 }
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Definition: matrices.h:74
Matrix< typename CoeffType::Scalar, Dynamic, Dynamic > make_companion(const CoeffType &coeffs)
Definition: eigensolver_generic.cpp:111

References a, CALL_SUBTEST, check_eigensolver_for_given_mat(), e(), Eigen::EigenSolver< MatrixType_ >::eigenvalues(), Eigen::EigenSolver< MatrixType_ >::eigenvectors(), i, make_companion(), n, Eigen::EigenSolver< MatrixType_ >::pseudoEigenvalueMatrix(), Eigen::EigenSolver< MatrixType_ >::pseudoEigenvectors(), VERIFY_IS_APPROX, and VERIFY_IS_MUCH_SMALLER_THAN.

◆ eigensolver_verify_assert()

template<typename MatrixType >
void eigensolver_verify_assert ( const MatrixType m)
97  {
103 
104  MatrixType a = MatrixType::Random(m.rows(), m.cols());
105  eig.compute(a, false);
108 }
MatrixType pseudoEigenvalueMatrix() const
Returns the block-diagonal matrix in the pseudo-eigendecomposition.
Definition: EigenSolver.h:319
const MatrixType & pseudoEigenvectors() const
Returns the pseudo-eigenvectors of given matrix.
Definition: EigenSolver.h:202
#define VERIFY_RAISES_ASSERT(a)
Definition: main.h:329

References a, Eigen::EigenSolver< MatrixType_ >::compute(), Eigen::EigenSolver< MatrixType_ >::eigenvalues(), Eigen::EigenSolver< MatrixType_ >::eigenvectors(), m, Eigen::EigenSolver< MatrixType_ >::pseudoEigenvalueMatrix(), Eigen::EigenSolver< MatrixType_ >::pseudoEigenvectors(), and VERIFY_RAISES_ASSERT.

Referenced by EIGEN_DECLARE_TEST().

◆ make_companion()

template<typename CoeffType >
Matrix<typename CoeffType::Scalar, Dynamic, Dynamic> make_companion ( const CoeffType &  coeffs)
111  {
112  Index n = coeffs.size() - 1;
114  res.setZero();
115  res.row(0) = -coeffs.tail(n) / coeffs(0);
116  res.diagonal(-1).setOnes();
117  return res;
118 }
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3

References n, and res.

Referenced by eigensolver_generic_extra().