ρ(G)
Bán kính quang phổ và hội tụ
ρ<1ω
Ma trận tách
Đối với các cuộc thảo luận dưới đây, tôi sẽ giả định rằng hệ thống được giải quyết được đưa ra bởi
Ax=b,
với một lần lặp của mẫu
x(k+1)=v+Gx(k),
vkx(k)
SOR lấy trung bình trọng số của phép lặp cũ và phép lặp Gauss-Seidel. Phương thức Gauss-Seidel dựa trên sự phân tách ma trận của biểu mẫu
A=D+L+U
DALARA
x(k+1)=(D+L)−1b+GG−Sx(k)
và ma trận lặp là
GG−S=−(D+L)−1U.
SOR sau đó có thể được viết là
x(k+1)=ω(D+ωL)−1b+GSORx(k)
Ở đâu
GSOR=(D+ωL)−1((1−ω)D−ωU).
ω
SOR tối ưu
Một ví dụ thực tế trong đó hệ số trọng số tối ưu được biết đến phát sinh trong bối cảnh giải phương trình Poisson:
∇2u=f in Ωu=g on ∂Ω
Phân biệt hệ thống này trên một miền vuông trong 2D bằng cách sử dụng các khác biệt hữu hạn bậc hai với khoảng cách lưới đồng nhất dẫn đến một ma trận dải đối xứng với 4 trên đường chéo, -1 ngay trên và dưới đường chéo và thêm hai dải -1 khoảng cách đường chéo. Có một số khác biệt do điều kiện biên, nhưng đó là cấu trúc cơ bản. Với ma trận này, sự lựa chọn tối ưu có thể chứng minh cho hệ số SOR được đưa ra bởi
ω=21+sin(πΔx/L)
ΔxL
Như bạn có thể thấy, SOR đạt độ chính xác của máy trong khoảng 100 lần lặp mà tại đó Gauss-Seidel kém hơn khoảng 25 bậc. Nếu bạn muốn chơi xung quanh với ví dụ này, tôi đã bao gồm mã MATLAB tôi đã sử dụng bên dưới.
clear all
close all
%number of iterations:
niter = 150;
%number of grid points in each direction
N = 16;
% [x y] = ndgrid(linspace(0,1,N),linspace(0,1,N));
[x y] = ndgrid(linspace(-pi,pi,N),linspace(-pi,pi,N));
dx = x(2,1)-x(1,1);
L = x(N,1)-x(1,1);
%desired solution:
U = sin(x/2).*cos(y);
% Right hand side for the Poisson equation (computed from U to produce the
% desired known solution)
Ix = 2:N-1;
Iy = 2:N-1;
f = zeros(size(U));
f(Ix,Iy) = (-4*U(Ix,Iy)+U(Ix-1,Iy)+U(Ix+1,Iy)+U(Ix,Iy-1)+U(Ix,Iy+1));
figure(1)
clf
contourf(x,y,U,50,'linestyle','none')
title('True solution')
%initial guess (must match boundary conditions)
U0 = U;
U0(Ix,Iy) = rand(N-2);
%Gauss-Seidel iteration:
UGS = U0; EGS = zeros(1,niter);
for iter=1:niter
for iy=2:N-1
for ix=2:N-1
UGS(ix,iy) = -1/4*(f(ix,iy)-UGS(ix-1,iy)-UGS(ix+1,iy)-UGS(ix,iy-1)-UGS(ix,iy+1));
end
end
%error:
EGS(iter) = sum(sum((U-UGS).^2))/sum(sum(U.^2));
end
figure(2)
clf
contourf(x,y,UGS,50,'linestyle','none')
title(sprintf('Gauss-Seidel approximate solution, iteration %d', iter))
drawnow
%SOR iteration:
USOR = U0; ESOR = zeros(1,niter);
w = 2/(1+sin(pi*dx/L));
for iter=1:niter
for iy=2:N-1
for ix=2:N-1
USOR(ix,iy) = (1-w)*USOR(ix,iy)-w/4*(f(ix,iy)-USOR(ix-1,iy)-USOR(ix+1,iy)-USOR(ix,iy-1)-USOR(ix,iy+1));
end
end
%error:
ESOR(iter) = sum(sum((U-USOR).^2))/sum(sum(U.^2));
end
figure(4)
clf
contourf(x,y,USOR,50,'linestyle','none')
title(sprintf('Gauss-Seidel approximate solution, iteration %d', iter))
drawnow
figure(5)
clf
semilogy(EGS,'b')
hold on
semilogy(ESOR,'r')
title('L2 relative error')
xlabel('Iteration number')
legend('Gauss-Seidel','SOR','location','southwest')