diff options
author | Gael Guennebaud <g.gael@free.fr> | 2013-06-09 23:19:32 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2013-06-09 23:19:32 +0200 |
commit | a69b4b092beec7caf87f1fe13cbba0781c651852 (patch) | |
tree | 76137784e030012cc6fcd5bc50180ac0bfd59355 /Eigen/src/Cholesky | |
parent | c98fd7a6cae853f1ca8570994ae9ba3c13e9c4bd (diff) |
Fix bug #608: the sign computation in LDLT was broken
Diffstat (limited to 'Eigen/src/Cholesky')
-rw-r--r-- | Eigen/src/Cholesky/LDLT.h | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/Eigen/src/Cholesky/LDLT.h b/Eigen/src/Cholesky/LDLT.h index 4c0be9dd9..d933b10d4 100644 --- a/Eigen/src/Cholesky/LDLT.h +++ b/Eigen/src/Cholesky/LDLT.h @@ -278,22 +278,13 @@ template<> struct ldlt_inplace<Lower> // are compared; if any diagonal is negligible compared // to the largest overall, the algorithm bails. cutoff = abs(NumTraits<Scalar>::epsilon() * biggest_in_corner); - - if(sign) - *sign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0 ? 1 : -1; - } - else if(sign) - { - // LDLT is not guaranteed to work for indefinite matrices, but let's try to get the sign right - int newSign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0; - if(newSign != *sign) - *sign = 0; } // Finish early if the matrix is not full rank. if(biggest_in_corner < cutoff) { for(Index i = k; i < size; i++) transpositions.coeffRef(i) = i; + if(sign) *sign = 0; break; } @@ -334,6 +325,16 @@ template<> struct ldlt_inplace<Lower> } if((rs>0) && (abs(mat.coeffRef(k,k)) > cutoff)) A21 /= mat.coeffRef(k,k); + + if(sign) + { + // LDLT is not guaranteed to work for indefinite matrices, but let's try to get the sign right + int newSign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0; + if(k == 0) + *sign = newSign; + else if(*sign != newSign) + *sign = 0; + } } return true; |