From 22820e950e916917cebfc8aa1633162b847b53f7 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 1 Jul 2013 11:49:23 +0200 Subject: [PATCH] Improve BiCGSTAB robustness: fix a divide by zero and allow to restart with a new initial residual reference. --- Eigen/src/IterativeLinearSolvers/BiCGSTAB.h | 24 +++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h index fbefb696f..048d59170 100644 --- a/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +++ b/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h @@ -43,8 +43,9 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, VectorType r = rhs - mat * x; VectorType r0 = r; - RealScalar r0_sqnorm = rhs.squaredNorm(); - if(r0_sqnorm == 0) + RealScalar r0_sqnorm = r0.squaredNorm(); + RealScalar rhs_sqnorm = rhs.squaredNorm(); + if(rhs_sqnorm == 0) { x.setZero(); return true; @@ -61,13 +62,22 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, RealScalar tol2 = tol*tol; int i = 0; + int restarts = 0; - while ( r.squaredNorm()/r0_sqnorm > tol2 && i tol2 && iRealScalar(0)) + w = t.dot(s) / t.squaredNorm(); x += alpha * y + w * z; r = s - w * t; ++i; } - tol_error = sqrt(r.squaredNorm()/r0_sqnorm); + tol_error = sqrt(r.squaredNorm()/rhs_sqnorm); iters = i; return true; }