12#ifndef EIGEN_GENERALIZEDEIGENSOLVER_H
13#define EIGEN_GENERALIZEDEIGENSOLVER_H
18#include "./InternalHeaderCheck.h"
61template <
typename MatrixType_>
68 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
69 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
70 Options = internal::traits<MatrixType>::Options,
71 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
72 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
76 typedef typename MatrixType::Scalar
Scalar;
77 typedef typename NumTraits<Scalar>::Real RealScalar;
112 typedef Matrix<
ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime,
113 MaxColsAtCompileTime>
124 : m_eivec(), m_alphas(), m_betas(), m_computeEigenvectors(false), m_isInitialized(false), m_realQZ() {}
133 : m_eivec(size, size),
136 m_computeEigenvectors(false),
137 m_isInitialized(false),
154 : m_eivec(A.rows(), A.cols()),
157 m_computeEigenvectors(false),
158 m_isInitialized(false),
161 compute(A, B, computeEigenvectors);
177 eigen_assert(info() ==
Success &&
"GeneralizedEigenSolver failed to compute eigenvectors");
178 eigen_assert(m_computeEigenvectors &&
"Eigenvectors for GeneralizedEigenSolver were not calculated");
201 eigen_assert(info() ==
Success &&
"GeneralizedEigenSolver failed to compute eigenvalues.");
211 eigen_assert(info() ==
Success &&
"GeneralizedEigenSolver failed to compute alphas.");
221 eigen_assert(info() ==
Success &&
"GeneralizedEigenSolver failed to compute betas.");
251 eigen_assert(m_isInitialized &&
"EigenSolver is not initialized.");
252 return m_realQZ.
info();
263 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
269 bool m_computeEigenvectors;
270 bool m_isInitialized;
275template <
typename MatrixType>
278 bool computeEigenvectors) {
281 eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
282 Index size = A.cols();
285 m_realQZ.compute(A, B, computeEigenvectors);
286 if (m_realQZ.info() ==
Success) {
288 m_alphas.resize(size);
289 m_betas.resize(size);
290 if (computeEigenvectors) {
291 m_eivec.resize(size, size);
303 if (i == size - 1 || mS.coeff(i + 1, i) ==
Scalar(0)) {
305 m_alphas.
coeffRef(i) = mS.diagonal().coeff(i);
306 m_betas.coeffRef(i) = mT.diagonal().coeff(i);
307 if (computeEigenvectors) {
308 v.setConstant(
Scalar(0.0));
309 v.coeffRef(i) =
Scalar(1.0);
311 if (abs(m_betas.coeffRef(i)) >= (std::numeric_limits<RealScalar>::min)()) {
313 const Scalar alpha =
real(m_alphas.coeffRef(i));
314 const Scalar beta = m_betas.coeffRef(i);
315 for (
Index j = i - 1; j >= 0; j--) {
316 const Index st = j + 1;
317 const Index sz = i - j;
318 if (j > 0 && mS.coeff(j, j - 1) !=
Scalar(0)) {
321 beta * mS.template block<2, Dynamic>(j - 1, st, 2, sz))
322 .lazyProduct(v.segment(st, sz));
324 beta * mS.template block<2, 2>(j - 1, j - 1) - alpha * mT.template block<2, 2>(j - 1, j - 1);
325 v.template segment<2>(j - 1) = lhs.partialPivLu().solve(rhs);
328 v.coeffRef(j) = -v.segment(st, sz)
330 .cwiseProduct(beta * mS.block(j, st, 1, sz) - alpha * mT.block(j, st, 1, sz))
332 (beta * mS.coeffRef(j, j) - alpha * mT.coeffRef(j, j));
336 m_eivec.col(i).real().noalias() = m_realQZ.matrixZ().transpose() * v;
337 m_eivec.col(i).real().normalize();
338 m_eivec.col(i).imag().setConstant(0);
348 RealScalar a = mT.diagonal().coeff(i), b = mT.diagonal().coeff(i + 1);
349 const RealScalar beta = m_betas.coeffRef(i) = m_betas.coeffRef(i + 1) = a * b;
357 m_alphas.coeffRef(i) =
conj(alpha);
358 m_alphas.coeffRef(i + 1) = alpha;
360 if (computeEigenvectors) {
365 cv.
coeffRef(i) = -(
static_cast<Scalar>(beta * mS.coeffRef(i, i + 1)) - alpha * mT.coeffRef(i, i + 1)) /
366 (
static_cast<Scalar>(beta * mS.coeffRef(i, i)) - alpha * mT.coeffRef(i, i));
367 for (
Index j = i - 1; j >= 0; j--) {
368 const Index st = j + 1;
369 const Index sz = i + 1 - j;
370 if (j > 0 && mS.coeff(j, j - 1) !=
Scalar(0)) {
373 beta * mS.template block<2, Dynamic>(j - 1, st, 2, sz))
374 .lazyProduct(cv.segment(st, sz));
376 beta * mS.template block<2, 2>(j - 1, j - 1) - alpha * mT.template block<2, 2>(j - 1, j - 1);
377 cv.template segment<2>(j - 1) = lhs.partialPivLu().solve(rhs);
382 .cwiseProduct(beta * mS.block(j, st, 1, sz) - alpha * mT.block(j, st, 1, sz))
384 (alpha * mT.coeffRef(j, j) -
static_cast<Scalar>(beta * mS.coeffRef(j, j)));
387 m_eivec.col(i + 1).noalias() = (m_realQZ.matrixZ().transpose() * cv);
388 m_eivec.col(i + 1).normalize();
389 m_eivec.col(i) = m_eivec.col(i + 1).conjugate();
395 m_computeEigenvectors = computeEigenvectors;
396 m_isInitialized =
true;
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition CwiseBinaryOp.h:79
Computes the generalized eigenvalues and eigenvectors of a pair of general matrices.
Definition GeneralizedEigenSolver.h:62
CwiseBinaryOp< internal::scalar_quotient_op< ComplexScalar, Scalar >, ComplexVectorType, VectorType > EigenvalueType
Expression type for the eigenvalues as returned by eigenvalues().
Definition GeneralizedEigenSolver.h:105
GeneralizedEigenSolver & compute(const MatrixType &A, const MatrixType &B, bool computeEigenvectors=true)
Computes generalized eigendecomposition of given matrix.
Definition GeneralizedEigenSolver.h:276
const VectorType & betas() const
Definition GeneralizedEigenSolver.h:220
std::complex< RealScalar > ComplexScalar
Complex scalar type for MatrixType.
Definition GeneralizedEigenSolver.h:86
Matrix< ComplexScalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > ComplexVectorType
Type for vector of complex scalar values eigenvalues as returned by alphas().
Definition GeneralizedEigenSolver.h:100
Matrix< Scalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > VectorType
Type for vector of real scalar values eigenvalues as returned by betas().
Definition GeneralizedEigenSolver.h:93
MatrixType::Scalar Scalar
Scalar type for matrices of type MatrixType.
Definition GeneralizedEigenSolver.h:76
GeneralizedEigenSolver()
Default constructor.
Definition GeneralizedEigenSolver.h:123
const ComplexVectorType & alphas() const
Definition GeneralizedEigenSolver.h:210
Eigen::Index Index
Definition GeneralizedEigenSolver.h:78
GeneralizedEigenSolver(const MatrixType &A, const MatrixType &B, bool computeEigenvectors=true)
Constructor; computes the generalized eigendecomposition of given matrix pair.
Definition GeneralizedEigenSolver.h:153
EigenvalueType eigenvalues() const
Returns an expression of the computed generalized eigenvalues.
Definition GeneralizedEigenSolver.h:200
GeneralizedEigenSolver(Index size)
Default constructor with memory preallocation.
Definition GeneralizedEigenSolver.h:132
GeneralizedEigenSolver & setMaxIterations(Index maxIters)
Definition GeneralizedEigenSolver.h:257
Matrix< ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime > EigenvectorsType
Type for matrix of eigenvectors as returned by eigenvectors().
Definition GeneralizedEigenSolver.h:114
MatrixType_ MatrixType
Synonym for the template parameter MatrixType_.
Definition GeneralizedEigenSolver.h:65
A matrix or vector expression mapping an existing array of data.
Definition Map.h:96
const DiagonalWrapper< const Derived > asDiagonal() const
Definition DiagonalMatrix.h:344
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:186
constexpr Scalar & coeffRef(Index rowId, Index colId)
Definition PlainObjectBase.h:217
constexpr const Scalar & coeff(Index rowId, Index colId) const
Definition PlainObjectBase.h:198
Derived & setZero(Index size)
Definition CwiseNullaryOp.h:563
Performs a real QZ decomposition of a pair of square matrices.
Definition RealQZ.h:61
ComputationInfo info() const
Reports whether previous computation was successful.
Definition RealQZ.h:170
RealQZ & setMaxIterations(Index maxIters)
Definition RealQZ.h:185
ComputationInfo
Definition Constants.h:438
@ Success
Definition Constants.h:440
Namespace containing all symbols from the Eigen library.
Definition Core:137
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_real_op< typename Derived::Scalar >, const Derived > real(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
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 Meta.h:523