1.迭代法
设有线性方程组
{
a
11
x
1
+
a
12
x
2
+
⋯
+
a
1
n
x
n
=
b
1
,
a
21
x
1
+
a
22
x
2
+
⋯
+
a
2
n
x
n
=
b
2
,
⋮
a
n
1
x
1
+
a
n
2
x
2
+
⋯
+
a
n
n
x
n
=
b
n
,
\begin{cases} a_{11}x_1&+&a_{12}x_2&+&\cdots&+a_{1n}x_n&=&b_1,\\ a_{21}x_1&+&a_{22}x_2&+&\cdots&+a_{2n}x_n&=&b_2,\\ \vdots\\ a_{n1}x_1&+&a_{n2}x_2&+&\cdots&+a_{nn}x_n&=&b_n,& \end{cases}
⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧a11x1a21x1⋮an1x1+++a12x2a22x2an2x2+++⋯⋯⋯+a1nxn+a2nxn+annxn===b1,b2,bn,现将该线性方程组改写为
{
x
1
=
1
a
11
(
−
a
12
x
2
−
⋯
−
a
1
n
x
n
+
b
1
)
,
x
2
=
1
a
22
(
−
a
21
x
1
−
a
23
x
3
−
⋯
−
a
2
n
x
n
+
b
2
)
,
⋮
x
n
=
1
a
n
n
(
−
a
n
1
x
1
−
a
n
2
x
2
−
⋯
−
a
n
n
−
1
x
n
−
1
+
b
n
)
;
(
1
)
\begin{cases} x_1=\dfrac{1}{a_{11}}(-a_{12}x_2&-\cdots&&-a_{1n}x_n&+&b_1),\\ x_2=\dfrac{1}{a_{22}}(-a_{21}x_1&-a_{23}x_3&-\cdots&-a_{2n}x_n&+&b_2),\\ \vdots\\ x_n=\dfrac{1}{a_{nn}}(-a_{n1}x_1&-a_{n2}x_2&-\cdots&-a_{nn-1}x_{n-1}&+&b_n); (1) \end{cases}
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧x1=a111(−a12x2x2=a221(−a21x1⋮xn=ann1(−an1x1−⋯−a23x3−an2x2−⋯−⋯−a1nxn−a2nxn−ann−1xn−1+++b1),b2),bn);(1)或者写为
x
=
B
0
x
+
f
,
x=B_0x+f,
x=B0x+f,其中
B
0
=
[
0
−
a
12
a
11
−
a
13
a
11
…
−
a
1
n
a
11
−
a
21
a
22
0
−
a
23
a
22
…
−
a
2
n
a
22
−
a
31
a
33
−
a
32
a
33
0
…
−
a
3
n
a
33
⋮
⋮
⋮
⋱
⋮
−
a
n
1
a
n
n
−
a
n
2
a
n
n
…
−
a
n
n
−
1
a
n
n
0
]
,
f
=
[
b
1
a
11
b
2
a
22
b
3
a
33
⋮
b
n
a
n
n
]
B_0=\begin{bmatrix} 0&-\dfrac{a_{12}}{a_{11}}&-\dfrac{a_{13}}{a_{11}}&\ldots&-\dfrac{a_{1n}}{a_{11}}\\ -\dfrac{a_{21}}{a_{22}}&0&-\dfrac{a_{23}}{a_{22}}&\ldots&-\dfrac{a_{2n}}{a_{22}}\\ -\dfrac{a_{31}}{a_{33}}&-\dfrac{a_{32}}{a_{33}}&0&\ldots&-\dfrac{a_{3n}}{a_{33}}\\ \vdots&\vdots&\vdots&\ddots&\vdots\\ -\dfrac{a_{n1}}{a_{nn}}&-\dfrac{a_{n2}}{a_{nn}}&\ldots&-\dfrac{a_{nn-1}}{a_{nn}}&0 \end{bmatrix}, f=\begin{bmatrix} \dfrac{b_1}{a_{11}}\\ \dfrac{b_2}{a_{22}}\\ \dfrac{b_3}{a_{33}}\\ \vdots\\ \dfrac{b_n}{a_{nn}} \end{bmatrix}
B0=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡0−a22a21−a33a31⋮−annan1−a11a120−a33a32⋮−annan2−a11a13−a22a230⋮…………⋱−annann−1−a11a1n−a22a2n−a33a3n⋮0⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤,f=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡a11b1a22b2a33b3⋮annbn⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
任取初始值
x
(
0
)
=
(
0
,
0
,
…
,
0
)
T
x^{(0)}=(0,0,\ldots,0)^T
x(0)=(0,0,…,0)T,将其带入(1)式右边,得到新的值
x
(
1
)
=
(
x
1
(
1
)
,
x
2
(
1
)
,
…
,
x
n
(
1
)
)
T
x^{(1)}=(x_1^{(1)},x_2^{(1)},\ldots,x_n^{(1)})^T
x(1)=(x1(1),x2(1),…,xn(1))T
再将
x
(
1
)
x^{(1)}
x(1)带入右边,反复进行从而可以得到一个向量序列
x
(
k
+
1
)
=
B
x
(
k
)
+
f
,
k
=
0
,
1
,
2
,
…
,
(
2
)
x^{(k+1)}=Bx^{(k)}+f,k=0,1,2,\ldots,(2)
x(k+1)=Bx(k)+f,k=0,1,2,…,(2)其中k表示迭代次数.
迭代法及其收敛性定义
(1)对于给定的线性方程组
x
=
B
x
+
f
,
x=Bx+f,
x=Bx+f,用公式(2)逐步带入求近似解的方法称为迭代法(或一阶定常迭代法,这里
B
与
k
B与k
B与k无关).
(2)如果
lim
k
→
∞
x
(
k
)
存
在
(
记
为
x
∗
)
,
\lim\limits_{k \to \infty}x^{(k)}存在(记为x^{*}),
k→∞limx(k)存在(记为x∗),称次迭代法收敛,显然
x
∗
x^{*}
x∗就是此方程的解,否则称此迭代法发散.
2.雅可比迭代法(Jacobi)
将线性方程组
A
x
=
b
Ax=b
Ax=b中的系数矩阵
A
=
(
a
i
j
)
∈
R
n
×
n
A=(a_{ij})\in \mathbb{R}^{n\times n}
A=(aij)∈Rn×n分成三部分
A
=
[
a
11
a
22
⋱
a
n
n
]
−
[
0
−
a
21
0
⋮
⋮
⋱
−
a
n
−
1
,
1
−
a
n
−
1
,
2
…
0
−
a
n
1
−
a
n
2
…
−
a
n
,
n
−
1
0
]
−
[
0
−
a
12
…
−
a
1
,
n
−
1
−
a
1
n
0
…
−
a
2
,
n
−
1
−
a
2
n
⋱
⋮
⋮
0
−
a
n
−
1
,
n
0
]
≡
D
−
L
−
U
.
A=\begin{bmatrix} a_{11}&&&\\ &a_{22}&&\\ &&\ddots&\\ &&&a_{nn} \end{bmatrix}- \begin{bmatrix} 0&&&&\\ -a_{21}&0&&&\\ \vdots&\vdots&\ddots&&\\ -a_{n-1,1}&-a_{n-1,2}&\ldots&0\\ -a_{n1}&-a_{n2}&\ldots&-a_{n,n-1}&0 \end{bmatrix}- \begin{bmatrix} 0&-a_{12}&\ldots&-a_{1,n-1}&-a_{1n}\\ &0&\ldots&-a_{2,n-1}&-a_{2n}\\ &&\ddots&\vdots&\vdots\\ &&&0&-a_{n-1,n}\\ &&&&0 \end{bmatrix}\equiv D-L-U.
A=⎣⎢⎢⎡a11a22⋱ann⎦⎥⎥⎤−⎣⎢⎢⎢⎢⎢⎡0−a21⋮−an−1,1−an10⋮−an−1,2−an2⋱……0−an,n−10⎦⎥⎥⎥⎥⎥⎤−⎣⎢⎢⎢⎢⎢⎡0−a120……⋱−a1,n−1−a2,n−1⋮0−a1n−a2n⋮−an−1,n0⎦⎥⎥⎥⎥⎥⎤≡D−L−U.
设
a
i
i
≠
0
(
i
=
1
,
2
,
…
,
n
)
,
a_{ii}\neq 0(i=1,2,\ldots,n),
aii=0(i=1,2,…,n),选取
M
M
M为
A
A
A的对角元素部分,即选取
M
=
D
(
对
角
矩
阵
)
,
A
=
D
−
N
,
M=D(对角矩阵),A=D-N,
M=D(对角矩阵),A=D−N,得到解
A
x
=
b
Ax=b
Ax=b的雅可比(Jacobi)迭代法
{
x
(
0
)
,
初始向量,
x
(
k
+
1
)
=
B
x
(
k
)
+
f
,
k
=
0
,
1
,
2
,
…
,
\begin{cases} x^{(0)},\text{初始向量,}\\ x^{(k+1)}=Bx^{(k)}+f,k=0,1,2,\ldots, \end{cases}
{x(0),初始向量,x(k+1)=Bx(k)+f,k=0,1,2,…,
其中
B
=
I
−
D
−
1
A
=
D
−
1
(
L
+
U
)
≡
J
,
f
=
D
−
1
b
.
B=I-D^{-1}A=D^{-1}(L+U)\equiv J,f=D^{-1}b.
B=I−D−1A=D−1(L+U)≡J,f=D−1b.称
J
为
A
x
=
b
J为Ax=b
J为Ax=b的雅可比迭代法的迭代矩阵.
3.高斯-赛德尔迭代法(Gauss-Seidel)
选取分裂矩阵
M
为
A
M为A
M为A的下三角部分,即选取
M
=
D
−
L
(
下
三
角
矩
阵
)
,
A
=
M
−
N
,
于
是
得
到
解
A
x
=
b
的
高
斯
−
赛
德
尔
迭
代
法
.
M=D-L(下三角矩阵),A=M-N,于是得到解Ax=b的高斯-赛德尔迭代法.
M=D−L(下三角矩阵),A=M−N,于是得到解Ax=b的高斯−赛德尔迭代法.
{
x
(
0
)
,
初始向量,
x
(
k
+
1
)
=
B
x
(
k
)
+
f
,
k
=
0
,
1
,
2
,
…
,
\begin{cases} x^{(0)},\text{初始向量,}\\ x^{(k+1)}=Bx^{(k)}+f,k=0,1,2,\ldots, \end{cases}
{x(0),初始向量,x(k+1)=Bx(k)+f,k=0,1,2,…,
其中
B
=
I
−
(
D
−
L
)
−
1
A
=
(
D
−
L
)
−
1
U
≡
G
,
f
=
(
D
−
L
)
−
1
b
.
B=I-(D-L)^{-1}A=(D-L)^{-1}U\equiv G,f=(D-L)^{-1}b.
B=I−(D−L)−1A=(D−L)−1U≡G,f=(D−L)−1b.
称
G
=
(
D
−
L
)
−
1
U
为
解
A
x
=
b
G=(D-L)^{-1}U为解Ax=b
G=(D−L)−1U为解Ax=b的高斯-赛德尔迭代法的迭代矩阵.
4.逐次超松弛迭代法(SOR)
选取分裂矩阵
M
M
M为带参数的下三角矩阵
M
=
1
ω
(
D
−
ω
L
)
,
M=\frac{1}{\omega }(D-\omega L),
M=ω1(D−ωL),
其中
ω
>
0
\omega >0
ω>0为可选择的松弛因子.于是可以构造一个迭代矩阵
L
ω
≡
I
−
ω
(
D
−
ω
L
)
−
1
A
=
(
D
−
ω
L
)
−
1
(
(
1
−
ω
)
D
+
ω
U
)
.
L_{\omega}\equiv I-\omega(D-\omega L)^{-1}A=(D-\omega L)^{-1}((1-\omega)D+\omega U).
Lω≡I−ω(D−ωL)−1A=(D−ωL)−1((1−ω)D+ωU).
从而得到解
A
x
=
b
Ax=b
Ax=b的逐次超松弛迭代法(successive over relaxation method,简称SOR方法).
解
A
x
=
b
Ax=b
Ax=b的SOR方法为
{
x
(
0
)
,
初始向量,
x
(
k
+
1
)
=
L
ω
x
(
k
)
+
f
,
k
=
0
,
1
,
…
,
\begin{cases} x^{(0)},\text{初始向量,}\\ x^{(k+1)}=L_{\omega}x^{(k)}+f,k=0,1,\ldots, \end{cases}
{x(0),初始向量,x(k+1)=Lωx(k)+f,k=0,1,…,
其中
L
ω
=
(
D
−
ω
L
)
−
1
(
(
1
−
ω
)
D
+
ω
U
)
,
f
=
ω
(
D
−
ω
L
)
−
1
b
.
L_{\omega}=(D-\omega L)^{-1}((1-\omega)D+\omega U),f=\omega (D-\omega L)^{-1}b.
Lω=(D−ωL)−1((1−ω)D+ωU),f=ω(D−ωL)−1b.
5.Python实现三种迭代法
import numpy as np
from scipy.linalg import eigvals, inv
def vector_norm(vector: np.ndarray, p=None):
"""
计算向量的p-范数
:param vector: 实向量或者复向量
:param p: 指定类型的范数,默认是oo范数
:return: 指定向量范数和p值
"""
if p is None:
return abs(vector).max(), p
elif p >= 1:
return np.power(np.sum(np.power(abs(vector), p)), 1 / p), p
else:
raise Exception("error,p must be an integer , greater than or equal to 1")
def jacobi(coefficient_matrix: np.ndarray,
right_hand_side_vector: np.ndarray,
initial_vector: np.ndarray, epsilon=1e-4):
d = np.diag(np.diag(coefficient_matrix))
l = -np.tril(coefficient_matrix, k=-1)
u = -np.triu(coefficient_matrix, k=1)
jacobi_matrix = inv(d) @ (l + u)
if spectral_radius(jacobi_matrix) < 1:
f = inv(d) @ right_hand_side_vector
x_1 = initial_vector
x_2 = jacobi_matrix @ x_1 + f
iteration_count = 1
while 1:
norm, _ = vector_norm(x_2 - x_1)
if norm < epsilon:
return x_2, iteration_count
x_1 = x_2
x_2 = jacobi_matrix @ x_1 + f
iteration_count += 1
raise Exception("jacobi iteration is not convergent")
def gauss_seidel(coefficient_matrix: np.ndarray,
right_hand_side_vector: np.ndarray,
initial_vector: np.ndarray, epsilon=1e-4):
d = np.diag(np.diag(coefficient_matrix))
l = -np.tril(coefficient_matrix, k=-1)
u = -np.triu(coefficient_matrix, k=1)
gauss_seidel_matrix = inv(d - l) @ u
if spectral_radius(gauss_seidel_matrix) < 1:
f = inv(d - l) @ right_hand_side_vector
x_1 = initial_vector
x_2 = gauss_seidel_matrix @ x_1 + f
iteration_count = 1
while 1:
norm, _ = vector_norm(x_2 - x_1)
if norm < epsilon:
return x_2, iteration_count
x_1 = x_2
x_2 = gauss_seidel_matrix @ x_1 + f
iteration_count += 1
raise Exception("jacobi iteration is not convergent")
def successive_over_relaxation(coefficient_matrix: np.ndarray,
right_hand_side_vector: np.ndarray,
initial_vector: np.ndarray,
true_solution: np.ndarray, omega=1.0, epsilon=5e-6):
d = np.diag(np.diag(coefficient_matrix))
l = -np.tril(coefficient_matrix, k=-1)
u = -np.triu(coefficient_matrix, k=1)
l_omega = inv(d - omega * l) @ ((1 - omega) * d + omega * u)
if spectral_radius(l_omega) < 1:
f = omega * inv(d - omega * l) @ right_hand_side_vector
x = l_omega @ initial_vector + f
iteration_count = 1
while 1:
norm, _ = vector_norm(true_solution - x)
if norm < epsilon:
return x, iteration_count
x = l_omega @ x + f
iteration_count += 1
raise Exception("jacobi iteration is not convergent")
def hilbert_matrix(order: int):
hilbert = np.zeros((order, order))
for i in range(order):
for j in range(order):
hilbert[i, j] = 1 / (i + j + 1)
return hilbert
def spectral_radius(square_matrix: np.ndarray):
if square_matrix.shape[0] == square_matrix.shape[1]:
return abs(eigvals(square_matrix)).max()
raise Exception("\n{} is not a square matrix".format(square_matrix))