13#ifndef EIGEN_GENERALIZEDEIGENSOLVER_H
14#define EIGEN_GENERALIZEDEIGENSOLVER_H
19#include "./InternalHeaderCheck.h"
62template <
typename MatrixType_>
69 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
70 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
71 Options = internal::plain_object_options<MatrixType>::value,
72 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
73 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
77 using Scalar =
typename MatrixType::Scalar;
78 using RealScalar =
typename NumTraits<Scalar>::Real;
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),
153 template <
typename InputTypeA,
typename InputTypeB>
155 bool computeEigenvectors =
true)
156 : m_eivec(A.rows(), A.cols()),
159 m_computeEigenvectors(false),
160 m_isInitialized(false),
161 m_realQZ(A.derived(), B.derived(), computeEigenvectors),
163 computeFromQZ(computeEigenvectors);
177 template <
typename InputTypeA,
typename InputTypeB>
179 : m_eivec(A.rows(), A.cols()),
182 m_computeEigenvectors(false),
183 m_isInitialized(false),
184 m_realQZ(A.derived(), B.derived(), computeEigenvectors),
186 computeFromQZ(computeEigenvectors);
202 eigen_assert(info() ==
Success &&
"GeneralizedEigenSolver failed to compute eigenvectors");
203 eigen_assert(m_computeEigenvectors &&
"Eigenvectors for GeneralizedEigenSolver were not calculated");
226 eigen_assert(info() ==
Success &&
"GeneralizedEigenSolver failed to compute eigenvalues.");
236 eigen_assert(info() ==
Success &&
"GeneralizedEigenSolver failed to compute alphas.");
246 eigen_assert(info() ==
Success &&
"GeneralizedEigenSolver failed to compute betas.");
273 template <
typename InputTypeA,
typename InputTypeB>
275 bool computeEigenvectors =
true);
278 eigen_assert(m_isInitialized &&
"EigenSolver is not initialized.");
279 return m_realQZ.info();
290 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
291 EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL)
296 bool m_computeEigenvectors;
297 bool m_isInitialized;
305template <
typename MatrixType>
306template <
typename InputTypeA,
typename InputTypeB>
308 const EigenBase<InputTypeB>& B,
309 bool computeEigenvectors) {
310 eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
313 m_realQZ.compute(A.derived(), B.derived(), computeEigenvectors);
314 return computeFromQZ(computeEigenvectors);
319template <
typename MatrixType>
321 const Index size = m_realQZ.matrixS().cols();
322 if (m_realQZ.info() ==
Success) {
324 m_alphas.resize(size);
325 m_betas.resize(size);
326 if (computeEigenvectors) {
327 m_eivec.resize(size, size);
333 ComplexVectorType& cv = m_tmp;
334 const MatrixType& mS = m_realQZ.matrixS();
335 const MatrixType& mT = m_realQZ.matrixT();
339 if (i == size - 1 || mS.coeff(i + 1, i) == Scalar(0)) {
341 m_alphas.coeffRef(i) = mS.diagonal().coeff(i);
342 m_betas.coeffRef(i) = mT.diagonal().coeff(i);
343 if (computeEigenvectors) {
344 v.setConstant(Scalar(0.0));
345 v.coeffRef(i) = Scalar(1.0);
347 if (numext::abs(m_betas.coeffRef(i)) >= (std::numeric_limits<RealScalar>::min)()) {
349 const Scalar alpha = real(m_alphas.coeffRef(i));
350 const Scalar beta = m_betas.coeffRef(i);
351 for (Index j = i - 1; j >= 0; j--) {
352 const Index st = j + 1;
353 const Index sz = i - j;
354 if (j > 0 && mS.coeff(j, j - 1) != Scalar(0)) {
357 beta * mS.template block<2, Dynamic>(j - 1, st, 2, sz))
358 .lazyProduct(v.segment(st, sz));
360 beta * mS.template block<2, 2>(j - 1, j - 1) - alpha * mT.template block<2, 2>(j - 1, j - 1);
361 v.template segment<2>(j - 1) = lhs.partialPivLu().solve(rhs);
364 v.coeffRef(j) = -v.segment(st, sz)
366 .cwiseProduct(beta * mS.block(j, st, 1, sz) - alpha * mT.block(j, st, 1, sz))
368 (beta * mS.coeffRef(j, j) - alpha * mT.coeffRef(j, j));
372 m_eivec.col(i).real().noalias() = m_realQZ.matrixZ().transpose() * v;
373 m_eivec.col(i).real().normalize();
374 m_eivec.col(i).imag().setConstant(0);
384 RealScalar a = mT.diagonal().coeff(i), b = mT.diagonal().coeff(i + 1);
385 const RealScalar beta = m_betas.coeffRef(i) = m_betas.coeffRef(i + 1) = a * b;
390 Scalar p = Scalar(0.5) * (S2.coeff(0, 0) - S2.coeff(1, 1));
391 Scalar z = numext::sqrt(numext::abs(p * p + S2.coeff(1, 0) * S2.coeff(0, 1)));
392 const ComplexScalar alpha = ComplexScalar(S2.coeff(1, 1) + p, (beta > 0) ? z : -z);
393 m_alphas.coeffRef(i) = conj(alpha);
394 m_alphas.coeffRef(i + 1) = alpha;
396 if (computeEigenvectors) {
399 cv.coeffRef(i + 1) = Scalar(1.0);
401 cv.coeffRef(i) = -(
static_cast<Scalar
>(beta * mS.coeffRef(i, i + 1)) - alpha * mT.coeffRef(i, i + 1)) /
402 (
static_cast<Scalar
>(beta * mS.coeffRef(i, i)) - alpha * mT.coeffRef(i, i));
403 for (Index j = i - 1; j >= 0; j--) {
404 const Index st = j + 1;
405 const Index sz = i + 1 - j;
406 if (j > 0 && mS.coeff(j, j - 1) != Scalar(0)) {
409 beta * mS.template block<2, Dynamic>(j - 1, st, 2, sz))
410 .lazyProduct(cv.segment(st, sz));
412 beta * mS.template block<2, 2>(j - 1, j - 1) - alpha * mT.template block<2, 2>(j - 1, j - 1);
413 cv.template segment<2>(j - 1) = lhs.partialPivLu().solve(rhs);
416 cv.coeffRef(j) = cv.segment(st, sz)
418 .cwiseProduct(beta * mS.block(j, st, 1, sz) - alpha * mT.block(j, st, 1, sz))
420 (alpha * mT.coeffRef(j, j) -
static_cast<Scalar
>(beta * mS.coeffRef(j, j)));
423 m_eivec.col(i + 1).noalias() = m_realQZ.matrixZ().transpose() * cv;
424 m_eivec.col(i + 1).normalize();
425 m_eivec.col(i) = m_eivec.col(i + 1).conjugate();
431 m_computeEigenvectors = computeEigenvectors;
432 m_isInitialized =
true;
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition CwiseBinaryOp.h:80
Computes the generalized eigenvalues and eigenvectors of a pair of general matrices.
Definition GeneralizedEigenSolver.h:63
GeneralizedEigenSolver(EigenBase< InputTypeA > &A, EigenBase< InputTypeB > &B, bool computeEigenvectors=true)
Constructor for inplace decomposition .
Definition GeneralizedEigenSolver.h:178
internal::make_complex_t< Scalar > ComplexScalar
Complex scalar type for MatrixType.
Definition GeneralizedEigenSolver.h:87
Eigen::Index Index
Definition GeneralizedEigenSolver.h:79
EigenvectorsType eigenvectors() const
Returns the computed generalized eigenvectors.
Definition GeneralizedEigenSolver.h:201
Matrix< Scalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > VectorType
Type for vector of real scalar values eigenvalues as returned by betas().
Definition GeneralizedEigenSolver.h:94
typename MatrixType::Scalar Scalar
Scalar type for matrices of type MatrixType.
Definition GeneralizedEigenSolver.h:77
MatrixType_ MatrixType
Synonym for the template parameter MatrixType_.
Definition GeneralizedEigenSolver.h:66
const VectorType & betas() const
Definition GeneralizedEigenSolver.h:245
CwiseBinaryOp< internal::scalar_quotient_op< ComplexScalar, Scalar >, ComplexVectorType, VectorType > EigenvalueType
Expression type for the eigenvalues as returned by eigenvalues().
Definition GeneralizedEigenSolver.h:105
GeneralizedEigenSolver()
Default constructor.
Definition GeneralizedEigenSolver.h:123
const ComplexVectorType & alphas() const
Definition GeneralizedEigenSolver.h:235
Matrix< ComplexScalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > ComplexVectorType
Type for vector of complex scalar values eigenvalues as returned by alphas().
Definition GeneralizedEigenSolver.h:101
GeneralizedEigenSolver(const EigenBase< InputTypeA > &A, const EigenBase< InputTypeB > &B, bool computeEigenvectors=true)
Constructor; computes the generalized eigendecomposition of given matrix pair.
Definition GeneralizedEigenSolver.h:154
Matrix< ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime > EigenvectorsType
Type for matrix of eigenvectors as returned by eigenvectors().
Definition GeneralizedEigenSolver.h:113
EigenvalueType eigenvalues() const
Returns an expression of the computed generalized eigenvalues.
Definition GeneralizedEigenSolver.h:225
GeneralizedEigenSolver(Index size)
Default constructor with memory preallocation.
Definition GeneralizedEigenSolver.h:132
GeneralizedEigenSolver & setMaxIterations(Index maxIters)
Definition GeneralizedEigenSolver.h:284
GeneralizedEigenSolver & compute(const EigenBase< InputTypeA > &A, const EigenBase< InputTypeB > &B, bool computeEigenvectors=true)
Computes generalized eigendecomposition of given matrix.
A matrix or vector expression mapping an existing array of data.
Definition Map.h:97
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
Performs a real QZ decomposition of a pair of square matrices.
Definition RealQZ.h:62
ComputationInfo
Definition Constants.h:455
@ Success
Definition Constants.h:457
Definition EigenBase.h:34