From 2915e1fc5de1cd830eb1a4a723c41a7b14d87254 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 29 Aug 2016 14:14:18 +0200 Subject: [PATCH] Revert part of changeset 5b3a6f51d353bb3b35f6d15f2455774b73d088e0 to keep accuracy of smallest eigenvalues. --- Eigen/src/Eigenvalues/RealSchur.h | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/Eigen/src/Eigenvalues/RealSchur.h b/Eigen/src/Eigenvalues/RealSchur.h index 9d9063004..d6a339f07 100644 --- a/Eigen/src/Eigenvalues/RealSchur.h +++ b/Eigen/src/Eigenvalues/RealSchur.h @@ -236,7 +236,7 @@ template class RealSchur typedef Matrix Vector3s; Scalar computeNormOfT(); - Index findSmallSubdiagEntry(Index iu, const Scalar& maxDiagEntry); + Index findSmallSubdiagEntry(Index iu); void splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift); void computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo); void initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector); @@ -293,18 +293,14 @@ RealSchur& RealSchur::computeFromHessenberg(const HessMa if(norm!=0) { - Scalar maxDiagEntry = m_matT.cwiseAbs().diagonal().maxCoeff(); - while (iu >= 0) { - Index il = findSmallSubdiagEntry(iu,maxDiagEntry); + Index il = findSmallSubdiagEntry(iu); // Check for convergence if (il == iu) // One root found { m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift; - // keep track of the largest diagonal coefficient - maxDiagEntry = numext::maxi(maxDiagEntry,abs(m_matT.coeffRef(iu,iu))); if (iu > 0) m_matT.coeffRef(iu, iu-1) = Scalar(0); iu--; @@ -313,8 +309,6 @@ RealSchur& RealSchur::computeFromHessenberg(const HessMa else if (il == iu-1) // Two roots found { splitOffTwoRows(iu, computeU, exshift); - // keep track of the largest diagonal coefficient - maxDiagEntry = numext::maxi(maxDiagEntry,numext::maxi(abs(m_matT.coeff(iu,iu)), abs(m_matT.coeff(iu-1,iu-1)))); iu -= 2; iter = 0; } @@ -329,8 +323,6 @@ RealSchur& RealSchur::computeFromHessenberg(const HessMa Index im; initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector); performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace); - // keep track of the largest diagonal coefficient - maxDiagEntry = numext::maxi(maxDiagEntry,m_matT.cwiseAbs().diagonal().segment(im,iu-im).maxCoeff()); } } } @@ -360,13 +352,14 @@ inline typename MatrixType::Scalar RealSchur::computeNormOfT() /** \internal Look for single small sub-diagonal element and returns its index */ template -inline Index RealSchur::findSmallSubdiagEntry(Index iu, const Scalar& maxDiagEntry) +inline Index RealSchur::findSmallSubdiagEntry(Index iu) { using std::abs; Index res = iu; while (res > 0) { - if (abs(m_matT.coeff(res,res-1)) <= NumTraits::epsilon() * maxDiagEntry) + Scalar s = abs(m_matT.coeff(res-1,res-1)) + abs(m_matT.coeff(res,res)); + if (abs(m_matT.coeff(res,res-1)) <= NumTraits::epsilon() * s) break; res--; }