mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-19 16:19:37 +08:00
bug #478: fix regression in the eigen decomposition of zero matrices.
This commit is contained in:
parent
63de19c000
commit
53026d29d4
@ -250,7 +250,7 @@ template<typename _MatrixType> class ComplexEigenSolver
|
||||
EigenvectorType m_matX;
|
||||
|
||||
private:
|
||||
void doComputeEigenvectors(const RealScalar& matrixnorm);
|
||||
void doComputeEigenvectors(RealScalar matrixnorm);
|
||||
void sortEigenvalues(bool computeEigenvectors);
|
||||
};
|
||||
|
||||
@ -284,10 +284,12 @@ ComplexEigenSolver<MatrixType>::compute(const EigenBase<InputType>& matrix, bool
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(const RealScalar& matrixnorm)
|
||||
void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(RealScalar matrixnorm)
|
||||
{
|
||||
const Index n = m_eivalues.size();
|
||||
|
||||
matrixnorm = numext::maxi(matrixnorm,(std::numeric_limits<RealScalar>::min)());
|
||||
|
||||
// Compute X such that T = X D X^(-1), where D is the diagonal of T.
|
||||
// The matrix X is unit triangular.
|
||||
m_matX = EigenvectorType::Zero(n, n);
|
||||
|
@ -248,12 +248,24 @@ template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeU)
|
||||
{
|
||||
const Scalar considerAsZero = (std::numeric_limits<Scalar>::min)();
|
||||
|
||||
eigen_assert(matrix.cols() == matrix.rows());
|
||||
Index maxIters = m_maxIters;
|
||||
if (maxIters == -1)
|
||||
maxIters = m_maxIterationsPerRow * matrix.rows();
|
||||
|
||||
Scalar scale = matrix.derived().cwiseAbs().maxCoeff();
|
||||
if(scale<considerAsZero)
|
||||
{
|
||||
m_matT.setZero(matrix.rows(),matrix.cols());
|
||||
if(computeU)
|
||||
m_matU.setIdentity(matrix.rows(),matrix.cols());
|
||||
m_info = Success;
|
||||
m_isInitialized = true;
|
||||
m_matUisUptodate = computeU;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Step 1. Reduce to Hessenberg form
|
||||
m_hess.compute(matrix.derived()/scale);
|
||||
|
@ -131,6 +131,15 @@ template<typename MatrixType> void eigensolver(const MatrixType& m)
|
||||
ComplexEigenSolver<MatrixType> eig(a.adjoint() * a);
|
||||
eig.compute(a.adjoint() * a);
|
||||
}
|
||||
|
||||
// regression test for bug 478
|
||||
{
|
||||
a.setZero();
|
||||
ComplexEigenSolver<MatrixType> ei3(a);
|
||||
VERIFY_IS_EQUAL(ei3.info(), Success);
|
||||
VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(),RealScalar(1));
|
||||
VERIFY((ei3.eigenvectors().transpose()*ei3.eigenvectors().transpose()).eval().isIdentity());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m)
|
||||
|
@ -76,6 +76,15 @@ template<typename MatrixType> void eigensolver(const MatrixType& m)
|
||||
EigenSolver<MatrixType> eig(a.adjoint() * a);
|
||||
eig.compute(a.adjoint() * a);
|
||||
}
|
||||
|
||||
// regression test for bug 478
|
||||
{
|
||||
a.setZero();
|
||||
EigenSolver<MatrixType> ei3(a);
|
||||
VERIFY_IS_EQUAL(ei3.info(), Success);
|
||||
VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(),RealScalar(1));
|
||||
VERIFY((ei3.eigenvectors().transpose()*ei3.eigenvectors().transpose()).eval().isIdentity());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m)
|
||||
|
@ -180,6 +180,15 @@ template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
|
||||
SelfAdjointEigenSolver<MatrixType> eig(a.adjoint() * a);
|
||||
eig.compute(a.adjoint() * a);
|
||||
}
|
||||
|
||||
// regression test for bug 478
|
||||
{
|
||||
a.setZero();
|
||||
SelfAdjointEigenSolver<MatrixType> ei3(a);
|
||||
VERIFY_IS_EQUAL(ei3.info(), Success);
|
||||
VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(),RealScalar(1));
|
||||
VERIFY((ei3.eigenvectors().transpose()*ei3.eigenvectors().transpose()).eval().isIdentity());
|
||||
}
|
||||
}
|
||||
|
||||
template<int>
|
||||
|
Loading…
x
Reference in New Issue
Block a user