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

Functions

template<typename MatrixType >
bool find_pivot (typename MatrixType::Scalar tol, MatrixType &diffs, Index col=0)
 
template<typename VectorType >
void verify_is_approx_upto_permutation (const VectorType &vec1, const VectorType &vec2)
 
template<typename MatrixType >
void eigensolver (const MatrixType &m)
 
template<typename MatrixType >
void eigensolver_verify_assert (const MatrixType &m)
 
 EIGEN_DECLARE_TEST (eigensolver_complex)
 

Function Documentation

◆ EIGEN_DECLARE_TEST()

EIGEN_DECLARE_TEST ( eigensolver_complex  )
149  {
150  int s = 0;
151  for (int i = 0; i < g_repeat; i++) {
152  CALL_SUBTEST_1(eigensolver(Matrix4cf()));
153  s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
154  CALL_SUBTEST_2(eigensolver(MatrixXcd(s, s)));
155  CALL_SUBTEST_3(eigensolver(Matrix<std::complex<float>, 1, 1>()));
156  CALL_SUBTEST_4(eigensolver(Matrix3f()));
158  }
160  s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
162  CALL_SUBTEST_3(eigensolver_verify_assert(Matrix<std::complex<float>, 1, 1>()));
164 
165  // Test problem size constructors
167 
169 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
#define EIGEN_TEST_MAX_SIZE
Definition: boostmultiprec.cpp:16
Computes eigenvalues and eigenvectors of general complex matrices.
Definition: ComplexEigenSolver.h:49
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
void eigensolver_verify_assert(const MatrixType &m)
Definition: eigensolver_complex.cpp:139
void eigensolver(const MatrixType &m)
Definition: eigensolver_complex.cpp:68
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, s, TEST_SET_BUT_UNUSED_VARIABLE, and tmp.

◆ eigensolver()

template<typename MatrixType >
void eigensolver ( const MatrixType m)
68  {
69  /* this test covers the following files:
70  ComplexEigenSolver.h, and indirectly ComplexSchur.h
71  */
72  Index rows = m.rows();
73  Index cols = m.cols();
74 
75  typedef typename MatrixType::Scalar Scalar;
76  typedef typename NumTraits<Scalar>::Real RealScalar;
77 
78  MatrixType a = MatrixType::Random(rows, cols);
79  MatrixType symmA = a.adjoint() * a;
80 
82  VERIFY_IS_EQUAL(ei0.info(), Success);
83  VERIFY_IS_APPROX(symmA * ei0.eigenvectors(), ei0.eigenvectors() * ei0.eigenvalues().asDiagonal());
84 
86  VERIFY_IS_EQUAL(ei1.info(), Success);
87  VERIFY_IS_APPROX(a * ei1.eigenvectors(), ei1.eigenvectors() * ei1.eigenvalues().asDiagonal());
88  // Note: If MatrixType is real then a.eigenvalues() uses EigenSolver and thus
89  // another algorithm so results may differ slightly
90  verify_is_approx_upto_permutation(a.eigenvalues(), ei1.eigenvalues());
91 
95  VERIFY_IS_EQUAL(ei2.eigenvectors(), ei1.eigenvectors());
96  VERIFY_IS_EQUAL(ei2.eigenvalues(), ei1.eigenvalues());
97  if (rows > 2) {
98  ei2.setMaxIterations(1).compute(a);
101  }
102 
103  ComplexEigenSolver<MatrixType> eiNoEivecs(a, false);
104  VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);
105  VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());
106 
107  // Regression test for issue #66
110  VERIFY((eiz.eigenvalues().cwiseEqual(0)).all());
111 
112  MatrixType id = MatrixType::Identity(rows, cols);
113  VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));
114 
115  if (rows > 1 && rows < 20) {
116  // Test matrix with NaN
117  a(0, 0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
119  VERIFY_IS_EQUAL(eiNaN.info(), NoConvergence);
120  }
121 
122  // regression test for bug 1098
123  {
124  ComplexEigenSolver<MatrixType> eig(a.adjoint() * a);
125  eig.compute(a.adjoint() * a);
126  }
127 
128  // regression test for bug 478
129  {
130  a.setZero();
132  VERIFY_IS_EQUAL(ei3.info(), Success);
133  VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(), RealScalar(1));
134  VERIFY((ei3.eigenvectors().transpose() * ei3.eigenvectors().transpose()).eval().isIdentity());
135  }
136 }
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
SCALAR Scalar
Definition: bench_gemm.cpp:45
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
Index getMaxIterations()
Returns the maximum number of iterations.
Definition: ComplexEigenSolver.h:225
ComplexEigenSolver & compute(const EigenBase< InputType > &matrix, bool computeEigenvectors=true)
Computes eigendecomposition of given matrix.
ComplexEigenSolver & setMaxIterations(Index maxIters)
Sets the maximum number of iterations allowed.
Definition: ComplexEigenSolver.h:219
const EigenvalueType & eigenvalues() const
Returns the eigenvalues of given matrix.
Definition: ComplexEigenSolver.h:177
ComputationInfo info() const
Reports whether previous computation was successful.
Definition: ComplexEigenSolver.h:213
const EigenvectorType & eigenvectors() const
Returns the eigenvectors of given matrix.
Definition: ComplexEigenSolver.h:153
Performs a complex Schur decomposition of a real or complex square matrix.
Definition: ComplexSchur.h:56
void verify_is_approx_upto_permutation(const VectorType &vec1, const VectorType &vec2)
Definition: eigensolver_complex.cpp:50
@ Success
Definition: Constants.h:440
@ NoConvergence
Definition: Constants.h:444
#define VERIFY_IS_APPROX(a, b)
Definition: integer_types.cpp:13
const Scalar * a
Definition: level2_cplx_impl.h:32
int * m
Definition: level2_cplx_impl.h:294
#define VERIFY(a)
Definition: main.h:362
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:367
#define VERIFY_IS_MUCH_SMALLER_THAN(a, b)
Definition: main.h:371
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
double Zero
Definition: pseudosolid_node_update_elements.cc:35
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217

References a, cols, Eigen::ComplexEigenSolver< MatrixType_ >::compute(), Eigen::ComplexEigenSolver< MatrixType_ >::eigenvalues(), Eigen::ComplexEigenSolver< MatrixType_ >::eigenvectors(), Eigen::ComplexEigenSolver< MatrixType_ >::getMaxIterations(), Eigen::ComplexEigenSolver< MatrixType_ >::info(), m, Eigen::NoConvergence, rows, Eigen::ComplexEigenSolver< MatrixType_ >::setMaxIterations(), Eigen::Success, VERIFY, VERIFY_IS_APPROX, verify_is_approx_upto_permutation(), VERIFY_IS_EQUAL, VERIFY_IS_MUCH_SMALLER_THAN, and oomph::PseudoSolidHelper::Zero.

Referenced by EIGEN_DECLARE_TEST(), and main().

◆ eigensolver_verify_assert()

template<typename MatrixType >
void eigensolver_verify_assert ( const MatrixType m)
139  {
143 
144  MatrixType a = MatrixType::Random(m.rows(), m.cols());
145  eig.compute(a, false);
147 }
#define VERIFY_RAISES_ASSERT(a)
Definition: main.h:329

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

Referenced by EIGEN_DECLARE_TEST().

◆ find_pivot()

template<typename MatrixType >
bool find_pivot ( typename MatrixType::Scalar  tol,
MatrixType diffs,
Index  col = 0 
)
17  {
18  bool match = diffs.diagonal().sum() <= tol;
19  if (match || col == diffs.cols()) {
20  return match;
21  } else {
22  Index n = diffs.cols();
23  std::vector<std::pair<Index, Index> > transpositions;
24  for (Index i = col; i < n; ++i) {
25  Index best_index(0);
26  if (diffs.col(col).segment(col, n - i).minCoeff(&best_index) > tol) break;
27 
28  best_index += col;
29 
30  diffs.row(col).swap(diffs.row(best_index));
31  if (find_pivot(tol, diffs, col + 1)) return true;
32  diffs.row(col).swap(diffs.row(best_index));
33 
34  // move current pivot to the end
35  diffs.row(n - (i - col) - 1).swap(diffs.row(best_index));
36  transpositions.push_back(std::pair<Index, Index>(n - (i - col) - 1, best_index));
37  }
38  // restore
39  for (Index k = transpositions.size() - 1; k >= 0; --k)
40  diffs.row(transpositions[k].first).swap(diffs.row(transpositions[k].second));
41  }
42  return false;
43 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
m col(1)
bool find_pivot(typename MatrixType::Scalar tol, MatrixType &diffs, Index col=0)
Definition: eigensolver_complex.cpp:17
bool match(const T &xpr, std::string ref, std::string str_xpr="")
Definition: indexed_view.cpp:29
char char char int int * k
Definition: level2_impl.h:374

References col(), i, k, match(), and n.

Referenced by verify_is_approx_upto_permutation().

◆ verify_is_approx_upto_permutation()

template<typename VectorType >
void verify_is_approx_upto_permutation ( const VectorType vec1,
const VectorType vec2 
)
50  {
51  typedef typename VectorType::Scalar Scalar;
52  typedef typename NumTraits<Scalar>::Real RealScalar;
53 
54  VERIFY(vec1.cols() == 1);
55  VERIFY(vec2.cols() == 1);
56  VERIFY(vec1.rows() == vec2.rows());
57 
58  Index n = vec1.rows();
59  RealScalar tol = test_precision<RealScalar>() * test_precision<RealScalar>() *
60  numext::maxi(vec1.squaredNorm(), vec2.squaredNorm());
62  (vec1.rowwise().replicate(n) - vec2.rowwise().replicate(n).transpose()).cwiseAbs2();
63 
64  VERIFY(find_pivot(tol, diffs));
65 }
RowVectorXd vec1(3)
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T maxi(const T &x, const T &y)
Definition: MathFunctions.h:926

References find_pivot(), Eigen::numext::maxi(), n, vec1(), and VERIFY.

Referenced by eigensolver().