function [x, flag, k, errv] = bicgstab_ell(aparams,mparams, b, params, x0) %bicgstab_ell bicgstab(ell) for right-preconditioned iterates % [x, flag,iter,resvec] = bicgstab_ell(aparams,mparams, b, params, x0) % input % aparams structure defining coefficient matrix % mparams structure defining preconditioning matrix % b right-hand side vector % params four-dimensional vector to control iteration % params(1) = relative residual reduction factor % params(2) = max number of iterations % params(3), params(4): see source file for definitions % x0 initial preconditioned iterate % output % x computed (approximate) preconditioned solution % flag convergence flag % 0 for convergence to params(1) within params(2) iterations % 1 if iterated params(2) times but did not converge to params(1) % iter total iteration count % resvec vector of residual norms of iterates % % called by bicgstab_ell_r % IFISS function: HCE; 15 March 2005. %Modification of BiCGstab(ell) written by Gerard Sleijpen. %Copyright 1997 Gerard Sleijpen. %Reproduced and distributed with permission of the copyright holder. %Modifications to handle IFISS data structures identified in line. %function [x, flag, k, errv] = bicgstab_ell(aparams,mparams, b, params, x0) % ************************************************************************* % Modification of BiCGstab(ell) routine as documented below, to handle % IFISS matrix operations: calls to "operate" replaced by calls to IFISS % mvp and preconditioning routines. % Note: this program is designed for a right-preconditioned system with % inital guess x0 for the preconditioned iterate. Adapted via the wrapper % "rbcg_ell.m" to handle an initial guess for the unpreconditioned iterate % by using the residual as the right hand side and solving for the % correction starting with zero initial guess. % % Modifications by HCE, 14 January 2005. % ************************************************************************* % % BiCGstab(ell) algorithm by Sleijpen & Fokkema 1993 % enhanced with modifications by Sleijpen & van der Vorst % % Version 22.01.97 by Gerard Sleijpen % % Computes the solution of Ax=b using the BiCGstab(ell) scheme. % If a preconditioning matrix M is provided, % bicgstabl will implicitly solve the system A*C y=b, where C=M^(-1), % and return the solution x=C*y. % % Startvector: x0 % parameters: params=[tol,maxiter,ell,kappa] % having the following meaning. % Maximal number of iterations: maxiter % Desired residual reduction: tol % Value of ell: ell % - BiCGstab(ell) is a "product" of BiCG and GMRES(ell) - % - ell=1 (& kappa=0) then BiCGstab(1) = BiCGSTAB - % - specifically for skew problems - % - ell=2 (default) or 4 is better choice - % Maximum value |cos(r,Ar)|: kappa % - An average of GMRES(ell) and FOM(ell) - % - if angle(r,Ar) is large (> 45 degr), - % - can improve the stability of the BiCG part: - % - kappa:=max|cos(r,Ar)| controles - % - the switch from GMRES(ell) to average. - % - kappa=0.7 corresponds to angle of 45 degr (default choice). - % - kappa=0 then in all steps GMRES(ell) (standaard BiCGstab(ell)) - % In operate.m action of preconditioned matrix A*C % Each iteration step of BiCGSTAB requires 2 MVs (precond. matrix actions) % Each it. step, BiCGstab(ell) requires 2*ell MVs. % Computational costs average per MV are more or less independent of ell % Therefore, for fair comparision, in this code: 1 iteration = 2 MV. % Names of mvp and preconditioning routines afun = aparams.Afun; mfun = mparams.Mfun; %unprecond=0; tol = params(1); maxiter = params(2); l = params(3); kappa=params(4); % Note: initial iterate here is for preconditioned quantity x = x0; n = size(b,1); %y = x; operate; r = b - y; %% Modification by HCE, adapt for IFISS data structures r = b - feval(afun, feval(mfun,x,aparams,mparams), aparams); rt = r; %% random shadow vector rt may work better for skew problems rand('seed',0), rt = rand(n,1); u = zeros(n,1); gamma=1; omega=1; k = 0; norm_r=norm(r); r0_norm = norm_r; errv(1,1)=1; L=2:l+1; ZERO=zeros(l,1); %PRINTS0=' %5i %8.4f ';PRINTS=[PRINTS0,' bicg\n']; while ( ktol ) gamma=-omega*gamma; y=r; for j=1:l rho=rt'*y; beta=rho/gamma; u=r-beta*u; % y=u(:,j); operate; u(:,j+1)=y; %% Modification by HCE, adapt for IFISS data structures y = feval(afun, feval(mfun,u(:,j),aparams,mparams), aparams); u(:,j+1) = y; gamma=rt'*y; alpha=rho/gamma; x=x+alpha*u(:,1); r=r-alpha*u(:,2:j+1); % y=r(:,j); operate; r(:,j+1)=y; %% Modification by HCE, adapt for IFISS data structures y = feval(afun, feval(mfun,r(:,j),aparams,mparams), aparams); r(:,j+1) = y; end G=r'*r; % norm_r=sqrt(G(1,1)); errv(k+L,1)=ZERO+norm_r/r0_norm; k=k+l; %% fprintf(PRINTS,k,log10(errv(k+1,1))); PRINTS=[PRINTS0,' mr\n']; Gamma0=[1;-G(2:l,2:l)\G(2:l,1);0]; Gamma1=[0;-G(2:l,2:l)\G(2:l,l+1);1]; NGamma0=Gamma0'*G*Gamma0; NGamma1=Gamma1'*G*Gamma1; omega=Gamma0'*G*Gamma1; cosine=abs(omega)/sqrt(NGamma0*NGamma1); omega=omega/NGamma1; if cosinetol, flag = 1; else flag = 0; end errv = errv*r0_norm;