ComplexEigenSolver.h
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) 2009 Claire Maurice
5 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
6 // Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
7 //
8 // This Source Code Form is subject to the terms of the Mozilla
9 // Public License v. 2.0. If a copy of the MPL was not distributed
10 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 
12 #ifndef EIGEN_COMPLEX_EIGEN_SOLVER_H
13 #define EIGEN_COMPLEX_EIGEN_SOLVER_H
14 
15 #include "./ComplexSchur.h"
16 
17 // IWYU pragma: private
18 #include "./InternalHeaderCheck.h"
19 
20 namespace Eigen {
21 
48 template <typename MatrixType_>
50  public:
52  typedef MatrixType_ MatrixType;
53 
54  enum {
55  RowsAtCompileTime = MatrixType::RowsAtCompileTime,
56  ColsAtCompileTime = MatrixType::ColsAtCompileTime,
58  MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
59  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
60  };
61 
63  typedef typename MatrixType::Scalar Scalar;
65  typedef Eigen::Index Index;
66 
73  typedef std::complex<RealScalar> ComplexScalar;
74 
81 
90 
97  : m_eivec(), m_eivalues(), m_schur(), m_isInitialized(false), m_eigenvectorsOk(false), m_matX() {}
98 
106  : m_eivec(size, size),
107  m_eivalues(size),
108  m_schur(size),
109  m_isInitialized(false),
110  m_eigenvectorsOk(false),
111  m_matX(size, size) {}
112 
122  template <typename InputType>
123  explicit ComplexEigenSolver(const EigenBase<InputType>& matrix, bool computeEigenvectors = true)
124  : m_eivec(matrix.rows(), matrix.cols()),
126  m_schur(matrix.rows()),
127  m_isInitialized(false),
128  m_eigenvectorsOk(false),
129  m_matX(matrix.rows(), matrix.cols()) {
130  compute(matrix.derived(), computeEigenvectors);
131  }
132 
153  const EigenvectorType& eigenvectors() const {
154  eigen_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
155  eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
156  return m_eivec;
157  }
158 
177  const EigenvalueType& eigenvalues() const {
178  eigen_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
179  return m_eivalues;
180  }
181 
206  template <typename InputType>
207  ComplexEigenSolver& compute(const EigenBase<InputType>& matrix, bool computeEigenvectors = true);
208 
214  eigen_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
215  return m_schur.info();
216  }
217 
220  m_schur.setMaxIterations(maxIters);
221  return *this;
222  }
223 
226 
227  protected:
229 
236 
237  private:
238  void doComputeEigenvectors(RealScalar matrixnorm);
239  void sortEigenvalues(bool computeEigenvectors);
240 };
241 
242 template <typename MatrixType>
243 template <typename InputType>
245  bool computeEigenvectors) {
246  // this code is inspired from Jampack
247  eigen_assert(matrix.cols() == matrix.rows());
248 
249  // Do a complex Schur decomposition, A = U T U^*
250  // The eigenvalues are on the diagonal of T.
251  m_schur.compute(matrix.derived(), computeEigenvectors);
252 
253  if (m_schur.info() == Success) {
254  m_eivalues = m_schur.matrixT().diagonal();
255  if (computeEigenvectors) doComputeEigenvectors(m_schur.matrixT().norm());
256  sortEigenvalues(computeEigenvectors);
257  }
258 
259  m_isInitialized = true;
260  m_eigenvectorsOk = computeEigenvectors;
261  return *this;
262 }
263 
264 template <typename MatrixType>
266  const Index n = m_eivalues.size();
267 
268  matrixnorm = numext::maxi(matrixnorm, (std::numeric_limits<RealScalar>::min)());
269 
270  // Compute X such that T = X D X^(-1), where D is the diagonal of T.
271  // The matrix X is unit triangular.
273  for (Index k = n - 1; k >= 0; k--) {
274  m_matX.coeffRef(k, k) = ComplexScalar(1.0, 0.0);
275  // Compute X(i,k) using the (i,k) entry of the equation X T = D X
276  for (Index i = k - 1; i >= 0; i--) {
277  m_matX.coeffRef(i, k) = -m_schur.matrixT().coeff(i, k);
278  if (k - i - 1 > 0)
279  m_matX.coeffRef(i, k) -=
280  (m_schur.matrixT().row(i).segment(i + 1, k - i - 1) * m_matX.col(k).segment(i + 1, k - i - 1)).value();
282  if (z == ComplexScalar(0)) {
283  // If the i-th and k-th eigenvalue are equal, then z equals 0.
284  // Use a small value instead, to prevent division by zero.
286  }
287  m_matX.coeffRef(i, k) = m_matX.coeff(i, k) / z;
288  }
289  }
290 
291  // Compute V as V = U X; now A = U T U^* = U X D X^(-1) U^* = V D V^(-1)
292  m_eivec.noalias() = m_schur.matrixU() * m_matX;
293  // .. and normalize the eigenvectors
294  for (Index k = 0; k < n; k++) {
295  m_eivec.col(k).stableNormalize();
296  }
297 }
298 
299 template <typename MatrixType>
300 void ComplexEigenSolver<MatrixType>::sortEigenvalues(bool computeEigenvectors) {
301  const Index n = m_eivalues.size();
302  for (Index i = 0; i < n; i++) {
303  Index k;
304  m_eivalues.cwiseAbs().tail(n - i).minCoeff(&k);
305  if (k != 0) {
306  k += i;
308  if (computeEigenvectors) m_eivec.col(i).swap(m_eivec.col(k));
309  }
310  }
311 }
312 
313 } // end namespace Eigen
314 
315 #endif // EIGEN_COMPLEX_EIGEN_SOLVER_H
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
#define eigen_assert(x)
Definition: Macros.h:910
#define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE)
Definition: StaticAssert.h:74
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
Computes eigenvalues and eigenvectors of general complex matrices.
Definition: ComplexEigenSolver.h:49
EigenvectorType m_matX
Definition: ComplexEigenSolver.h:235
EigenvectorType m_eivec
Definition: ComplexEigenSolver.h:230
ComplexSchur< MatrixType > m_schur
Definition: ComplexEigenSolver.h:232
@ MaxColsAtCompileTime
Definition: ComplexEigenSolver.h:59
@ Options
Definition: ComplexEigenSolver.h:57
@ ColsAtCompileTime
Definition: ComplexEigenSolver.h:56
@ RowsAtCompileTime
Definition: ComplexEigenSolver.h:55
@ MaxRowsAtCompileTime
Definition: ComplexEigenSolver.h:58
std::complex< RealScalar > ComplexScalar
Complex scalar type for MatrixType.
Definition: ComplexEigenSolver.h:73
ComplexEigenSolver(Index size)
Default Constructor with memory preallocation.
Definition: ComplexEigenSolver.h:105
Index getMaxIterations()
Returns the maximum number of iterations.
Definition: ComplexEigenSolver.h:225
ComplexEigenSolver()
Default constructor.
Definition: ComplexEigenSolver.h:96
MatrixType::Scalar Scalar
Scalar type for matrices of type MatrixType.
Definition: ComplexEigenSolver.h:63
ComplexEigenSolver(const EigenBase< InputType > &matrix, bool computeEigenvectors=true)
Constructor; computes eigendecomposition of given matrix.
Definition: ComplexEigenSolver.h:123
ComplexEigenSolver & compute(const EigenBase< InputType > &matrix, bool computeEigenvectors=true)
Computes eigendecomposition of given matrix.
Eigen::Index Index
Definition: ComplexEigenSolver.h:65
Matrix< ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime > EigenvectorType
Type for matrix of eigenvectors as returned by eigenvectors().
Definition: ComplexEigenSolver.h:89
void sortEigenvalues(bool computeEigenvectors)
Definition: ComplexEigenSolver.h:300
bool m_isInitialized
Definition: ComplexEigenSolver.h:233
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
MatrixType_ MatrixType
Synonym for the template parameter MatrixType_.
Definition: ComplexEigenSolver.h:52
NumTraits< Scalar >::Real RealScalar
Definition: ComplexEigenSolver.h:64
bool m_eigenvectorsOk
Definition: ComplexEigenSolver.h:234
void doComputeEigenvectors(RealScalar matrixnorm)
Definition: ComplexEigenSolver.h:265
ComputationInfo info() const
Reports whether previous computation was successful.
Definition: ComplexEigenSolver.h:213
EigenvalueType m_eivalues
Definition: ComplexEigenSolver.h:231
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
ComputationInfo info() const
Reports whether previous computation was successful.
Definition: ComplexSchur.h:220
const ComplexMatrixType & matrixU() const
Returns the unitary matrix in the Schur decomposition.
Definition: ComplexSchur.h:142
const ComplexMatrixType & matrixT() const
Returns the triangular matrix in the Schur decomposition.
Definition: ComplexSchur.h:165
Index getMaxIterations()
Returns the maximum number of iterations.
Definition: ComplexSchur.h:236
ComplexSchur & setMaxIterations(Index maxIters)
Sets the maximum number of iterations allowed.
Definition: ComplexSchur.h:230
ComplexSchur & compute(const EigenBase< InputType > &matrix, bool computeU=true)
Computes Schur decomposition of given matrix.
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
Definition: PlainObjectBase.h:217
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
Definition: PlainObjectBase.h:198
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(DenseBase< OtherDerived > &other)
Override DenseBase::swap() since for dynamic-sized matrices of same type it is enough to swap the dat...
Definition: PlainObjectBase.h:898
Eigen::Map< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor >, 0, Eigen::OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: common.h:85
#define min(a, b)
Definition: datatypes.h:22
ComputationInfo
Definition: Constants.h:438
@ Success
Definition: Constants.h:440
@ RowMajor
Definition: Constants.h:320
EIGEN_BLAS_FUNC() swap(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:117
char char char int int * k
Definition: level2_impl.h:374
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T maxi(const T &x, const T &y)
Definition: MathFunctions.h:926
EIGEN_DEVICE_FUNC internal::add_const_on_value_type_t< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar)> real_ref(const Scalar &x)
Definition: MathFunctions.h:1051
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
squared absolute value
Definition: GlobalFunctions.h:87
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
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43
Definition: EigenBase.h:33
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
Definition: ForwardDeclarations.h:21