GMRES算法及Matlab程序

文章介绍了GMRES方法用于求解线性方程组Ax=b的问题,重点在于Galerkin条件下的Krylov子空间迭代和施密特正交化的概念。提供了4阶Pascal矩阵和10阶稀疏矩阵的Matlab代码示例,展示了GMRES算法的执行过程,包括矩阵的正交化、Givens变换和回带过程。
摘要由CSDN通过智能技术生成

关于GMRES的总结
一些理论以及代码

首先是我们要解决的问题,也就是最常见的问题,即求解
A x = b Ax=b
Ax=b
Galerkin条件
在这里插入图片描述
在这里插入图片描述
krylov子空间
在这里插入图片描述
我们所做的GMRES实际上就是在Galerkin条件的扩张下,n o r m ( r ) norm®norm®不断减小的一个过程。这也是r rr在( A r , A 2 r , . . . A n − 1 r ) (Ar,A{2}r,…A{n-1}r)(Ar,A
2
r,…A
n−1
r)下的一个线性表出的过程。这个过程中,求解系数的方法是不断的通过正交化求投影值,与施密特正交化类似。

matlab代码
我用了两个例子,结果都是零解,一个用的是4阶pascal矩阵(对称正定),一个用的是10阶稀疏矩阵。

主函数

% main
clear; clc; close all 
A = pascal(4);
b = [0 0 0 0]';
x0 = [1 0 0 0]';
%
[V,R,H,res] = bGMRES(A,b,x0)
%
r0 = b-A*x0;beta = norm(r0);
be = zeros(4,1);be(1) = beta;
be
[T,bk] = givens( H,be )
%
newT = zeros(4,4);
for i = 1:4
    for j = 1:i
        newT(j,i) = T(j,i);
    end
end
newT
x4 = inv(newT)*bk
x5 = backward( newT,bk )
%
realSolution = inv(A)*b
sol1 = x0+V(:,1:4)*x4
sol2 = x0+V(:,1:4)*x5
%%
clear; clc; close all 
A = sprandsym(10,0.7);
A
b = [0 0 0 0 0 0 0 0 0 0]';
x0 = [1 0 0 0 0 0 0 0 0 0]';
%
[V,R,H,res] = bGMRES(A,b,x0)
%
r0 = b-A*x0;beta = norm(r0);
be = zeros(10,1);be(1) = beta;
be
[T,bk] = givens( H,be )
%
newT = zeros(10,10);
for i = 1:10
    for j = 1:i
        newT(j,i) = T(j,i);
    end
end
newT
x4 = inv(newT)*bk
x5 = backward( newT,bk )
%
realSolution = inv(A)*b
sol1 = x0+V(:,1:10)*x4
sol2 = x0+V(:,1:10)*x5

GMRES

%Ax = b
function [V,R,H,res] = bGMRES(A,b,x0)
    %bGMRES:basic GMRES method
    %Input: x0:初值;A为mxm矩阵,b为解
    %Output: res为残差
    [m, ~] = size(A);
    R = Inf(m,m);%R为剩余向量
    H = zeros(m+1,m);V = zeros(m,m+1);%A*V=V*H
    %设定初值
    r0 = b-A*x0;
    V(:,1) = r0./norm(r0);
    for j = 1:m
        R(:,j) = A*V(:,j);
        for i = 1:j
            H(i,j) = R(:,j)'*V(:,i);
            R(:,j) = R(:,j) - H(i,j)*V(:,i);
        end
        H(j+1,j) = norm(R(:,j));
        res = H(j+1,j);
        if abs(H(j+1,j)) < 1e-10
            sprintf('done without residual')
            break;
        else
            V(:,j+1) = R(:,j)./H(j+1,j);
        end
    end
end

GIVENS

function [T,bk] = givens( H,b )
%givens: 通过givens变换化上Hessenborg阵为上三角矩阵
%  化 Hx=b 为 Tx=c
    [~,n] = size(H);
    %提取
    Ht = H(n+1,:);
    H = H(1:n,:);
    b = b(1:n);
    %Rotate Matrix need to recrate every iteration
    %R = eye(n,n);%Rotate Matrix
    for k = 1:n-1
        R = eye(n,n);
        down = (H(k,k)^2+H(k+1,k)^2)^(1/2);
        s = H(k+1,k)/down;
        c = H(k,k)/down;
        R(k:k+1,k:k+1) = [c,s;-s,c];
        R
        H = R*H
        H(k+1,k) = 0;
        b = R*b
    end
    T = [H;Ht];
    bk = b;
end

backward

function x = backward( A,b )
%backward:   上三角矩阵回带过程
% 求解Ax=b
    [~,c] = size(A);
    A = A(1:c,:);
    x = zeros(c,1);
    x(end) = b(end)/A(c,c);
    for k = 2:c
        V = x(c-k+2:c);
        x(c-k+1) = (b(c-k+1)-A(c-k+1,c-k+2:end)*V)/A(c-k+1,c-k+1);
    end
end

————————————————
版权声明:本文为CSDN博主「老李今天学习了吗」的原创文章,原文链接:https://blog.csdn.net/weixin_29732003/article/details/106337865

以下是使用GMRES GPU算法MATLAB代码示例: ```matlab %GMRES-GPU algorithm %The matrix A and the vector b are stored in the device (GPU) %The initial guess x0 is also stored in the device (GPU) %The algorithm solves Ax = b for x function [x, flag, relres, iter] = gmres_gpu(A, b, x0, rtol, maxit) %Transfer A and b from the host (CPU) to the device (GPU) A_gpu = gpuArray(A); b_gpu = gpuArray(b); %Initialize variables n = size(A, 1); x = gpuArray(x0); r = b_gpu - A_gpu * x; normb = norm(b_gpu); normr = norm(r); %Check for initial guess x0 if normr/normb <= rtol flag = 0; relres = normr/normb; iter = 0; return; end %Initialize GMRES variables m = 30; %maximum number of iterations Q = zeros(n, m+1, 'gpuArray'); H = zeros(m+1, m, 'gpuArray'); cs = zeros(m, 1, 'gpuArray'); sn = zeros(m, 1, 'gpuArray'); e1 = [1; zeros(m, 1), 'gpuArray']; Q(:,1) = r/normr; beta = normr; j = 0; while normr/normb > rtol && j < maxit j = j + 1; %Arnoldi process for i = 1:m v = A_gpu * Q(:,i); for k = 1:i H(k,i) = Q(:,k)' * v; v = v - H(k,i) * Q(:,k); end H(i+1,i) = norm(v); Q(:,i+1) = v / H(i+1,i); %Apply Givens rotations for k = 1:i-1 temp = cs(k) * H(k,i) + sn(k) * H(k+1,i); H(k+1,i) = -sn(k) * H(k,i) + cs(k) * H(k+1,i); H(k,i) = temp; end %Compute Givens rotation [cs(i), sn(i), H(i,i)] = givens(H(i,i), H(i+1,i)); H(i+1,i) = 0; %Apply Givens rotation to RHS temp = cs(i) * beta; beta = -sn(i) * beta; beta = cs(i) * (H(i,i) - temp) + sn(i) * H(i+1,i); H(i+1,i) = -sn(i) * (H(i,i) - temp) + cs(i) * H(i+1,i); %Check for convergence if abs(beta) <= rtol y = H(1:i,1:i) \ beta * e1(1:i); x = x + Q(:,1:i) * y; relres = norm(A_gpu * x - b_gpu) / normb; flag = 0; iter = j; return; end end %Solve least squares problem y = H(1:m,1:m) \ beta * e1(1:m); x = x + Q(:,1:m) * y; %Compute residual r = b_gpu - A_gpu * x; normr = norm(r); %Check for convergence if normr/normb <= rtol relres = normr/normb; flag = 0; iter = j; return; end end %Check for maximum number of iterations if j >= maxit flag = 1; else flag = -1; end %Compute relative residual relres = normr/normb; %Return number of iterations iter = j; end %Givens rotation function function [c, s, r] = givens(a, b) if b == 0 c = sign(a); s = 0; r = abs(a); elseif abs(b) > abs(a) temp = a / b; s = sign(b) / sqrt(1 + temp^2); c = s * temp; r = b / s; else temp = b / a; c = sign(a) / sqrt(1 + temp^2); s = c * temp; r = a / c; end end ``` 请注意,此代码需要GPU计算能力。您还需要确保您的MATLAB版本支持GPU计算。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值