aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Cholesky
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2013-06-09 23:19:32 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2013-06-09 23:19:32 +0200
commita69b4b092beec7caf87f1fe13cbba0781c651852 (patch)
tree76137784e030012cc6fcd5bc50180ac0bfd59355 /Eigen/src/Cholesky
parentc98fd7a6cae853f1ca8570994ae9ba3c13e9c4bd (diff)
Fix bug #608: the sign computation in LDLT was broken
Diffstat (limited to 'Eigen/src/Cholesky')
-rw-r--r--Eigen/src/Cholesky/LDLT.h21
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;