La convergenza dei solutori iterativi classici per sistemi lineari è determinata dal raggio spettrale della matrice di iterazione, . Per un sistema lineare generale, è difficile determinare un parametro SOR ottimale (o addirittura buono) a causa della difficoltà nel determinare il raggio spettrale della matrice di iterazione. Di seguito ho incluso molti dettagli aggiuntivi, incluso un esempio di un problema reale in cui è noto il peso SOR ottimale.ρ(G)
Raggio spettrale e convergenza
Il raggio spettrale è definito come il valore assoluto dell'autovalore di massima magnitudine. Un metodo converge se e un raggio spettrale più piccolo significa una convergenza più rapida. SOR agisce modificando la suddivisione della matrice utilizzata per derivare la matrice di iterazione in base alla scelta di un parametro di ponderazione ω , eventualmente diminuendo il raggio spettrale della matrice di iterazione risultante.ρ<1ω
Frazionamento a matrice
Per la discussione che segue, presumo che il sistema da risolvere sia dato da
Ax=b,
con un'iterazione del modulo
x(k+1)=v+Gx(k),
dove è un vettore e il numero di iterazione k è indicato con x ( k ) .vkx(k)
SOR prende una media ponderata della vecchia iterazione e di una iterazione di Gauss-Seidel. Il metodo Gauss-Seidel si basa su una suddivisione matriciale del modulo
A=D+L+U
dove è la diagonale di A , L è una matrice triangolare inferiore contenente tutti gli elementi di A strettamente sotto la diagonale e R è una matrice triangolare superiore contenente tutti gli elementi di A rigorosamente sopra la diagonale. L'iterazione di Gauss-Seidel viene quindi data daDALARA
x(k+1)=(D+L)−1b+GG−Sx(k)
e la matrice di iterazione è
solG - S= - ( D + L )- 1U .
SOR può quindi essere scritto come
X( k + 1 )= ω ( D + ω L )- 1b + GS O RX( k )
dove
solS O R= ( D + ω L )- 1( ( 1 - ω ) D - ω U ) .
ω
SOR ottimale
Un esempio realistico in cui è noto il coefficiente di ponderazione ottimale si pone nel contesto della risoluzione di un'equazione di Poisson:
∇2u=f in Ωu=g on ∂Ω
Discretizzare questo sistema su un dominio quadrato in 2D usando differenze finite del secondo ordine con spaziatura della griglia uniforme si traduce in una matrice a bande simmetriche con 4 sulla diagonale, -1 immediatamente sopra e sotto la diagonale e altre due bande di -1 a una certa distanza dalla diagonale. Ci sono alcune differenze dovute alle condizioni al contorno, ma questa è la struttura di base. Data questa matrice, la scelta decisamente ottimale per il coefficiente SOR è data da
ω=21+sin(πΔx/L)
ΔxL
Come puoi vedere, SOR raggiunge la precisione della macchina in circa 100 iterazioni a quel punto Gauss-Seidel è circa 25 ordini di grandezza peggiori. Se vuoi giocare con questo esempio, ho incluso il codice MATLAB che ho usato di seguito.
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')