之前有详细介绍过理论部分
线性方程组迭代解法理论
这里给出了 3 × 3 3 \times 3 3×3矩阵作为系数矩阵迭代解法的python实现
1. 雅可比迭代法
求解方程为 A x ⃗ = b ⃗ A\vec{x} = \vec{b} Ax=b,具体值如下
A = [ 5 2 1 − 1 4 2 2 − 3 10 ] b ⃗ = [ − 12 20 3 ] A = \left[\begin{matrix} 5& 2& 1\\ -1& 4& 2\\ 2& -3& 10 \end{matrix}\right] \quad \vec{b} = \left[\begin{matrix} -12\\ 20\\ 3 \end{matrix}\right] A=⎣⎡5−1224−31210⎦⎤b=⎣⎡−12203⎦⎤
代码中的符号和推导时的符号一样,具体含义如下
{ x ⃗ k + 1 = B x ⃗ k + f ⃗ B = D − 1 ( L + U ) f ⃗ = D − 1 b ⃗ \begin{cases} \vec{x}_{k + 1} = B\vec{x}_k + \vec{f}\\ B = D^{-1}(L + U)\\ \vec{f} = D^{-1}\vec{b} \end{cases} ⎩⎪⎨⎪⎧xk+1=Bxk+fB=D−1(L+U)f=D−1b
import numpy as np
ERROR = 0.001
A = np.array([[5, 2, 1],
[-1, 4, 2],
[2, -3, 10]])
b = np.array([[-12], [20], [3]])
m, n = np.shape(A)
D = np.mat(np.zeros((m, n)))
L = np.mat(np.zeros((m, n)))
U = np.mat(np.zeros((m, n)))
for i in range(m):
for j in range(n):
if i == j:
D[i, j] = A[i, j]
if i < j:
L[i, j] = -A[i, j]
if i > j:
U[i, j] = -A[i, j]
x0 = np.array(np.zeros((m, 1)))
xk = np.array(np.zeros((m, 1)))
B = np.dot(D.I, (L + U))
f = np.dot(D.I, b)
print("B:", B)
print("f:", f)
iter_time = 1
xk = np.dot(B, x0) + f
while(np.linalg.norm((xk - x0)) >= ERROR):
iter_time += 1
print(xk)
x0 = xk
xk = np.dot(B, xk) + f
print("The iteration time: %d" %iter_time)
在运行结果中可以看到一共迭代了14次,中间过程输出省略,只显示最后两次向量 x ⃗ \vec{x} x的迭代结果
[[-4.00122406]
[ 3.00000859]
[ 2.00098719]]
[[-4.00020088]
[ 2.99920039]
[ 2.00024739]]
The iteration time: 14
2. G-S迭代法
求解方程为 A x ⃗ = b ⃗ A\vec{x} = \vec{b} Ax=b,具体值如下
A = [ 5 2 1 − 1 4 2 2 − 3 10 ] b ⃗ = [ − 12 20 3 ] A = \left[\begin{matrix} 5& 2& 1\\ -1& 4& 2\\ 2& -3& 10 \end{matrix}\right] \quad \vec{b} = \left[\begin{matrix} -12\\ 20\\ 3 \end{matrix}\right] A=⎣⎡5−1224−31210⎦⎤b=⎣⎡−12203⎦⎤
代码中的符号和推导时的符号一样,具体含义如下
{ x ⃗ k + 1 = B x ⃗ k + f ⃗ B = ( D − L ) − 1 U f ⃗ = ( D − L ) − 1 b ⃗ \begin{cases} \vec{x}_{k + 1} = B\vec{x}_k + \vec{f}\\ B = (D - L)^{-1}U\\ \vec{f} = (D - L)^{-1}\vec{b} \end{cases} ⎩⎪⎨⎪⎧xk+1=Bxk+fB=(D−L)−1Uf=(D−L)−1b
import numpy as np
ERROR = 0.001
A = np.array([[5, 2, 1],
[-1, 4, 2],
[2, -3, 10]])
b = np.array([[-12], [20], [3]])
m, n = np.shape(A)
D = np.mat(np.zeros((m, n)))
L = np.mat(np.zeros((m, n)))
U = np.mat(np.zeros((m, n)))
for i in range(m):
for j in range(n):
if i == j:
D[i, j] = A[i, j]
if i < j:
L[i, j] = -A[i, j]
if i > j:
U[i, j] = -A[i, j]
x0 = np.array(np.zeros((m, 1)))
xk = np.array(np.zeros((m, 1)))
B = np.dot((D - L).I, U)
f = np.dot((D - L).I, b)
print("B:", B)
print("f:", f)
iter_time = 1
xk = np.dot(B, x0) + f
while(np.linalg.norm((xk - x0)) >= ERROR):
iter_time += 1
print(xk)
x0 = xk
xk = np.dot(B, xk) + f
print("The iteration time: %d" %iter_time)
在运行结果中可以看到一共迭代了7次,说明比雅可比迭代法收敛速度要快。中间过程输出省略,只显示最后两次向量 x ⃗ \vec{x} x的迭代结果
[[-4.00004 ]
[ 3.00207406]
[ 1.99605188]]
[[-3.999996 ]
[ 2.99967489]
[ 2.00063022]]
The iteration time: 7
3. 逐次超松弛迭代法(SOR)
求解方程为 A x ⃗ = b ⃗ A\vec{x} = \vec{b} Ax=b,具体值如下
A = [ 5 2 1 − 1 4 2 2 − 3 10 ] b ⃗ = [ − 12 20 3 ] A = \left[\begin{matrix} 5& 2& 1\\ -1& 4& 2\\ 2& -3& 10 \end{matrix}\right] \quad \vec{b} = \left[\begin{matrix} -12\\ 20\\ 3 \end{matrix}\right] A=⎣⎡5−1224−31210⎦⎤b=⎣⎡−12203⎦⎤
代码中的符号和推导时的符号一样,具体含义如下
{ x ⃗ k + 1 = B x ⃗ k + f ⃗ B = ( D − w L ) − 1 ( ( 1 − w ) D + w U ) f ⃗ = ( D − s L ) − 1 w b ⃗ \begin{cases} \vec{x}_{k + 1} = B\vec{x}_k + \vec{f}\\ B = (D - wL)^{-1}((1-w)D + wU)\\ \vec{f} = (D - sL)^{-1}w\vec{b} \end{cases} ⎩⎪⎨⎪⎧xk+1=Bxk+fB=(D−wL)−1((1−w)D+wU)f=(D−sL)−1wb
import numpy as np
ERROR = 0.001
w = 0.9
A = np.array([[5, 2, 1],
[-1, 4, 2],
[2, -3, 10]])
b = np.array([[-12], [20], [3]])
m, n = np.shape(A)
D = np.mat(np.zeros((m, n)))
L = np.mat(np.zeros((m, n)))
U = np.mat(np.zeros((m, n)))
for i in range(m):
for j in range(n):
if i == j:
D[i, j] = A[i, j]
if i < j:
L[i, j] = -A[i, j]
if i > j:
U[i, j] = -A[i, j]
# print(A)
# print(D)
# print(L)
# print(U)
x0 = np.array(np.zeros((m, 1)))
xk = np.array(np.zeros((m, 1)))
temp_mat = (D - w * L).I
B = np.dot(temp_mat, (1 - w) * D + w * U)
f = np.dot(temp_mat, b)
print("B:", B)
print("f:", f)
iter_time = 1
xk = np.dot(B, x0) + f
while(np.linalg.norm((xk - x0)) >= ERROR):
iter_time += 1
print(xk)
x0 = xk
xk = np.dot(B, xk) + f
print("The iteration time: %d" %iter_time)
在运行结果中可以看到一共迭代了7次,说明比雅可比迭代法收敛速度要快,但是SOR迭代法和G-S迭代法速度差不多,其实G-S迭代法只是w = 1时的SOR迭代法。中间过程输出省略,只显示最后两次向量 x ⃗ \vec{x} x的迭代结果
[[-4.44425225]
[ 3.33368384]
[ 2.22092673]]
[[-4.44445216]
[ 3.33344291]
[ 2.22215271]]
The iteration time: 7