Eigen  3.4.90 (git rev 5a9f66fb35d03a4da9ef8976e67a61b30aa16dcf)
 
Loading...
Searching...
No Matches
ComplexEigenSolver.h
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 <[email protected]>
6// Copyright (C) 2010,2012 Jitse Niesen <[email protected]>
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
20namespace Eigen {
21
48template <typename MatrixType_>
50 public:
52 typedef MatrixType_ MatrixType;
53
54 enum {
55 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
56 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
57 Options = internal::traits<MatrixType>::Options,
58 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
59 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
60 };
61
63 typedef typename MatrixType::Scalar Scalar;
64 typedef typename NumTraits<Scalar>::Real RealScalar;
66
73 typedef std::complex<RealScalar> ComplexScalar;
74
80 typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options & (~RowMajor), MaxColsAtCompileTime, 1> EigenvalueType;
81
87 typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime,
88 MaxColsAtCompileTime>
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()),
125 m_eivalues(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
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
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:
228 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
229
230 EigenvectorType m_eivec;
231 EigenvalueType m_eivalues;
233 bool m_isInitialized;
234 bool m_eigenvectorsOk;
235 EigenvectorType m_matX;
236
237 private:
238 void doComputeEigenvectors(RealScalar matrixnorm);
239 void sortEigenvalues(bool computeEigenvectors);
240};
241
242template <typename MatrixType>
243template <typename InputType>
244ComplexEigenSolver<MatrixType>& ComplexEigenSolver<MatrixType>::compute(const EigenBase<InputType>& matrix,
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
264template <typename MatrixType>
265void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(RealScalar matrixnorm) {
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.
272 m_matX = EigenvectorType::Zero(n, n);
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();
281 ComplexScalar z = m_schur.matrixT().coeff(i, i) - m_schur.matrixT().coeff(k, k);
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.
285 numext::real_ref(z) = NumTraits<RealScalar>::epsilon() * matrixnorm;
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
299template <typename MatrixType>
300void 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;
307 std::swap(m_eivalues[k], m_eivalues[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
Computes eigenvalues and eigenvectors of general complex matrices.
Definition ComplexEigenSolver.h:49
ComplexEigenSolver & compute(const EigenBase< InputType > &matrix, bool computeEigenvectors=true)
Computes eigendecomposition of given matrix.
std::complex< RealScalar > ComplexScalar
Complex scalar type for MatrixType.
Definition ComplexEigenSolver.h:73
Matrix< ComplexScalar, ColsAtCompileTime, 1, Options &(~RowMajor), MaxColsAtCompileTime, 1 > EigenvalueType
Type for vector of eigenvalues as returned by eigenvalues().
Definition ComplexEigenSolver.h:80
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 & setMaxIterations(Index maxIters)
Sets the maximum number of iterations allowed.
Definition ComplexEigenSolver.h:219
ComplexEigenSolver(const EigenBase< InputType > &matrix, bool computeEigenvectors=true)
Constructor; computes eigendecomposition of given matrix.
Definition ComplexEigenSolver.h:123
const EigenvectorType & eigenvectors() const
Returns the eigenvectors of given matrix.
Definition ComplexEigenSolver.h:153
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
MatrixType_ MatrixType
Synonym for the template parameter MatrixType_.
Definition ComplexEigenSolver.h:52
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
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
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
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:186
ComputationInfo
Definition Constants.h:438
Namespace containing all symbols from the Eigen library.
Definition Core:137
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:83
Definition EigenBase.h:33
Derived & derived()
Definition EigenBase.h:49