bug #1479: fix failure detection in LDLT

(grafted from 672bdc126b0923e6228a024ce62d1f18b05840ea
)
This commit is contained in:
Gael Guennebaud 2017-11-16 17:55:24 +01:00
parent d18877f18d
commit c20043c8fd
2 changed files with 19 additions and 0 deletions

View File

@ -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;

View File

@ -373,6 +373,7 @@ template<typename MatrixType> void cholesky_definiteness(const MatrixType& m)
VERIFY(ldlt.info()==Success);
VERIFY(!ldlt.isNegative());
VERIFY(!ldlt.isPositive());
VERIFY_IS_APPROX(mat,ldlt.reconstructedMatrix());
}
{
mat << 1, 2, 2, 1;
@ -380,6 +381,7 @@ template<typename MatrixType> void cholesky_definiteness(const MatrixType& m)
VERIFY(ldlt.info()==Success);
VERIFY(!ldlt.isNegative());
VERIFY(!ldlt.isPositive());
VERIFY_IS_APPROX(mat,ldlt.reconstructedMatrix());
}
{
mat << 0, 0, 0, 0;
@ -387,6 +389,7 @@ template<typename MatrixType> void cholesky_definiteness(const MatrixType& m)
VERIFY(ldlt.info()==Success);
VERIFY(ldlt.isNegative());
VERIFY(ldlt.isPositive());
VERIFY_IS_APPROX(mat,ldlt.reconstructedMatrix());
}
{
mat << 0, 0, 0, 1;
@ -394,6 +397,7 @@ template<typename MatrixType> void cholesky_definiteness(const MatrixType& m)
VERIFY(ldlt.info()==Success);
VERIFY(!ldlt.isNegative());
VERIFY(ldlt.isPositive());
VERIFY_IS_APPROX(mat,ldlt.reconstructedMatrix());
}
{
mat << -1, 0, 0, 0;
@ -401,6 +405,7 @@ template<typename MatrixType> void cholesky_definiteness(const MatrixType& m)
VERIFY(ldlt.info()==Success);
VERIFY(ldlt.isNegative());
VERIFY(!ldlt.isPositive());
VERIFY_IS_APPROX(mat,ldlt.reconstructedMatrix());
}
}
@ -452,6 +457,18 @@ void cholesky_faillure_cases()
VERIFY(ldlt.info()==NumericalIssue);
VERIFY_IS_NOT_APPROX(mat,ldlt.reconstructedMatrix());
}
// bug 1479
{
mat.resize(4,4);
mat << 1, 2, 0, 1,
2, 4, 0, 2,
0, 0, 0, 1,
1, 2, 1, 1;
ldlt.compute(mat);
VERIFY(ldlt.info()==NumericalIssue);
VERIFY_IS_NOT_APPROX(mat,ldlt.reconstructedMatrix());
}
}
template<typename MatrixType> void cholesky_verify_assert()