Gauss-Jordanの消去法#
ガウスの消去法 (Gauss elimination)、 ガウス=ジョルダンの消去法 (Gauss-Jordan elimination)、あるいは 掃き出し法 と呼ばれる方法。
について考える。
連立1次方程式を
の形に書く。
Gaussの消去法では、前進消去と後退代入という操作によって方程式を解く。
前進消去#
(1) 1番目の未知数
この操作のあとの連立1次方程式は、
とおくと、
となる。
この消去操作において着目した行列要素の位置
(2) 2番目の未知数
以下、このような操作を
ただし、
後退代入#
なので、
として解が求まる。
となっているので
として解が求まる。
これを一般化すると、解は
によって求まる。これを 後退代入 と呼ぶ。
# データの作成
import numpy as np
A = np.array([
[1,2,3],
[4,5,6],
[7,8,0],
])
x_true = np.array([1, 2, 3])
b = A @ x_true
def forward_elimination(A, b):
# 前進消去
n = len(b)
for k in range(n):
for i in range(k + 1, n):
m = A[i,k] / A[k,k]
# numpyのベクトル演算に頼っているが、本来はここもA[i,]の各j要素にわたってfor j in range(n)が必要 → 計算量はO(n^3)
A[i,k:] = A[i,k:] - m * A[k,k:]
b[i] = b[i] - m * b[k]
# print(f"{i=}, {j=}, {m=}")
# print(A)
return A, b
A, b = forward_elimination(A, b)
print(f"{A=}")
print(f"{b=}")
A=array([[ 1, 2, 3],
[ 0, -3, -6],
[ 0, 0, -9]])
b=array([ 14, -24, -27])
def backward_substitution(A, b):
# 後退代入
n = len(b)
x = np.zeros(shape=(n,))
for i in range(n-1, -1, -1):
x[i] = (1 / A[i,i]) * (b[i] - A[i,i+1:] @ x[i+1:])
return x
x = backward_substitution(A, b)
print(f"{x=}")
x=array([1., 2., 3.])
消去法が使える行列#
以下の条件のいずれかを満たす行列
行方向に一般化狭義優対角.
列方向に一般化狭義優対角.
(正則な)
行列.対称部分が正定値:
.
一般化狭義優対角行列
各行において, 対角要素の絶対値が非対角要素の絶対値の和に比べて大きい 行列, すなわち,
を満たす行列
また、正の実数
が成り立つとき,
M行列
正則な実行列
枢軸選択#
枢軸要素
第
import numpy as np
A = np.array([
[-0.001, 6],
[3, 5],
])
x_true = np.array([-1, 1])
b = A @ x_true
print(f"{b=}")
b=array([6.001, 2. ])
A, b = forward_elimination(A, b)
print(f"{A=}")
print(f"{b=}")
x = backward_substitution(A, b)
print(f"{x=}")
A=array([[-1.0000e-03, 6.0000e+00],
[ 0.0000e+00, 1.8005e+04]])
b=array([6.0010e+00, 1.8005e+04])
x=array([-1., 1.])
スケーリング#
各方程式にゼロでない定数を掛けることをスケーリングと呼ぶ。
数学的には解は不変のはずだが、枢軸選択の結果はスケーリングに依存してしまう問題がある。
参考文献#
杉原正顯, & 室田一雄. (2009). 線形計算の数理. 岩波書店.