线性方程组迭代法实现

之前有详细介绍过理论部分

线性方程组迭代解法理论

这里给出了 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=5122431210b =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} x k+1=Bx k+f B=D1(L+U)f =D1b

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=5122431210b =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} x k+1=Bx k+f B=(DL)1Uf =(DL)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=5122431210b =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} x k+1=Bx k+f B=(DwL)1((1w)D+wU)f =(DsL)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

你可能感兴趣的:(线性方程组迭代法实现)