diff options
author | Gael Guennebaud <g.gael@free.fr> | 2013-07-17 13:21:35 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2013-07-17 13:21:35 +0200 |
commit | 2f593ee67cd2ce995fcf52560daf88774c7c64f2 (patch) | |
tree | 973b12ded629a9778d2cb05961edba799d8e908e /Eigen/src/Cholesky | |
parent | 231d4a6fdae342af5f2a482104539eafe4fc5cdb (diff) | |
parent | 20e535e1429cdb2f2dace3e2e6915e33968aa198 (diff) |
merge with main branch
Diffstat (limited to 'Eigen/src/Cholesky')
-rw-r--r-- | Eigen/src/Cholesky/LDLT.h | 37 | ||||
-rw-r--r-- | Eigen/src/Cholesky/LLT.h | 10 |
2 files changed, 24 insertions, 23 deletions
diff --git a/Eigen/src/Cholesky/LDLT.h b/Eigen/src/Cholesky/LDLT.h index 9bd60d648..05b300c56 100644 --- a/Eigen/src/Cholesky/LDLT.h +++ b/Eigen/src/Cholesky/LDLT.h @@ -259,7 +259,7 @@ template<> struct ldlt_inplace<Lower> { transpositions.setIdentity(); if(sign) - *sign = real(mat.coeff(0,0))>0 ? 1:-1; + *sign = numext::real(mat.coeff(0,0))>0 ? 1:-1; return true; } @@ -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; } @@ -309,11 +300,11 @@ template<> struct ldlt_inplace<Lower> for(int i=k+1;i<index_of_biggest_in_corner;++i) { Scalar tmp = mat.coeffRef(i,k); - mat.coeffRef(i,k) = conj(mat.coeffRef(index_of_biggest_in_corner,i)); - mat.coeffRef(index_of_biggest_in_corner,i) = conj(tmp); + mat.coeffRef(i,k) = numext::conj(mat.coeffRef(index_of_biggest_in_corner,i)); + mat.coeffRef(index_of_biggest_in_corner,i) = numext::conj(tmp); } if(NumTraits<Scalar>::IsComplex) - mat.coeffRef(index_of_biggest_in_corner,k) = conj(mat.coeff(index_of_biggest_in_corner,k)); + mat.coeffRef(index_of_biggest_in_corner,k) = numext::conj(mat.coeff(index_of_biggest_in_corner,k)); } // partition the matrix: @@ -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 = numext::real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0; + if(k == 0) + *sign = newSign; + else if(*sign != newSign) + *sign = 0; + } } return true; @@ -349,7 +350,7 @@ template<> struct ldlt_inplace<Lower> template<typename MatrixType, typename WDerived> static bool updateInPlace(MatrixType& mat, MatrixBase<WDerived>& w, const typename MatrixType::RealScalar& sigma=1) { - using internal::isfinite; + using numext::isfinite; typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::Index Index; @@ -367,9 +368,9 @@ template<> struct ldlt_inplace<Lower> break; // Update the diagonal terms - RealScalar dj = real(mat.coeff(j,j)); + RealScalar dj = numext::real(mat.coeff(j,j)); Scalar wj = w.coeff(j); - RealScalar swj2 = sigma*abs2(wj); + RealScalar swj2 = sigma*numext::abs2(wj); RealScalar gamma = dj*alpha + swj2; mat.coeffRef(j,j) += swj2/alpha; @@ -380,7 +381,7 @@ template<> struct ldlt_inplace<Lower> Index rs = size-j-1; w.tail(rs) -= wj * mat.col(j).tail(rs); if(gamma != 0) - mat.col(j).tail(rs) += (sigma*conj(wj)/gamma)*w.tail(rs); + mat.col(j).tail(rs) += (sigma*numext::conj(wj)/gamma)*w.tail(rs); } return true; } diff --git a/Eigen/src/Cholesky/LLT.h b/Eigen/src/Cholesky/LLT.h index db22a2f85..2e6189f7d 100644 --- a/Eigen/src/Cholesky/LLT.h +++ b/Eigen/src/Cholesky/LLT.h @@ -232,10 +232,10 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V RealScalar beta = 1; for(Index j=0; j<n; ++j) { - RealScalar Ljj = real(mat.coeff(j,j)); - RealScalar dj = abs2(Ljj); + RealScalar Ljj = numext::real(mat.coeff(j,j)); + RealScalar dj = numext::abs2(Ljj); Scalar wj = temp.coeff(j); - RealScalar swj2 = sigma*abs2(wj); + RealScalar swj2 = sigma*numext::abs2(wj); RealScalar gamma = dj*beta + swj2; RealScalar x = dj + swj2/beta; @@ -251,7 +251,7 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V { temp.tail(rs) -= (wj/Ljj) * mat.col(j).tail(rs); if(gamma != 0) - mat.col(j).tail(rs) = (nLjj/Ljj) * mat.col(j).tail(rs) + (nLjj * sigma*conj(wj)/gamma)*temp.tail(rs); + mat.col(j).tail(rs) = (nLjj/Ljj) * mat.col(j).tail(rs) + (nLjj * sigma*numext::conj(wj)/gamma)*temp.tail(rs); } } } @@ -277,7 +277,7 @@ template<typename Scalar> struct llt_inplace<Scalar, Lower> Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k); Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k); - RealScalar x = real(mat.coeff(k,k)); + RealScalar x = numext::real(mat.coeff(k,k)); if (k>0) x -= A10.squaredNorm(); if (x<=RealScalar(0)) return k; |