From feef39e2d1bfd2a703ff9125b60e899802f0c3d9 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 13 Apr 2016 22:49:51 +0200 Subject: Fix underflow in JacoviSVD's complex to real preconditioner --- Eigen/src/SVD/JacobiSVD.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'Eigen/src/SVD') diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h index bf5ff48c3..88bc0688e 100644 --- a/Eigen/src/SVD/JacobiSVD.h +++ b/Eigen/src/SVD/JacobiSVD.h @@ -368,9 +368,15 @@ struct svd_precondition_2x2_block_to_be_real if(n==0) { - z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q); - work_matrix.row(p) *= z; - if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z); + // make sure firt column is zero (deflation) + work_matrix.coeffRef(p,p) = work_matrix.coeffRef(q,p) = Scalar(0); + if(work_matrix.coeff(p,q)!=Scalar(0)) + { + // work_matrix.coeff(p,q) can be zero if work_matrix.coeff(q,p) is not zero but small enough to underflow when computing n + z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q); + work_matrix.row(p) *= z; + if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z); + } if(work_matrix.coeff(q,q)!=Scalar(0)) { z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q); -- cgit v1.2.3