function [ x, error, total_iters ] = gmresb ( x0, b, atv, params ) % GMRES linear equation solver, brute-force approach % % C. T. Kelley, January 10, 1994 % % function [x, error, total_iters] = gmresb(x0, b, atv, params) % % Disclaimer: % % This code comes with no guarantee or warranty of any kind. % % Author: % % Tim Kelley % % Reference: % % Tim Kelley, % Iterative Methods for Linear and Nonlinear Equations, % SIAM, 2004, % ISBN: 0898713528, % LC: QA297.8.K45. % % 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. % % params = two dimensional vector to control iteration % params(1) = relative residual reduction factor % params(2) = max number of iterations % % Output: x=solution % % error = vector of residual norms for the history of % the iteration % % total_iters = number of iterations % % % initialization % n=length(b); errtol=params(1); kmax=params(2); x=x0; % % h=zeros(kmax); v=zeros(n,kmax); %r=b-feval(atv,x); if norm(x) ~=0 r = b-feval(atv,x); else r = b; end rho=norm(r); errtol=errtol*norm(b); error=[]; % % test for termination on entry % error=[error,rho]; total_iters=0; 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)); % % Modified Gram-Schmidt % for j=1:k 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)); % % Watch out for happy breakdown. % if(h(k+1,k) ~= 0) v(:,k+1)=v(:,k+1)/h(k+1,k); end % % Formulate and solve the least squares problem. % Update the residual approximation. % y=h(1:k+1,1:k)\(beta*eye(k+1,1)); rho=norm(beta*eye(k+1,1) - h(1:k+1,1:k)*y); error=[error,rho]; end % % At this point either k > kmax or rho < errtol. % It's time to compute x and leave. % total_iters=k; x = x + v(1:n,1:k)*y;