SOR比Gauss-Seidel快的问题?


9

是否有简单的经验法则可以说明是否值得进行SOR而不是Gauss-Seidel?(以及可能的方法如何估计贴切参数)ω

我的意思是仅查看矩阵,还是矩阵代表的特定问题的知识?

我正在阅读有关以下问题的答案: 是否有用于优化连续超松弛(SOR)方法的试探法? 但这有点太复杂了。我没有看到简单的启发式方法,仅在矩阵上(或它代表的问题)如何估算光谱半径。

我想要简单得多的东西- 仅有几个 SOR收敛更快的矩阵(问题)示例


我正在针对该国王的矩阵进行SOR实验: 其中是单位矩阵,和 s是来自unifrom分布的随机数,使得。我以为最优与参数。A=I+C+RICij=c i,jRij|Rij|<rωc,r

编辑:我用很小的来确保tha在对角线中很强。(对于尺寸5-10的矩阵,)。我还应该说这些是真实且对称的。c,rA|c|<0.1r<2|c|A

但是,我发现Gauss-Seidel()几乎总是最好的(?)ω=1。这是否意味着之间必须存在更多的关联才能利用SOR?还是我做错了什么? Aij


我知道,SOR并不是最有效的求解器(与CG,GMRES ...相比),但是它易于实现和并行化以及针对特定问题进行修改。对原型来说肯定不错。

Answers:


5

线性系统经典迭代求解器的收敛由迭代矩阵的谱半径。对于一般的线性系统,由于难以确定迭代矩阵的谱半径,因此难以确定最佳(甚至良好)的SOR参数。下面,我提供了许多其他详细信息,包括一个实际问题的示例,其中已知最佳SOR权重。ρ(G)

光谱半径和会聚

光谱半径定义为最大幅度特征值的绝对值。如果,则方法将收敛,而较小的频谱半径意味着收敛速度更快。SOR通过基于加权参数的选择来更改用于导出迭代矩阵的矩阵拆分,从而希望减小所得迭代矩阵的频谱半径,从而实现工作。ρ<1ω

矩阵分割

对于下面的讨论,我将假设要解决的系统由

Ax=b,

与形式的迭代

x(k+1)=v+Gx(k),

其中是向量,迭代次数表示为。vkx(k)

SOR采用旧迭代和高斯-赛德尔迭代的加权平均值。高斯-塞德尔方法依赖于形式的矩阵分裂

A=D+L+U

其中是的对角线,是一个下三角矩阵,包含所有元素,严格位于对角线之下,而是上三角矩阵包含所有元素,严格位于对角线上方。高斯-赛德尔迭代然后由DALARA

x(k+1)=(D+L)1b+GGSx(k)

迭代矩阵为

GGS=(D+L)1U.

SOR可以写成

x(k+1)=ω(D+ωL)1b+GSORx(k)

哪里

GSOR=(D+ωL)1((1ω)DωU).

确定迭代方案的收敛速度实际上归结为确定这些迭代矩阵的谱半径。通常,除非您对矩阵的结构有特定的了解,否则这是一个难题。我知道的最佳加权系数可计算的地方很少。实际上,必须根据观察到的(假定的)运行算法的收敛动态确定。这在某些情况下有效,但在其他情况下则失败。ω

最佳SOR

在求解泊松方程的情况下出现了一个已知最佳加权系数的现实示例:

2u=f in Ωu=g on Ω

使用具有均匀网格间距的二阶有限差分在2D平方域上将此系统离散化,得到一个对称的带状矩阵,对角线上有4个,对角线上下分别为-1,另外两个带为-1,与对角线。由于边界条件而存在一些差异,但这是基本结构。给定该矩阵,SOR系数的最佳选择由下式给出

ω=21+sin(πΔx/L)

其中是网格间距,是域大小。对于这两种方法,使用已知解决方案进行简单处理会产生以下误差与迭代次数的关系:ΔxL

高斯-塞德尔和SOR错误

如您所见,SOR在大约100次迭代中达到了机器精度,此时Gauss-Seidel差了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')

您是否知道用于动态计算SOR参数的任何良好/众所周知的技术?我之前听说过,这些技术使用光谱半径的估计值-您能解释一下它们如何使用光谱半径,或提供良好的参考吗?
nukeguy

哦,我看到此问题已在链接的问题scicomp.stackexchange.com/questions/851/…中解决。没关系我的问题,但是如果您要添加更多内容,请随时添加。
nukeguy

@Doug Lipinski我认为f应该乘以dx * dy。该因子来自离散的二阶导数(例如,请参见此处)。顺便说一句,当我这样做时,该算法无法正常工作。你知道为什么吗?
shamalaia

0

这方面的内容并不是我真正的专长,但是我认为这对许多实际应用程序来说不是一个超公平的测试。

我不确定您对cr使用什么值,但是我怀疑您正在使用条件极差的矩阵。(下面的一些Python代码显示它们可能不是最可逆的矩阵。)

>>> import numpy
>>> for n in [100, 1000]:
...     for c in [.1, 1, 10]:
...         for r in [.1, 1, 10]:
...             print numpy.linalg.cond(
...                 numpy.eye(n) + 
...                 c * numpy.ones((n, n)) + 
...                 r * numpy.random.random((n, n))
...             )
... 
25.491634739
2034.47889101
2016.33059429
168.220149133
27340.0090644
5532.81258852
1617.33518781
42490.4410689
5326.3865534
6212.01580004
91910.8386417
50543.9269739
24737.6648458
271579.469212
208913.592289
275153.967337
17021788.5576
117365.924601

如果您实际上需要将这种病态的矩阵求逆,则可以a)使用一种专门的方法,而b)应该只是去寻找一个新的场😉

对于任何大小的条件良好的矩阵,SOR可能会更快。对于速度很重要的实际问题,很少会使用SOR-从复杂的角度来看,如今情况会好得多。从缓慢但可靠的方面来看,SOR并非您能做的最好的事情。


嗨,我不是说我的“测试”是公平的。我什至不会说这是一个测试,这只是我天真的尝试,目的是弄清楚SOR和Gauss-Seidel是如何进行实验的。假设我是这个领域的完整入门者。我的参数在和。为确保矩阵具有强烈的对角线区域性(我使用了尺寸较小的矩阵,尺寸约为〜10)0.01<|c|<0.1r<2|c|
Prokop Hapala 2014年

我要说的是对角线占主导地位。
meawoppl 2014年

0

好的,因此对于该国王的对称矩阵:

1 t 0 0 0 0 t t 0 0 
t 1 0 0 0 0 0 0 0 0 
0 0 1 0 0 0 0 t 0 t 
0 0 0 1 0 0 0 0 0 t 
0 0 0 0 1 t 0 0 0 0 
0 0 0 0 t 1 0 t 0 0 
t 0 0 0 0 0 1 0 0 0 
t 0 t 0 0 t 0 1 0 0 
0 0 0 0 0 0 0 0 1 t 
0 0 t t 0 0 0 0 t 1 

如果每行中的 s的数量很小(远小于A的维数)并且所有 s都相似,则SOR的收敛速度比Gauss-Seidel更快。我正在使用这样生成的:ttt

ti=c+random(r,r)

如果 s变化很大并且在0周围居中(),则比高斯-塞德尔更快。如果每一行被 s 填充的一半以上,Gauss-Seidel也会更快。这也意味着SOR适用于非常大和非常稀疏的矩阵。tc=0,r=0.1t

(这只是皇帝的观察,并不严格)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.