数値線形代数において、ガウス・ザイデル法(リープマン法または逐次変位法とも呼ばれる)は、連立一次方程式を解くための反復法である。この方法は、ドイツの数学者カール・フリードリヒ・ガウスとフィリップ・ルートヴィヒ・フォン・ザイデルにちなんで名付けられた。対角要素がゼロでない任意の行列に適用できるが、収束が保証されるのは、行列が厳密に対角優位である場合[ 1 ]、または対称かつ正定値である場合のみである。この方法は、 1823年にガウスが教え子のゲルリングに宛てた私信の中で言及されただけである[ 2 ]。ザイデルによる出版物は1874年以前には発表されなかった[ 3 ] 。
させてn個の線形方程式からなる正方システムとする。
いつそして知られていること、そしてが不明な場合、ガウス・ザイデル法を用いて反復的に近似することができる。ベクトル初期推定値を表す、 頻繁のためにで表すのの 番目の近似または反復、そして近似値次の(または第 1 回反復。
解は反復的に得られる 行列下三角成分に分解される、そして厳密に上三角関数の成分そのため[ 4 ]より具体的には、の中へそして次のように与えられます。
この連立一次方程式は次のように書き換えることができます。
ガウス・ザイデル法では、この式の左辺を解いて以前の値を使用して右側。解析的には、これは次のように書ける。
しかし、三角形の形状を利用することで要素各行について順次計算できます前方代入法を用いる:[ 5 ]
この式では、反復ごとに 2 つの総和が使用されていますが、これは 1 つの総和として表現できます。これは、最近計算された反復処理を使用します。手順は一般的に、反復によって行われた変更が、十分に小さな残差などの許容範囲を下回るまで続けられます。
ガウス・ザイデル法の要素ごとの公式は、(反復)ヤコビ法の公式と関連しているが、重要な違いがある。
ガウス・ザイデル法では、要素を使用するすでに計算されている要素のみ計算されていないこれは、ヤコビ法とは異なり、要素が計算されるにつれて上書きできるため、必要なストレージベクトルは1つだけで済むことを意味し、非常に大規模な問題に対して有利となる場合があります。
しかし、ヤコビ法とは異なり、各要素の計算は一般的に並列処理が非常に困難であり、クリティカルパスが非常に長くなる可能性があるため、疎行列の場合に最も適しています。さらに、各反復における値は、元の方程式の次数に依存します。
ガウス・ザイデル法は、次の過緩和法と同じです。。
ガウス・ザイデル法の収束特性は行列に依存するすなわち、以下のいずれかの条件が満たされる場合、この手順は収束することが知られている。
ガウス・ザイデル法は、これらの条件が満たされない場合でも収束する可能性がある。
ゴルブとヴァン・ローンは、分割するアルゴリズムの定理を与えている。2つの部分に分けます。は非特異である。スペクトル半径は.次に反復します定義される収束する任意の開始ベクトルに対してもしは非単数であり、[ 8 ]
このアルゴリズムでは要素は計算時に上書きできるため、必要なストレージベクトルは1つだけで済み、ベクトルのインデックス付けは省略されます。アルゴリズムは以下のとおりです。
ガウス・ザイデル法アルゴリズムは、入力:A、b、出力:φです。解の初期推定値φを選択し、収束するまで 繰り返します。iを 1からnまで実行し、 σ ← 0 とします。 jを1からnまで実行し、 j ≠ iの場合、σ ← σ + a ij φ jとします。 jループ終了φ i ← ( b i − σ ) / a ii ( iループ終了) 収束に達したかどうかを確認する 終了(繰り返し)
線形システムとして以下のように表される次のように与えられます。
方程式を使用する 形式で どこ:
分解する下三角成分の合計にそして厳密な上三角成分:
逆は:
次に以下を探してください:
とそしてベクトル反復的に取得できる。
まず最初に、、 例えば推測値が最終解に近いほど、アルゴリズムに必要な反復回数は少なくなる。
次に計算します。
予想通り、アルゴリズムは解に収束する。 。
実際、行列Aは厳密には対角優位行列ではあるが、正定値行列ではない。
別の線形システムとして示されている次のように与えられます。
方程式を使用する 形式で どこ:
分解する下三角成分の合計にそして厳密な上三角成分:
逆は:
次に以下を探してください:
とそしてベクトル反復的に取得できる。
まず最初に、私たちは選択しなければなりません、 例えば
次に計算します。
収束テストでは、アルゴリズムが発散することがわかります。実際、行列は対角優位でも正定値でもない。すると、厳密解への収束が起こる。 保証されるものではなく、この場合、発生しません。
与えられたと仮定する方程式と出発点ガウス・ザイデル反復法のどのステップでも、最初の式を解いてに関しては;次に2番目の方程式を解いてに関しては発見されたばかりで、残りの; そして、そして、収束が達成されるまで反復計算を繰り返すか、解の発散が事前に定義されたレベルを超えて発散し始めた場合は処理を中断する。
例を挙げて考えてみましょう。
解決するそして与える:
初期近似値が (0, 0, 0, 0)であると仮定すると、最初の近似解は次のように与えられます。
得られた近似値を用いて、所望の精度に達するまで反復手順を繰り返す。以下は、4回の反復後の近似解である。
このシステムの正確な解は(1, 2, −1, 1)です。
以下の反復手順により、線形方程式系の解ベクトルが得られます。
import numpy as np反復回数制限= 1000# 行列を初期化しますA = np.array ( [ [ 10.0 , -1.0 , 2.0 , 0.0 ] , [ -1.0 , 11.0 , -1.0 , 3.0 ] , [ 2.0 , -1.0 , 10.0 , -1.0 ] , [ 0.0 , 3.0 , -1.0 , 8.0 ] , ] ) # 右辺ベクトルを初期化しますb = np.array ( [ 6.0 , 25.0 , -11.0 , 15.0 ] )print ( "連立方程式:" ) for i in range ( A.shape [ 0 ]): row = " + " .join ( f " { A [ i , j ] : 3g } *x { j + 1 } " for j in range ( A.shape [ 1 ] ) ) print ( f " [ { row } ] = [ { b [ i ] : 3g } ] " )x = np.zeros_like ( b ) for it_count in range ( 1 , ITERATION_LIMIT ) : x_new = np.zeros_like ( x ) print ( f " Iteration { it_count } : { x } " ) for i in range ( A.shape [ 0 ] ) : s1 = A [ i , : i ] @ x_new [: i ] s2 = A [ i , i + 1 : ] @ x [ i + 1 :] x_new [ i ] = ( b [ i ] - s1 - s2 ) / A [ i , i ] if np.allclose ( x , x_new , rtol = 1e - 8 ) : break x = x_newprint ( f "解答: { x } " ) error = A @ x - b print ( f "エラー: { error } " )出力結果は以下のとおりです。
連立方程式: [ 10*x1 + -1*x2 + 2*x3 + 0*x4] = [ 6] [ -1*x1 + 11*x2 + -1*x3 + 3*x4] = [ 25] [ 2*x1 + -1*x2 + 10*x3 + -1*x4] = [-11] [ 0*x1 + 3*x2 + -1*x3 + 8*x4] = [ 15]反復 1: [ 0. 0. 0. 0.]反復 2: [ 0.6 2.32727273 -0.98727273 0.87886364]反復 3: [ 1.03018182 2.03693802 -1.0144562 0.98434122]反復4: [ 1.00658504 2.00355502 -1.00252738 0.99835095]反復 5: [ 1.00086098 2.00029825 -1.00030728 0.99984975]反復 6: [ 1.00009128 2.00002134 -1.00003115 0.9999881 ]反復 7: [ 1.00000836 2.00000117 -1.00000275 0.99999922]反復 8: [ 1.00000067 2.00000002 -1.00000021 0.99999996]反復 9: [ 1.00000004 1.99999999 -1.00000001 1. ]反復 10: [ 1. 2. -1. 1.]解: [ 1. 2. -1. 1.]エラー: [ 2.06480930e-08 -1.25551054e-08 3.61417563e-11 0.00000000e+00]以下のコードは、数式を使用します。
function x = gauss_seidel ( A, b, x, iters ) for i = 1 : iters for j = 1 : size ( A , 1 ) x ( j ) = ( b ( j ) - sum ( A ( j ,:) '.* x ) + A ( j , j ) * x ( j )) / A ( j , j );終わり終わり終わりこの記事は、 GFDLライセンスの下で公開されているCFD-Wikiの記事「Gauss-Seidel_method」のテキストを組み込んでいます。