Klasik yinelemeli çözücülerin doğrusal sistemler için yakınsaklığı, yineleme matrisinin spektral yarıçapı ile belirlenir, ρ(G). Genel bir lineer sistem için, yineleme matrisinin spektral yarıçapını belirlemedeki zorluk nedeniyle optimal (hatta iyi) bir SOR parametresi belirlemek zordur. Aşağıda, optimal SOR ağırlığının bilindiği gerçek bir sorun örneği de dahil olmak üzere birçok ek ayrıntı ekledim.
Spektral yarıçap ve yakınsaklık
Spektral yarıçap, en büyük büyüklük özdeğerinin mutlak değeri olarak tanımlanır. Bir yöntem,ρ<1ve daha küçük bir spektral yarıçap daha hızlı yakınsama anlamına gelir. SOR, bir ağırlıklandırma parametresi seçimine dayanarak yineleme matrisini türetmek için kullanılan matris bölünmesini değiştirerek çalışırωumarım elde edilen iterasyon matrisinin spektral yarıçapını azaltır.
Matris bölme
Aşağıdaki tartışma için, çözülecek sistemin
Ax=b,
formun tekrarı ile
x(k+1)=v+Gx(k),
nerede v bir vektör ve yineleme sayısıdır k belirtildi x(k).
SOR, eski yinelemenin ve Gauss-Seidel yinelemesinin ağırlıklı bir ortalamasını alır. Gauss-Seidel yöntemi, formun bir matris bölünmesine dayanır
A=D+L+U
nerede D köşegenidir A, L 'nin tüm elemanlarını içeren alt üçgen bir matristir A kesinlikle diyagonalin altında ve R 'nin tüm elemanlarını içeren bir üst üçgen matristir Akesinlikle diyagonalin üzerinde. Sonra Gauss-Seidel yinelemesi
x(k+1)=(D+L)−1b+GG−Sx(k)
ve yineleme matrisi
GG−S=−(D+L)−1U.
SOR daha sonra şu şekilde yazılabilir:
x(k+1)=ω(D+ωL)−1b+GSORx(k)
nerede
GSOR=(D+ωL)−1((1−ω)D−ωU).
Yinelemeli şemanın yakınsama hızının belirlenmesi gerçekten bu yineleme matrislerinin spektral yarıçapının belirlenmesine bağlıdır. Genel olarak, matrisin yapısı hakkında spesifik bir şey bilmediğiniz sürece bu zor bir sorundur. Optimal ağırlık katsayısının nerede hesaplanabileceğinin farkında olduğum çok az örnek var. Uygulamada,ωçalışan algoritmanın gözlemlenen (varsayılan) yakınsamasına göre anında belirlenmelidir. Bu bazı durumlarda işe yarar, ancak diğerlerinde başarısız olur.
Optimal SOR
Optimal ağırlık katsayısının bilindiği gerçekçi bir örnek, bir Poisson denkleminin çözülmesi bağlamında ortaya çıkar:
∇2u=f in Ωu=g on ∂Ω
Düzgün ızgara aralığı ile ikinci dereceden sonlu farklar kullanılarak bu sistemin 2D'deki kare bir alan üzerinde ayrıklaştırılması, diyagonalde 4, diyagonalin hemen üstünde ve altında -1 ve -1'den iki bant daha uzakta olan simetrik bantlı bir matris ile sonuçlanır. diyagonal. Sınır koşulları nedeniyle bazı farklılıklar vardır, ancak temel yapı budur. Bu matris göz önüne alındığında, SOR katsayısı için en uygun seçenek şu şekilde verilir:
ω=21+sin(πΔx/L)
nerede Δx ızgara aralığı ve Letki alanı boyutudur. Bilinen bir çözümle basit bir durum için bunu yapmak, bu iki yöntem için yineleme sayısına karşı aşağıdaki hatayı verir:
Gördüğünüz gibi, SOR yaklaşık 100 yinelemede makine hassasiyetine ulaşır, bu noktada Gauss-Seidel yaklaşık 25 derece daha büyüktür. Bu örnekle oynamak istiyorsanız, aşağıda kullandığım MATLAB kodunu ekledim.
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')