summaryrefslogtreecommitdiff
path: root/modules/sparse/macros/conjgrad.sci
diff options
context:
space:
mode:
Diffstat (limited to 'modules/sparse/macros/conjgrad.sci')
-rwxr-xr-xmodules/sparse/macros/conjgrad.sci280
1 files changed, 280 insertions, 0 deletions
diff --git a/modules/sparse/macros/conjgrad.sci b/modules/sparse/macros/conjgrad.sci
new file mode 100755
index 000000000..07a7da992
--- /dev/null
+++ b/modules/sparse/macros/conjgrad.sci
@@ -0,0 +1,280 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Paul Bignier: transformed into a gateway to
+// propose pcg, cgs, bicg and bicgstab.
+// Copyright (C) 2009 - INRIA - Michael Baudin
+// Copyright (C) 2008 - INRIA - Michael Baudin
+// Copyright (C) 2006 - INRIA - Serge Steer
+// Copyright (C) 2005 - IRISA - Sage Group
+//
+// 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
+
+//
+// conjgrad --
+// This function regroups four methods from the "Conjugate Gradient family" to solve the linear system %Ax=b:
+// - PCG (Preconditioned Conjugate Gradient): A must be symmetric positive definite,
+// - CGS (preconditioned Conjugate Gradient Squared): A must be square,
+// - BICG (preconditioned BiConjugate Gradient): A must be square,
+// - BICGSTAB (preconditioned BiConjugate Gradient Stabilized): A must be square (default 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
+// flag INTEGER: 0 = solution found to tolerance
+// 1 = no convergence given maxIter
+// resNorm REAL final relative norm of the residual
+// iter INTEGER number of iterations performed
+// resVec REAL residual vector
+//
+// References
+//
+// PCG
+// "Templates for the Solution of Linear Systems: Building Blocks
+// for Iterative Methods",
+// Barrett, Berry, Chan, Demmel, Donato, Dongarra, Eijkhout,
+// Pozo, Romine, and Van der Vorst, SIAM Publications, 1993
+// (ftp netlib2.cs.utk.edu; cd linalg; get templates.ps).
+//
+// "Iterative Methods for Sparse Linear Systems, Second Edition"
+// Saad, SIAM Publications, 2003
+// (ftp ftp.cs.umn.edu; cd dept/users/saad/PS; get all_ps.zip).
+//
+// Golub and Van Loan, Matrix Computations
+//
+// CGS
+// "CGS, A Fast Lanczos-Type Solver for Nonsymmetric Linear systems"
+// by Peter Sonneveld
+//
+// http://epubs.siam.org/doi/abs/10.1137/0910004
+// http://dl.acm.org/citation.cfm?id=64888&preflayout=flat
+// http://mathworld.wolfram.com/ConjugateGradientSquaredMethod.html
+//
+// BICG
+// "Numerical Recipes: The Art of Scientific Computing." (third ed.)
+// by William Press, Saul Teukolsky, William Vetterling, Brian Flannery.
+//
+// http://apps.nrbook.com/empanel/index.html?pg=87
+// http://dl.acm.org/citation.cfm?doid=1874391.187410
+// http://mathworld.wolfram.com/BiconjugateGradientMethod.html
+//
+// BICGSTAB
+// "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
+//
+// The input / output arguments of this command are the same as
+// Matlab's pcg, cgs, bicg and bicgstab commands, augmented with the 'method' argument
+//
+
+function [x, flag, resNorm, iter, resVec] = conjgrad(%A, %b, method, tol, maxIter, %M, %M2, x0, verbose )
+
+ [lhs, rhs] = argn(0);
+
+ if rhs < 2 then
+ error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"conjgrad",2,7));
+ end
+ if rhs > 8 then
+ error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"conjgrad",2,7));
+ end
+ if exists("method", "local") == 0 then
+ method = "bicgstab";
+ end
+ if exists("tol", "local") == 0 then
+ tol = 1e-8
+ end
+ if exists("maxIter", "local") == 0 then
+ maxIter = size(%b, 1)
+ end
+ if exists("%M", "local") == 0 then
+ %M = []
+ end
+ if exists("%M2", "local") == 0 then
+ %M2 = []
+ end
+ if exists("x0", "local") == 0 then
+ x0 = zeros(%b);
+ end
+ if exists("verbose", "local") == 0 then
+ verbose = 0;
+ end
+ if verbose == 1 then
+ printf(gettext("Arguments:\n"));
+ printf(" tol = "+string(tol)+"\n");
+ printf(" maxIter = "+string(maxIter)+"\n");
+ printf(" M = \n")
+ disp(%M)
+ printf(" M2 = \n");
+ disp(%M2)
+ printf(" x0 = \n");
+ disp(x0)
+ printf(" verbose = "+string(verbose)+"\n");
+ end
+ // Compute matrixType
+ select type(%A)
+ case 1 then
+ matrixType = 1;
+ case 5 then
+ matrixType = 1;
+ case 13 then
+ matrixType = 0;
+ Aargs = list()
+ case 15 then
+ Aargs = list(%A(2:$))
+ // Caution : modify the input argument %A !
+ %A = %A(1);
+ matrixType = 0;
+ else
+ error(msprintf(gettext("%s: Wrong type for input argument #%d.\n"),"conjgrad",1));
+ end
+ // If %A is a matrix (dense or sparse)
+ if matrixType == 1 then
+ if size(%A,1) ~= size(%A,2) then
+ error(msprintf(gettext("%s: Wrong type for input argument #%d: Square matrix expected.\n"),"conjgrad",1));
+ end
+ end
+ // Check right hand side %b
+ if type(%b) ~= 1
+ error(msprintf(gettext("%s: Wrong type for input argument #%d: A matrix expected.\n"),"conjgrad",2));
+ end
+ if size(%b,2) ~= 1 then
+ error(msprintf(gettext("%s: Wrong type for input argument #%d: Column vector expected.\n"),"conjgrad",2));
+ end
+ if matrixType == 1 then
+ if size(%b,1) ~= size(%A,1) then
+ error(msprintf(gettext("%s: Wrong size for input argument #%d: Same size as input argument #%d expected.\n"),"conjgrad",2,1));
+ end
+ end
+ if matrixType == 1 then
+ if size(%b,1) ~= size(%A,1) then
+ error(msprintf(gettext("%s: Wrong size for input argument #%d: Same size as input argument #%d expected.\n"),"conjgrad",2,1));
+ end
+ end
+ // Check method
+ if type(method) ~= 10 | size(method) ~= [1 1]
+ error(msprintf(gettext("%s: Wrong type for input argument #%d: Single String expected.\n"),"conjgrad",3));
+ elseif and(method ~= ["pcg" "cgs" "bicg" "bicgstab"]),
+ error(msprintf(gettext("%s: Wrong value for input argument #%d: %s, %s, %s or %s expected.\n"),"conjgrad",3,"pcg","cgs","bicg","bicgstab"));
+ end
+ // Check type of the error tolerance tol
+ if or(size(tol) ~= [1 1]) then
+ error(msprintf(gettext("%s: Wrong type for input argument #%d: Scalar expected.\n"),"conjgrad",4));
+ end
+ // Check the type of maximum number of iterations maxIter
+ if or(size(maxIter) ~= [1 1]) then
+ error(msprintf(gettext("%s: Wrong type for input argument #%d: Scalar expected.\n"),"conjgrad",5));
+ end
+ // Compute precondType
+ select type(%M)
+ case 1 then
+ // M is a matrix
+ // precondType = 0 if the M is empty
+ // = 1 if the M is not empty
+ precondType = bool2s(size(%M,"*")>=1);
+ case 5 then
+ precondType = 1;
+ case 13 then
+ Margs = list()
+ precondType = 2;
+ case 15 then
+ Margs = list(%M(2:$))
+ // Caution : modify the input argument %M !
+ %M = %M(1);
+ precondType = 2;
+ else
+ error(msprintf(gettext("%s: Wrong type for input argument #%d.\n"),"conjgrad",6));
+ end
+ if precondType == 1 then
+ if size(%M,1) ~= size(%M,2) then
+ error(msprintf(gettext("%s: Wrong type for input argument #%d: Square matrix expected.\n"),"conjgrad",6));
+ end
+ if size(%M,1) ~= size(%b,1) then
+ error(msprintf(gettext("%s: Wrong size for input argument #%d: Same size as input argument #%d expected.\n"),"conjgrad",6,2));
+ end
+ end
+ // Compute precondBis
+ select type(%M2)
+ case 1 then
+ // M2 is a matrix
+ // precondBis = 0 if the M2 is empty
+ // = 1 if the M2 is not empty
+ precondBis = bool2s(size(%M2,"*")>=1);
+ case 5 then
+ precondBis = 1;
+ case 13 then
+ M2args = list()
+ precondBis = 2;
+ case 15 then
+ M2args = list(%M2(2:$))
+ // Caution : modify the input argument %M2 !
+ %M2 = %M2(1);
+ // Caution : modify precondType again !
+ precondType = 2;
+ else
+ error(msprintf(gettext("%s: Wrong type for input argument #%d.\n"),"conjgrad",7));
+ end
+ if precondBis == 1 then
+ if size(%M2,1) ~= size(%M2,2) then
+ error(msprintf(gettext("%s: Wrong type for input argument #%d: Square matrix expected.\n"),"conjgrad",7));
+ end
+ if size(%M2,1) ~= size(%b,1) then
+ error(msprintf(gettext("%s: Wrong size for input argument #%d: Same size as input argument #%d expected.\n"),"conjgrad",7,2));
+ end
+ end
+ // Check size of the initial vector x0
+ if size(x0,2) ~= 1 then
+ error(msprintf(gettext("%s: Wrong value for input argument #%d: Column vector expected.\n"),"conjgrad",8));
+ end
+ if size(x0,1) ~= size(%b,1) then
+ error(msprintf(gettext("%s: Wrong size for input argument #%d: Same size as input argument #%d expected.\n"),"conjgrad",8,2));
+ end
+
+ // ------------
+ // Computations
+ // ------------
+ select method
+ case "pcg"
+ [x, resNorm, iter, resVec] = %pcg(%A, %b, tol, maxIter, %M, %M2, x0, verbose )
+ case "cgs"
+ [x, resNorm, iter, resVec] = %cgs(%A, %b, tol, maxIter, %M, %M2, x0, verbose )
+ case "bicg"
+ [x, resNorm, iter, resVec] = %bicg(%A, %b, tol, maxIter, %M, %M2, x0, verbose )
+ else // "bicgstab"
+ [x, resNorm, iter, resVec] = %bicgstab(%A, %b, tol, maxIter, %M, %M2, x0, verbose )
+ 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"),"conjgrad"));
+ end
+ else
+ flag = 0;
+ if verbose == 1 then
+ printf(gettext("Algorithm pass\n"));
+ end
+ end
+
+endfunction