diff options
author | Gael Guennebaud <g.gael@free.fr> | 2014-04-14 13:52:16 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2014-04-14 13:52:16 +0200 |
commit | 148acf8e4fb71294703d4d1deafaf52829535ab7 (patch) | |
tree | d1688a45bf3200e6bd0de436d78600237d38b112 /Eigen | |
parent | 0587db8bf5ca5d5eb6fb8df1c02abddd5b5718ba (diff) |
bug #790: fix overflow in real_2x2_jacobi_svd
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/SVD/JacobiSVD.h | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h index eee31ca97..439eb5d29 100644 --- a/Eigen/src/SVD/JacobiSVD.h +++ b/Eigen/src/SVD/JacobiSVD.h @@ -415,6 +415,7 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q, JacobiRotation<RealScalar> *j_right) { using std::sqrt; + using std::abs; Matrix<RealScalar,2,2> m; m << numext::real(matrix.coeff(p,p)), numext::real(matrix.coeff(p,q)), numext::real(matrix.coeff(q,p)), numext::real(matrix.coeff(q,q)); @@ -428,9 +429,11 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q, } else { - RealScalar u = d / t; - rot1.c() = RealScalar(1) / sqrt(RealScalar(1) + numext::abs2(u)); - rot1.s() = rot1.c() * u; + RealScalar t2d2 = numext::hypot(t,d); + rot1.c() = abs(t)/t2d2; + rot1.s() = d/t2d2; + if(t<RealScalar(0)) + rot1.s() = -rot1.s(); } m.applyOnTheLeft(0,1,rot1); j_right->makeJacobi(m,0,1); |