SORがGauss-Seidelよりも高速であるような問題ですか?


9

Gauss-Seidelの代わりにSORを実行する価値があるかどうかを言う簡単な経験則はありますか?(そして、再帰パラメータを推定するための可能な方法)ω

私は単にマトリックスを見ることを意味しますか、またはマトリックスが表す特定の問題の知識?

私はこの質問の答えを読んでいました: 逐次過剰緩和(SOR)法を最適化するためのヒューリスティックはありますか? しかし、それは少し洗練されすぎています。マトリックス(またはそれが表す問題)を見ているだけで、スペクトル半径を推定する簡単なヒューリスティックがわかりません。

もっと単純なものが欲しい-SORがより速く収束する行列(問題)のほんの数例


私はこの王の行列に対してSORで実験した: 恒等行列であり、及び sはそのようunifrom分布から乱数であります。最適ながパラメーターある程度依存すると考えていました。I C I J = C I J R I J | R i j | < R ω C R=+C+RCj=c jRj|Rj|<rωcr

編集:私は非常に小さなを使用してが強く対角線的に支配的であることを確認しました。(、は次元5-10の行列の場合)。また、これらのは実対称であったとも言えます。A | c | < 0.1 r < 2 | c | cr|c|<0.1r<2|c|

ただし、Gauss-Seidel()がほとんど常に最適(?)ω=1であることがわかりました。これは、SORを利用するために間にさらに相関が必要なことを意味しますか?または私は何か間違ったことをしましたか? j


SORは(CG、GMRES ...と比較して)最も効率的なソルバーではありませんが、特定の問題を実装してパラレライズし、修正するのは簡単です。確かにプロトタイピングに適しています。

回答:


5

線形システムの従来の反復ソルバーの収束は、反復行列のスペクトル半径によって決定されます。一般的な線形システムでは、反復行列のスペクトル半径を決定するのが難しいため、最適な(または良い)SORパラメーターを決定することは困難です。以下に、最適なSOR重みがわかっている実際の問題の例を含む、多くの詳細を追加しました。ρ(G)

スペクトル半径と収束

スペクトル半径は、最大振幅固有値の絶対値として定義されます。で、スペクトル半径が小さいほど収束が速い場合、メソッドは収束します。SORは、重み付けパラメーター選択に基づいて反復行列を導出するために使用される行列分割を変更することで機能し、できれば結果の反復行列のスペクトル半径を小さくします。ωρ<1ω

マトリックス分割

以下の議論では、解くシステムは

Ax=b,

フォームの反復あり

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

ここで、はベクトルであり、反復番号はます。k x k vkx(k)

SORは、古い反復とGauss-Seidel反復の加重平均を取ります。ガウスザイデル法は、フォームの行列分割に依存しています

A=D+L+U

ここで、は対角、は対角の真下にあるすべての要素を含む下三角行列、は上三角行列です対角線の真上にあるすべての要素を含みます。ガウスザイデルの反復は、A L A R ADALARA

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

最適な重み係数がわかっている現実的な例の1つは、ポアソン方程式を解くコンテキストで発生します。

2u=f in Ωu=g on Ω

均一なグリッド間隔の2次有限差分を使用して、2Dの正方形領域でこのシステムを離散化すると、対角線上に4、対角線の真上と真下に-1、および-1から少し離れた2つのバンドをもつ対称バンドマトリックスが生成されます。対角線。境界条件による違いはありますが、それが基本的な構造です。この行列が与えられた場合、SOR係数の証明可能な最適な選択は、

ω=21+sin(πΔx/L

ここで、はグリッド間隔、はドメインサイズです。既知のソリューションを使用した単純なケースでこれを行うと、これらの2つの方法について次のエラーと反復数が得られます。ΔバツL

Gauss-Seidelおよび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を掛けるべきだと思いました。この係数は、離散2次導関数に由来します(たとえば、こちらを参照してください)。ところで、これを行うと、アルゴリズムが正しく機能しません。なぜなのかご存知ですか?
shamalaia 2018年

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はあなたができる最善ではありません。


0.01<|c|<0.1r<2|c|

私は強く対角線的に支配的に言うつもりでした。
meawoppl 2014

0

OK、このキングの対称行列の場合:

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 

ttt

t=c+radoメートルrr

tc=0r=0.1t

(これは単なる経験的観察であり、厳密なものではありません)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.