aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2012-08-05 09:57:31 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2012-08-05 09:57:31 +0200
commitaf824091be78c82212cef4b2fb085a083fbebc5e (patch)
treead7524bf83ec1493dc9cb63560a8e0008edf6c76 /Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
parentc73c3ec2f89b1660ccdb8e1eadfc709b1e3b4532 (diff)
Fix precision regression when attempting to fix underflow issues.
Diffstat (limited to 'Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h')
-rw-r--r--Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h11
1 files changed, 10 insertions, 1 deletions
diff --git a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
index acc5576fe..24c78b4b2 100644
--- a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
+++ b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
@@ -743,7 +743,16 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta
// RealScalar e2 = abs2(subdiag[end-1]);
// RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2));
// This explain the following, somewhat more complicated, version:
- RealScalar mu = diag[end] - (e / (td + (td>0 ? 1 : -1))) * (e / hypot(td,e));
+ RealScalar mu = diag[end];
+ if(td==0)
+ mu -= abs(e);
+ else
+ {
+ RealScalar e2 = abs2(subdiag[end-1]);
+ RealScalar h = hypot(td,e);
+ if(e2==0) mu -= (e / (td + (td>0 ? 1 : -1))) * (e / h);
+ else mu -= e2 / (td + (td>0 ? h : -h));
+ }
RealScalar x = diag[start] - mu;
RealScalar z = subdiag[start];