1.追赶法原理
解系数矩阵为对角占优的三对角线方程组
[
b
1
c
1
a
2
b
2
c
2
⋱
⋱
⋱
a
n
−
1
b
n
−
1
c
n
−
1
a
n
b
n
]
[
x
1
x
2
⋮
x
n
−
1
x
n
]
=
[
f
1
f
2
⋮
f
n
−
1
f
n
]
,
\begin{bmatrix} b_1&c_1&&&\\ a_2&b_2&c_2&&\\ &\ddots&\ddots&\ddots&\\ &&a_{n-1}&b_{n-1}&c_{n-1}\\ &&&a_n&b_n \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ \vdots\\ x_{n-1}\\ x_n \end{bmatrix}= \begin{bmatrix} f_1\\ f_2\\ \vdots\\ f_{n-1}\\ f_n \end{bmatrix},
⎣⎢⎢⎢⎢⎡b1a2c1b2⋱c2⋱an−1⋱bn−1ancn−1bn⎦⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎡x1x2⋮xn−1xn⎦⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎡f1f2⋮fn−1fn⎦⎥⎥⎥⎥⎥⎤,
简记为
A
x
=
f
.
Ax=f.
Ax=f.其中,当
∣
i
−
j
∣
>
1
|i-j|>1
∣i−j∣>1时,
a
i
j
=
1
,
a_{ij}=1,
aij=1,且:
∣
b
1
∣
>
∣
c
1
∣
>
0
;
| b_1| >| c_1| >0;
∣b1∣>∣c1∣>0;
∣
b
i
∣
≥
∣
a
i
∣
+
∣
c
i
∣
,
a
i
,
c
i
≠
0
,
i
=
2
,
3
,
…
,
n
−
1
| b_i| \ge |a_i| +|c_i|,a_i,c_i\ne0,i=2,3,\ldots,n-1
∣bi∣≥∣ai∣+∣ci∣,ai,ci=0,i=2,3,…,n−1
∣
b
n
∣
>
∣
a
n
∣
>
0.
| b_n| >| a_n| >0.
∣bn∣>∣an∣>0.
设
A
=
[
b
1
c
1
a
2
b
2
c
2
⋱
⋱
⋱
a
n
−
1
b
n
−
1
c
n
−
1
a
n
b
n
]
[
α
1
γ
2
α
2
⋱
⋱
γ
n
α
n
]
=
[
1
β
1
1
⋱
⋱
β
n
−
1
1
]
,
A=\begin{bmatrix} b_1&c_1&&&\\ a_2&b_2&c_2&&\\ &\ddots&\ddots&\ddots&\\ &&a_{n-1}&b_{n-1}&c_{n-1}\\ &&&a_n&b_n \end{bmatrix} \begin{bmatrix} \alpha_1&&&\\ \gamma_2&\alpha_2&&\\ &\ddots&\ddots&\\ &&\gamma_n&\alpha_n \end{bmatrix}= \begin{bmatrix} 1&\beta_1&&\\ &1&\ddots&\\ &&\ddots&\beta_{n-1}\\ &&&1 \end{bmatrix},
A=⎣⎢⎢⎢⎢⎡b1a2c1b2⋱c2⋱an−1⋱bn−1ancn−1bn⎦⎥⎥⎥⎥⎤⎣⎢⎢⎡α1γ2α2⋱⋱γnαn⎦⎥⎥⎤=⎣⎢⎢⎡1β11⋱⋱βn−11⎦⎥⎥⎤,其中
α
i
,
β
i
,
γ
i
为
待
定
系
数
.
\alpha_i,\beta_i,\gamma_i为待定系数.
αi,βi,γi为待定系数.
经过分析,求解
A
x
=
f
Ax=f
Ax=f等价于求解两个三角形方程组:
(
1
)
L
y
=
f
,
求
y
;
(1)Ly=f,求y;
(1)Ly=f,求y;
(
2
)
U
x
=
y
,
求
x
.
(2)Ux=y,求x.
(2)Ux=y,求x.
从而得到解三对角线方程组的追赶法公式:
(1)计算{
β
i
\beta_i
βi}的递推公式
β
1
=
c
1
/
b
1
,
β
i
=
c
i
/
(
b
i
−
α
i
β
i
−
1
)
,
i
=
2
,
3
,
…
,
n
−
1
;
\begin{aligned} \beta_1&=c_1/b_1,\\ \beta_i&=c_i/(b_i-\alpha_i\beta_{i-1}),i=2,3,\ldots,n-1; \end{aligned}
β1βi=c1/b1,=ci/(bi−αiβi−1),i=2,3,…,n−1;
(2)解
L
y
=
f
Ly=f
Ly=f
y
1
=
f
1
/
b
1
,
y
i
=
(
f
i
−
α
i
y
i
−
1
)
/
(
b
i
−
α
i
β
i
−
1
)
,
i
=
2
,
3
,
…
,
n
;
\begin{aligned} \quad y_1&=f_1/b_1,\\ \quad y_i&=(f_i-\alpha_iy_{i-1})/(b_i-\alpha_i\beta_{i-1}),i=2,3,\ldots,n; \end{aligned}
y1yi=f1/b1,=(fi−αiyi−1)/(bi−αiβi−1),i=2,3,…,n;
(3)解
U
x
=
y
Ux=y
Ux=y
x
n
=
y
n
,
x
i
=
y
i
−
β
i
x
i
+
1
,
i
=
n
−
1
,
n
−
2
,
…
,
1.
\begin{aligned} x_n&=y_n,\\ x_i&=y_i-\beta_ix_{i+1},i=n-1,n-2,\ldots,1. \end{aligned}
xnxi=yn,=yi−βixi+1,i=n−1,n−2,…,1.
2.Python实现追赶法解三对角线方程组
# 自己原创,注意这里没有做矩阵类型判断,该方法仅适用于解系数矩阵为对角占优的三对角线方程组,P159
def chasing_thomas(triple_diagonal_matrix: np.ndarray, f_vector: np.ndarray):
b_diagonal = np.diag(triple_diagonal_matrix)
c_diagonal = np.diag(triple_diagonal_matrix, k=1)
a_diagonal = np.diag(triple_diagonal_matrix, k=-1)
# 计算Bata_i,dtype=np.float64,提高运算精度,否则默认最小精度
beta_diagonal = np.ones_like(c_diagonal, dtype=np.float64)
beta_diagonal[0] = c_diagonal[0] / b_diagonal[0]
rows = triple_diagonal_matrix.shape[0]
for i in range(1, rows - 1):
beta_diagonal[i] = c_diagonal[i] / (b_diagonal[i] - a_diagonal[i] * beta_diagonal[i - 1])
# 解Ly=f
y = np.ones_like(f_vector, dtype=np.float64)
y[0, 0] = f_vector[0, 0] / b_diagonal[0]
for i in range(1, rows):
y[i, 0] = (f_vector[i, 0] - a_diagonal[i - 1] * y[i - 1, 0]) / (
b_diagonal[i] - a_diagonal[i - 1] * beta_diagonal[i - 1])
# 解Ux=y,自己写的发现第一个解x0=1.,而不是0.8333333333333334,有精度损失,
x = np.ones_like(f_vector, dtype=np.float64)
x[rows - 1, 0] = y[rows - 1, 0]
for i in range(rows - 2, 0, -1):
x[i, 0] = y[i, 0] - beta_diagonal[i] * x[i + 1, 0]
return x
3.解三对角线方程
[ 2 − 1 0 0 0 − 1 2 − 1 0 0 0 − 1 2 − 1 0 0 0 − 1 2 − 1 0 0 0 − 1 2 ] [ x 1 x 2 x 3 x 4 x 5 ] = [ 1 0 0 0 0 ] \begin{bmatrix} 2&-1&0&0&0\\ -1&2&-1&0&0\\ 0&-1&2&-1&0\\ 0&0&-1&2&-1\\ 0&0&0&-1&2 \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ x_3\\ x_4\\ x_5 \end{bmatrix}= \begin{bmatrix} 1\\0\\0\\0\\0 \end{bmatrix} ⎣⎢⎢⎢⎢⎡2−1000−12−1000−12−1000−12−1000−12⎦⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎡x1x2x3x4x5⎦⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎡10000⎦⎥⎥⎥⎥⎤
4.测试
if __name__ == '__main__':
# 追赶法测试成功,来源详见李庆扬数值分析第5版P177,e.g.9
# dtype指定为双精度浮点提高运算精度
tri_diagonal = np.array([[2, -1, 0, 0, 0],
[-1, 2, -1, 0, 0],
[0, -1, 2, -1, 0],
[0, 0, -1, 2, -1],
[0, 0, 0, -1, 2]], dtype=np.float64)
f = np.array([1, 0, 0, 0, 0], dtype=np.float64).reshape((5, 1))
print(chasing_thomas(tri_diagonal, f))
5.运行截图
说明:解向量{
x
i
x_i
xi}为倒序
x
5
,
…
,
x
1
.
x_5,\ldots,x_1.
x5,…,x1.
其中
x
1
=
5
6
x_1=\frac56
x1=65,由于自己实现方法精度不足,故只输出保留到整数位