summaryrefslogtreecommitdiff
path: root/modules/sparse/macros/%bicgstab.sci
diff options
context:
space:
mode:
Diffstat (limited to 'modules/sparse/macros/%bicgstab.sci')
-rwxr-xr-xmodules/sparse/macros/%bicgstab.sci202
1 files changed, 202 insertions, 0 deletions
diff --git a/modules/sparse/macros/%bicgstab.sci b/modules/sparse/macros/%bicgstab.sci
new file mode 100755
index 000000000..fe90693ed
--- /dev/null
+++ b/modules/sparse/macros/%bicgstab.sci
@@ -0,0 +1,202 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Paul Bignier
+//
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution. The terms
+// are also available at
+// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+
+//
+// bicgstab --
+// BICG solves the linear system %Ax=b using the BiConjugate Gradient Stabilized method.
+// If M is given, it is used as a preconditionning matrix.
+// If both M and M2 are given, the matrix M * M2 is used as a preconditionning
+// matrix.
+//
+// input %A REAL matrix or a function y=Ax(x) which computes y=%A*x for a given x
+// b REAL right hand side vector
+// tol, optional REAL error tolerance (default: 1e-8)
+// maxIter, optional INTEGER maximum number of iterations (default: size(%b))
+// %M, optional REAL preconditioner matrix (default: none)
+// %M2, optional REAL preconditioner matrix (default: none)
+// x0, optional REAL initial guess vector (default: the zero vector)
+// verbose, optional INTEGER set to 1 to enable verbose logging (default : 0)
+//
+// output x REAL solution vector
+// resNorm REAL final relative norm of the residual
+// iter INTEGER number of iterations performed
+// resVec REAL residual vector
+//
+// References
+//
+// "Bi-CGSTAB: A Fast and Smoothly Converging Variant of Bi-CG for the Solution of Nonsymmetric Linear Systems"
+// by Henk van der Vorst.
+//
+// http://epubs.siam.org/doi/abs/10.1137/0913035
+// http://dl.acm.org/citation.cfm?id=131916.131930&coll=DL&dl=GUIDE&CFID=372773884&CFTOKEN=56630250
+// http://mathworld.wolfram.com/BiconjugateGradientStabilizedMethod.html
+//
+// Notes
+// This script was originally a matlab > scilab translation of the bicgstab.m
+// script from http://www.netlib.org/templates/matlab
+//
+// The input / output arguments of this command are the same as Matlab's bicgstab command.
+//
+
+function [x, resNorm, iter, resVec] = %bicgstab(%A, %b, tol, maxIter, %M, %M2, x0, verbose )
+
+ // Initialization
+ bnrm2 = norm(%b);
+ if (verbose==1) then
+ printf(gettext("Norm of right-hand side : %s\n"), string(bnrm2));
+ end
+ if (bnrm2 == 0) then
+ if (verbose==1) then
+ printf(gettext("Special processing where the right-hand side is zero.\n"));
+ end
+ // When rhs is 0, there is a trivial solution : x=0
+ x = zeros(%b);
+ resNorm = 0;
+ resVec = resNorm;
+ else
+ x = x0;
+ // r = %b - %A*x;
+ if (matrixType ==1),
+ r = %b - %A*x;
+ r2 = r;
+ else
+ r = %b - %A(x,Aargs(:));
+ r2 = r;
+ end
+ resNorm = norm(r) / bnrm2;
+ resVec = resNorm;
+ end
+ if (verbose==1) then
+ printf(gettext(" Type of preconditionning #1 : %d\n"),precondType);
+ printf(gettext(" Type of preconditionning #2 : %d\n"),precondBis);
+ end
+ // Begin iteration
+ // Distinguish the number of iterations processed from the currentiter index
+ iter = 0
+ for currentiter = 1:maxIter
+ if (resNorm <= tol) then
+ if (verbose==1) then
+ printf(gettext(" New residual = %s < tol = %s => break\n"),string(resNorm),string(tol));
+ end
+ break;
+ end
+ iter = iter + 1
+ if (verbose==1) then
+ printf(gettext(" Iteration #%s/%s residual : %s\n"),string(currentiter),string(maxIter),string(resNorm));
+ printf(" x=\n");
+ disp(x);
+ end
+ rho = r2'*r;
+ if (rho == 0) then
+ break;
+ end
+ if (currentiter > 1) then
+ bet = (rho/rho_old)*(alp/ome);
+ p = r + bet*(p-ome*v);
+ else
+ p = r;
+ end
+ // Solve M' M2' P = p
+ if %M == [] & %M2 == [] then
+ P = p;
+ elseif %M2 == [] then
+ // Compute r so that M' P = p
+ if (precondType == 1) then
+ P = %M \ p;
+ elseif (precondType == 2) then
+ P = %M(p,Margs(:));
+ else
+ P = p;
+ end
+ else
+ // Compute r so that M' M2' P = p
+ if (precondBis == 1) then
+ P = %M \ p;
+ P = %M2 \ p;
+ elseif (precondBis == 2) then
+ P = %M(p,Margs(:));
+ P = %M2(p,M2args(:));
+ else
+ P = p;
+ end
+ end
+ // v = %A*P;
+ if (matrixType == 1),
+ v = %A*P;
+ else
+ v = %A(P);
+ end
+ alp = rho / (r2'*v);
+ s = r - alp*v;
+ // Check for convergence
+ if (norm(s) <= tol) then
+ x = x+alp*P;
+ resNorm = norm(s) / bnrm2;
+ if (verbose==1) then
+ printf(gettext(" New residual = %s < tol = %s => break\n"),string(resNorm),string(tol));
+ end
+ resVec = [resVec;resNorm];
+ break;
+ end
+ // Solve M M2 S = s
+ if %M == [] & %M2 == [] then
+ S = s;
+ elseif %M2 == [] then
+ // Compute r so that M S = s
+ if (precondType == 1) then
+ S = %M \ s;
+ elseif (precondType == 2) then
+ S = %M(s,Margs(:));
+ else
+ S = s;
+ end
+ else
+ // Compute r so that M M2 S = s
+ if (precondBis == 1) then
+ S = %M \ s;
+ S = %M2 \ s;
+ elseif (precondBis == 2) then
+ S = %M(s,Margs(:));
+ S = %M2(s,M2args(:));
+ else
+ S = s;
+ end
+ end
+ // t = %A*S;
+ if (matrixType == 1),
+ t = %A*S;
+ else
+ t = %A(S);
+ end
+ ome = (t'*s)/(t'*t);
+ x = x + alp*P+ome*S;
+ r = s - ome*t;
+ resNorm = norm(r) / bnrm2;
+ // Caution : transform the scalar resVec into vector resVec !
+ resVec = [resVec;resNorm];
+ rho_old = rho;
+ end
+ // Test for convergence
+ if (resNorm > tol) then
+ if (verbose==1) then
+ printf(gettext("Final residual = %s > tol =%s\n"),string(resNorm),string(tol));
+ printf(gettext("Algorithm fails\n"));
+ end
+ flag = 1;
+ if (lhs < 2) then
+ warning(msprintf(gettext("%s: Convergence error.\n"),"bicgstab"));
+ end
+ else
+ flag = 0;
+ if (verbose==1) then
+ printf(gettext("Algorithm pass\n"));
+ end
+ end
+
+endfunction