📄 gmres_r.m
字号:
function [x, flag, total_iters, error] = gmres_r(aparams,mparams, b, params, x0)
%gmres_r GMRES iteration with right preconditioning
% [x, flag, total_iters, error] = gmres_r(aparams,mparams, b, params, x0)
% input
% aparams structure defining coefficient matrix
% mparams structure defining preconditioning matrix
% b right-hand side vector
% params three-dimensional vector to control iteration
% params(1) = relative residual reduction factor
% params(2) = max number of iterations
% params(3) (Optional) = reorthogonalization method
% 1 -- Brown/Hindmarsh condition (default)
% 2 -- Never reorthogonalize (not recommended)
% 3 -- Always reorthogonalize (not cheap!)
% x0 initial iterate
% output
% x computed (approximate) 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)
% total_iters total iteration count
% error vector of residual norms of iterates
% IFISS function: HCE; 15 March 2005.
%Modification of gmres.m written by Tim Kelley.
%Copyright 1994 C. T. Kelley.
%Reproduced and distributed with permission of the copyright holder.
%Modifications to handle IFISS data structures identified in line.
%function [x, flag, error, total_iters] = gmres(x0, b, atv, params)
% GMRES linear equation solver
% Implementation following Saad-Schultz
%
% C. T. Kelley, July 10, 1994
%
% This code comes with no guarantee or warranty of any kind.
%
% function [x, flag, error, total_iters] = gmres(x0, b, atv, params)
%
%
% Input: x0 = initial iterate
% b = right hand side
% atv, a matrix-vector product routine
% atv must return Ax when x is input
% the format for atv is
% function ax = atv(x)
% Note that for GMRES we incorporate any
% preconditioning into the atv routine.
% HE modification: pass matrix vector product via aparams
% pass preconditioning operation via mparams
% params = three dimensional vector to control iteration
% params(1) = relative residual reduction factor
% params(2) = max number of iterations
% params(3) (Optional) = reorthogonalization method
% 1 -- Brown/Hindmarsh condition (default)
% 2 -- Never reorthogonalize (not recommended)
% 3 -- Always reorthogonalize (not cheap!)
%
% Output: x=solution
% flag = 0 for convergence to params(1) within params(2) iterations
% = 1 if iterated params(2) times but did not converge to params(1)
% error = vector of residual norms for the history of
% the iteration
% total_iters = number of iterations
%
% Requires givapp.m
% Names of mvp and preconditioning routines
afun = aparams.Afun;
mfun = mparams.Mfun;
%
% initialization
%
n=length(b);
errtol=params(1);
kmax=params(2);
reorth=1;
if length(params) == 3
reorth=params(3);
end
x=x0;
flag=0;
%
%
h=zeros(kmax);
v=zeros(n,kmax);
c=zeros(kmax+1,1);
s=zeros(kmax+1,1);
if norm(x) ~=0
% r = b-feval(atv,x);
r = b-feval(afun,x,aparams);
else
r = b;
end
rho=norm(r);
g=rho*eye(kmax+1,1);
errtol=errtol*norm(b);
error=[];
%
% test for termination on entry
%
error=[error,rho];
total_iters=0; %fprintf(' %5i %8.4f \n',total_iters,log10(rho));
if(rho < errtol)
return
end
%
v(:,1)=r/rho;
beta=rho;
k=0;
%
% GMRES iteration
%
while((rho > errtol) & (k < kmax))
k=k+1;
% v(:,k+1)=feval(atv,v(:,k));
%% Modification by HCE, 15 Oct. 2004: adapt for right preconditioning
v(:,k+1) = feval(afun, feval(mfun,v(:,k),aparams,mparams), aparams);
normav=norm(v(:,k+1));
%
% Modified Gram-Schmidt
%
for j=1:k
h(j,k)=v(:,j)'*v(:,k+1); % h(j,k)=v(:,k+1)'*v(:,j);
v(:,k+1)=v(:,k+1)-h(j,k)*v(:,j);
end
h(k+1,k)=norm(v(:,k+1));
normav2=h(k+1,k);
%
% Reorthogonalize?
%
if (reorth == 1 & normav + .001*normav2 == normav) | reorth == 3
for j=1:k
hr=v(:,j)'*v(:,k+1); % hr=v(:,k+1)'*v(:,j);
h(j,k)=h(j,k)+hr;
v(:,k+1)=v(:,k+1)-hr*v(:,j);
end
h(k+1,k)=norm(v(:,k+1));
end
%
% watch out for happy breakdown
%
if(h(k+1,k) ~= 0)
v(:,k+1)=v(:,k+1)/h(k+1,k);
end
%
% Form and store the information for the new Givens rotation
%
if k > 1
h(1:k,k)=givapp(c(1:k-1),s(1:k-1),h(1:k,k),k-1);
end
nu=norm(h(k:k+1,k));
if nu~=0
c(k)=conj(h(k,k)/nu); % c(k)=h(k,k)/nu; % Change 6/3/97
s(k)=-h(k+1,k)/nu;
h(k,k)=c(k)*h(k,k)-s(k)*h(k+1,k);
h(k+1,k)=0;
g(k:k+1)=givapp(c(k),s(k),g(k:k+1),1);
end
%
% Update the residual norm
%
rho=abs(g(k+1)); %fprintf(' %5i %8.4f \n',k,log10(rho));
error=[error,rho];
end
%
% At this point either k > kmax or rho < errtol.
% It's time to compute x and leave.
%
% set flag first
if rho<errtol, flag=0; else flag=1; end
y=h(1:k,1:k)\g(1:k);
total_iters=k;
%x = x0 + v(1:n,1:k)*y;
%% Modification by HCE, 15 Oct. 2005: adapt for right preconditioning
x = x0 + feval(mfun, v(1:n,1:k)*y, aparams,mparams);
error = error';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -