[英]GMRES method with given rotations in MATLAB
I have the following implementation of algorithm 我有以下算法实现
function[x,error,iter,flag,vetnorm_r]=gmres_givens(A,x,b,restart,maxit,tol)
% input A REAL nonsymmetric positive definite matrix
% x REAL initial guess vector
% b REAL right hand side vector
% M REAL preconditioner matrix
% restart INTEGER number of iterations between restarts
% maxit INTEGER maximum number of iterations
% tol REAL error tolerance
%
% output x REAL solution vector
% error REAL error norm
% iter INTEGER number of iterations performed
% flag INTEGER: 0 = solution found to tolerance
% 1 = no convergence given maxit
iter = 0; % initialization
flag = 0;
bnrm2=norm(b);
if(bnrm2==0), bnrm2=1.0; end
r=b-A*x;
error=norm(r)/bnrm2;
if(error < tol) return, end
[n,n]=size(A); % initialize workspace
m=restart;
V(:,1:m+1)=zeros(n,m+1);
H(1:m+1,1:m)=zeros(m+1,m);
c(1:m)=zeros(m,1);
s(1:m)=zeros(m,1);
e1=zeros(n,1);
e1(1)=1;
vetnorm_r=zeros(m+1,1);
for iter=1:maxit % begin iteration
r=(b-A*x);
V(:,1)=r/norm(r);
g=norm(r)*e1;
vetnorm_r(1)=norm(r);
for i=1:m % construct orthonormal system
w=(A*V(:,i));
for k=1:i
H(k,i)=w'*V(:,k); % basis using Gram-Schmidt
w=w-H(k,i)*V(:,k);
end
H(i+1,i)=norm(w);
V(:,i+1)=w/H(i+1,i);
for k=1:i-1 % apply Givens rotation
temp=c(k)*H(k,i)+s(k)*H(k+1,i);
H(k+1,i)=-s(k)*H(k,i)+c(k)*H(k+1,i);
H(k,i)=temp;
end
[c(i),s(i)]=givens(H(i,i),H(i+1,i)); % form i-th rotation matrix
temp=c(i)*g(i); % approximate residual norm
g(i+1)=-s(i)*g(i);
g(i)=temp;
H(i,i)=c(i)*H(i,i)+s(i)*H(i+1,i);
H(i+1,i)=0;
error=abs(g(i+1))/bnrm2;
vetnorm_r(i+1)=abs(g(i+1));
if (error <= tol) % update approximation
y=H(1:i,1:i)\g(1:i); % and exit
x=x+V(:,1:i)*y;
break;
end
end
if(error <= tol), break, end
y=H(1:m,1:m)\g(1:m); % update approximation
x=x+V*y; % compute residual
r=b-A*x
g(i+1)=norm(r);
error=g(i+1)/bnrm2; % check convergence
if(error <= tol), break, end;
end
if (error>tol) flag=1; end;
end
where
function [c,s]=givens(a,b)
if(b==0)
c=1;
s=0;
elseif (abs(b) > abs(a)),
temp=a/b;
s=1/sqrt(1+temp^2);
c=temp*s;
else
temp=b/a;
c=1/sqrt(1+temp^2);
s=temp*c;
end
My problem is to get a vector (probably a matrix) vetnorm_r
which contains all the norms of the residual (as output), at each iteration (and possibly at every restart). 我的问题是在每次迭代(可能是每次重新启动)时获得一个向量(可能是矩阵)
vetnorm_r
,其中包含残差的所有范数(作为输出)。 I do not know how to build this vector or matrix. 我不知道如何建立这个向量或矩阵。
% input A REAL nonsymmetric positive definite matrix % x REAL initial guess vector % b REAL right hand side vector % M REAL preconditioner matrix % restart INTEGER number of iterations between restarts % maxit INTEGER maximum number of iterations % tol REAL error tolerance % % output x REAL solution vector % error REAL error norm % iter INTEGER number of iterations performed % flag INTEGER: 0 = solution found to tolerance % 1 = no convergence given maxit %输入A REAL非对称正定矩阵%x REAL初始猜测向量%b REAL右侧向量%M REAL预调节器矩阵%restart INTEGER重新启动之间的迭代次数%maxit INTEGER最大迭代次数%tol REAL误差容限%%输出x REAL解决方案矢量%错误REAL错误范数%iter INTEGER所执行的迭代次数%标志INTEGER:0 =找到容差的解决方案%1 =未给出最大收敛
Thanks for any reply 感谢您的回复
You probably shouldn't copy code you don't understand. 您可能不应该复制您不了解的代码。 The residual is where it says check for convergence.
残差表示检查收敛。
if(error <= tol), break, end
y=H(1:m,1:m)\g(1:m); % update approximation
x=x+V*y; % compute residual
r=b-A*x
g(i+1)=norm(r);
error=g(i+1)/bnrm2; % check convergence
if(error <= tol), break, end;
end
I am not sure what you're asking for. 我不确定您要什么。 You can either code so that it doesn't break on tolerance and only performs and a number of iterations so that the vector of residuals is prestored, which is what I would do.
您可以编写任何代码,使其不会超出公差范围,而仅执行并进行多次迭代,以便预先存储残差矢量,这就是我要做的。 Or you can set the residual vector length long then when it gets near about to break add more to it.
或者,您可以将残差矢量长度设置得较长,然后在残差矢量即将断裂时对其添加更多的长度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.