Конвергенція класичних ітеративних розв'язків для лінійних систем визначається спектральним радіусом ітераційної матриці . Для загальної лінійної системи важко визначити оптимальний (або навіть хороший) параметр SOR через труднощі визначення спектрального радіусу ітераційної матриці. Нижче я включив багато додаткових деталей, включаючи приклад реальної проблеми, коли відома оптимальна вага SOR.ρ(G)
Спектральний радіус і конвергенція
Спектральний радіус визначається як абсолютне значення власного значення найбільшої величини. Метод буде сходитися, якщо а менший спектральний радіус означає швидше конвергенцію. SOR працює, змінюючи розбиття матриці, що використовується для отримання ітераційної матриці на основі вибору параметра зважування , сподіваючись зменшуючи спектральний радіус отриманої ітераційної матриці.ρ<1ω
Матричне розщеплення
Для обговорення нижче, я припускаю, що система, яку потрібно вирішити, задана
Ax=b,
з ітерацією форми
x(k+1)=v+Gx(k),
де - вектор, позначається число ітераціїvkx(k).
SOR приймає середньозважене значення серед старої ітерації та ітерації Гаусса-Сейделя. Метод Гаусса-Сейделя спирається на матричне розщеплення форми
A=D+L+U
де D є діагоналлю A, L являє собою нижню трикутну матрицю, що містить усі елементи A строго нижче діагоналі і R являє собою верхню трикутну матрицю, що містить усі елементи Aстрого вище діагоналі. Потім ітерація Гаусса-Сейделя задана
x(k+1)=(D+L)−1b+GG−Sx(k)
і матриця ітерації є
ГG - S= - ( D + L)- 1U .
Тоді SOR можна записати як
х( k + 1 )= ω ( D + ω L)- 1b +ГS O Rх( k )
де
ГS O R= ( D + ω L)- 1( ( 1 - ω ) D - ω U ) .
Визначення швидкості конвергенції ітераційної схеми дійсно зводиться до визначення спектрального радіуса цих ітераційних матриць. Взагалі, це складна проблема, якщо ви не знаєте чогось конкретного щодо структури матриці. Дуже мало прикладів, з яких я знаю, де обчислюється оптимальний коефіцієнт зважування. На практиці,ωповинні визначатися на ходу на основі спостережуваного (припущенного) зближення алгоритму, що працює. У деяких випадках це працює, але в інших не вдається.
Оптимальний SOR
Один реалістичний приклад, коли відомий оптимальний коефіцієнт зважування, виникає в контексті розв’язання рівняння Пуассона:
∇2u = f i n Ω u = g o n ∂ Ω
Дискретизація даної системи на квадратній області в 2D з використанням кінцевих відмінностей другого порядку з рівномірним міжрядковим інтервалом призводить до отримання симетричної смугової матриці з 4 по діагоналі, -1 безпосередньо вище та нижче діагоналі, та ще двох смуг -1 на деякій відстані від відстані діагональна. Існують деякі відмінності через граничні умови, але це основна структура. Враховуючи цю матрицю, виправдано оптимальний вибір коефіцієнта СОР задається методом
ω =21 + гріх( πΔ х / л )
де Δ x - інтервал між сітками та L- розмір домену. Зробити це для простого випадку з відомим рішенням, надається наступна помилка проти ітераційного числа для цих двох методів:
Як бачимо, SOR досягає машинної точності приблизно в 100 ітераціях, при цьому Гаусс-Сейдель на 25 порядків гірший. Якщо ви хочете пограти з цим прикладом, я включив код MATLAB, який я використовував нижче.
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')