summaryrefslogtreecommitdiffhomepage
path: root/eigen/Eigen/src/Cholesky/LDLT.h
diff options
context:
space:
mode:
Diffstat (limited to 'eigen/Eigen/src/Cholesky/LDLT.h')
-rw-r--r--eigen/Eigen/src/Cholesky/LDLT.h11
1 files changed, 7 insertions, 4 deletions
diff --git a/eigen/Eigen/src/Cholesky/LDLT.h b/eigen/Eigen/src/Cholesky/LDLT.h
index fcee7b2..0313a54 100644
--- a/eigen/Eigen/src/Cholesky/LDLT.h
+++ b/eigen/Eigen/src/Cholesky/LDLT.h
@@ -248,7 +248,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
/** \brief Reports whether previous computation was successful.
*
* \returns \c Success if computation was succesful,
- * \c NumericalIssue if the matrix.appears to be negative.
+ * \c NumericalIssue if the factorization failed because of a zero pivot.
*/
ComputationInfo info() const
{
@@ -376,6 +376,8 @@ template<> struct ldlt_inplace<Lower>
if((rs>0) && pivot_is_valid)
A21 /= realAkk;
+ else if(rs>0)
+ ret = ret && (A21.array()==Scalar(0)).all();
if(found_zero_pivot && pivot_is_valid) ret = false; // factorization failed
else if(!pivot_is_valid) found_zero_pivot = true;
@@ -568,13 +570,14 @@ void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) cons
// more precisely, use pseudo-inverse of D (see bug 241)
using std::abs;
const typename Diagonal<const MatrixType>::RealReturnType vecD(vectorD());
- // In some previous versions, tolerance was set to the max of 1/highest and the maximal diagonal entry * epsilon
- // as motivated by LAPACK's xGELSS:
+ // In some previous versions, tolerance was set to the max of 1/highest (or rather numeric_limits::min())
+ // and the maximal diagonal entry * epsilon as motivated by LAPACK's xGELSS:
// RealScalar tolerance = numext::maxi(vecD.array().abs().maxCoeff() * NumTraits<RealScalar>::epsilon(),RealScalar(1) / NumTraits<RealScalar>::highest());
// However, LDLT is not rank revealing, and so adjusting the tolerance wrt to the highest
// diagonal element is not well justified and leads to numerical issues in some cases.
// Moreover, Lapack's xSYTRS routines use 0 for the tolerance.
- RealScalar tolerance = RealScalar(1) / NumTraits<RealScalar>::highest();
+ // Using numeric_limits::min() gives us more robustness to denormals.
+ RealScalar tolerance = (std::numeric_limits<RealScalar>::min)();
for (Index i = 0; i < vecD.size(); ++i)
{