mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 03:39:01 +08:00
bug #793: detect NaN and INF in EigenSolver instead of aborting with an assert.
This commit is contained in:
parent
7098e6d976
commit
3c66bb136b
@ -275,10 +275,11 @@ template<typename _MatrixType> class EigenSolver
|
|||||||
*/
|
*/
|
||||||
EigenSolver& compute(const MatrixType& matrix, bool computeEigenvectors = true);
|
EigenSolver& compute(const MatrixType& matrix, bool computeEigenvectors = true);
|
||||||
|
|
||||||
|
/** \returns NumericalIssue if the input contains INF or NaN values or overflow occured. Returns Success otherwise. */
|
||||||
ComputationInfo info() const
|
ComputationInfo info() const
|
||||||
{
|
{
|
||||||
eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
|
eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
|
||||||
return m_realSchur.info();
|
return m_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Sets the maximum number of iterations allowed. */
|
/** \brief Sets the maximum number of iterations allowed. */
|
||||||
@ -302,6 +303,7 @@ template<typename _MatrixType> class EigenSolver
|
|||||||
EigenvalueType m_eivalues;
|
EigenvalueType m_eivalues;
|
||||||
bool m_isInitialized;
|
bool m_isInitialized;
|
||||||
bool m_eigenvectorsOk;
|
bool m_eigenvectorsOk;
|
||||||
|
ComputationInfo m_info;
|
||||||
RealSchur<MatrixType> m_realSchur;
|
RealSchur<MatrixType> m_realSchur;
|
||||||
MatrixType m_matT;
|
MatrixType m_matT;
|
||||||
|
|
||||||
@ -367,12 +369,15 @@ EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvect
|
|||||||
using std::sqrt;
|
using std::sqrt;
|
||||||
using std::abs;
|
using std::abs;
|
||||||
using std::max;
|
using std::max;
|
||||||
|
using numext::isfinite;
|
||||||
eigen_assert(matrix.cols() == matrix.rows());
|
eigen_assert(matrix.cols() == matrix.rows());
|
||||||
|
|
||||||
// Reduce to real Schur form.
|
// Reduce to real Schur form.
|
||||||
m_realSchur.compute(matrix, computeEigenvectors);
|
m_realSchur.compute(matrix, computeEigenvectors);
|
||||||
|
|
||||||
|
m_info = m_realSchur.info();
|
||||||
|
|
||||||
if (m_realSchur.info() == Success)
|
if (m_info == Success)
|
||||||
{
|
{
|
||||||
m_matT = m_realSchur.matrixT();
|
m_matT = m_realSchur.matrixT();
|
||||||
if (computeEigenvectors)
|
if (computeEigenvectors)
|
||||||
@ -386,6 +391,13 @@ EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvect
|
|||||||
if (i == matrix.cols() - 1 || m_matT.coeff(i+1, i) == Scalar(0))
|
if (i == matrix.cols() - 1 || m_matT.coeff(i+1, i) == Scalar(0))
|
||||||
{
|
{
|
||||||
m_eivalues.coeffRef(i) = m_matT.coeff(i, i);
|
m_eivalues.coeffRef(i) = m_matT.coeff(i, i);
|
||||||
|
if(!isfinite(m_eivalues.coeffRef(i)))
|
||||||
|
{
|
||||||
|
m_isInitialized = true;
|
||||||
|
m_eigenvectorsOk = false;
|
||||||
|
m_info = NumericalIssue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -406,6 +418,13 @@ EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvect
|
|||||||
|
|
||||||
m_eivalues.coeffRef(i) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, z);
|
m_eivalues.coeffRef(i) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, z);
|
||||||
m_eivalues.coeffRef(i+1) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, -z);
|
m_eivalues.coeffRef(i+1) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, -z);
|
||||||
|
if(!(isfinite(m_eivalues.coeffRef(i)) && isfinite(m_eivalues.coeffRef(i+1))))
|
||||||
|
{
|
||||||
|
m_isInitialized = true;
|
||||||
|
m_eigenvectorsOk = false;
|
||||||
|
m_info = NumericalIssue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -594,7 +613,7 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eigen_assert(0 && "Internal bug in EigenSolver"); // this should not happen
|
eigen_assert(0 && "Internal bug in EigenSolver (INF or NaN has not been detected)"); // this should not happen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user