一、问题描述
对于线性方程组
A
x
=
b
,
A
=
(
b
1
c
1
a
2
b
2
c
2
⋱
⋱
⋱
⋱
⋱
⋱
a
n
−
1
b
n
−
1
c
n
−
1
a
n
b
n
)
,
b
=
(
f
1
f
2
⋮
f
n
)
Ax=b,\quad A=\begin{pmatrix}b_1&c_1&&&&\\a_2&b_2&c_2&&&\\&\ddots&\ddots&\ddots&& \\&&\ddots&\ddots&\ddots& \\&&&a_{n-1}&b_{n-1}&c_{n-1}\\&&&&a_n&b_n\end{pmatrix},\quad b=\begin{pmatrix} f_1\\f_2\\ \vdots\\ f_n \end{pmatrix}
Ax=b,A=
b1a2c1b2⋱c2⋱⋱⋱⋱an−1⋱bn−1ancn−1bn
,b=
f1f2⋮fn
其中
{
∣
b
1
∣
>
∣
c
1
∣
>
0
∣
b
n
∣
>
∣
a
n
∣
>
0
∣
b
i
∣
≥
∣
a
i
∣
+
∣
c
i
∣
,
a
i
c
i
≠
0
,
i
=
2
,
3
,
⋯
n
−
1
\begin{cases} \begin{aligned}&\quad|b_1|>|c_1|>0\\&\quad|b_n|>|a_n|>0\\&\quad|b_i|\geq|a_i|+|c_i|,\quad a_ic_i\neq0,i=2,3,\cdots n-1\end{aligned} \end{cases}
⎩
⎨
⎧∣b1∣>∣c1∣>0∣bn∣>∣an∣>0∣bi∣≥∣ai∣+∣ci∣,aici=0,i=2,3,⋯n−1
二、追赶法解三对角方程组
A = ( b 1 c 1 a 2 b 2 c 2 ⋱ ⋱ ⋱ a n − 1 b n − 1 c n − 1 a n b n ) , L = ( 1 l 2 1 l 3 ⋱ ⋱ 1 l n 1 ) , U = ( u 1 d 1 u 2 d 2 ⋱ ⋱ u n − 1 d n − 1 u n ) \begin{equation*} A=\begin{pmatrix}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{pmatrix}, {L}=\begin{pmatrix}1\\l_2&1\\&l_3&\ddots\\&&\ddots&1\\&&&l_n&1\end{pmatrix},{U}=\begin{pmatrix}u_1&d_1\\&u_2&d_2\\&&\ddots&\ddots\\&&&u_{n-1}&d_{n-1}\\&&&&u_n\end{pmatrix} \end{equation*} A= b1a2c1b2⋱c2⋱an−1⋱bn−1ancn−1bn ,L= 1l21l3⋱⋱1ln1 ,U= u1d1u2d2⋱⋱un−1dn−1un
A = L U A = LU A=LU
首先通过前两行与前两列可以知道
b
1
=
u
1
,
a
2
=
l
2
u
1
,
c
1
=
d
1
b_1=u_1,a_2 = l_2u_1,c_1 = d_1
b1=u1,a2=l2u1,c1=d1得
u
1
,
d
1
,
l
2
u_1,d_1,l_2
u1,d1,l2
再从下式看两边是如何对应上的
A : i − 1 i i + 1 i a i b i c i A:\begin{array}{c|c|c|c} & i-1 &i&i+1\\ \hline i&a_i&b_i&c_i \end{array} A:ii−1aiibii+1ci
L : i − 1 i i + 1 i l i 1 U : i − 1 i i + 1 i − 2 d i − 2 i − 1 u i − 1 d i − 1 i u i d i i + 1 u i + 1 L:\begin{array}{c|c|c|c} & i-1 &i&i+1\\ \hline i&l_i&1& \end{array} \quad U:\begin{array}{c|c|c|c} & i-1 &i&i+1\\ \hline i-2&d_{i-2}& &\\ \hline i-1&u_{i-1}&d_{i-1}&\\\hline i& & u_i&d_i\\\hline i+1 & & &u_{i+1} \end{array} L:ii−1lii1i+1U:i−2i−1ii+1i−1di−2ui−1idi−1uii+1diui+1
可以看出
a
i
=
l
i
u
i
−
1
b
i
=
l
i
d
i
−
1
+
u
i
c
i
=
d
i
\begin{aligned} &a_i = l_i u_{i-1}\\ &b_i = l_i d_{i-1} +u_i\\ &c_i = d_i \end{aligned}
ai=liui−1bi=lidi−1+uici=di
d i d_i di已经得出,接下来只需算 l i l_i li 与 u i u_i ui 即可
再有 u 1 = b 1 u_1 = b_1 u1=b1, i = 2 → n i = 2 \to n i=2→n
l i = a i u i − 1 u i = b i − l i ⋅ c i − 1 \begin{gathered} l_i = \dfrac{a_i}{u_{i-1}}\\ u_i = b_i - l_i \cdot c_{i-1} \end{gathered} li=ui−1aiui=bi−li⋅ci−1
这样子, L L L 和 U U U就得到了
接下来,解 L y = b Ly = b Ly=b , U x = y Ux = y Ux=y,这一步可以用之前写好的程序直接解出
由于这里,结果比较简易,直接将结果写了出来:
解
L
y
=
b
Ly = b
Ly=b: (追)
(
1
l
2
1
l
3
⋱
⋱
1
l
n
1
)
(
y
1
y
2
⋮
y
n
−
1
y
n
)
=
(
f
1
f
2
⋮
f
n
−
1
f
n
)
\left.\begin{pmatrix}1\\l_2&1\\&l_3&\ddots\\&&\ddots&1\\&&&l_n&1\end{pmatrix}\left(\begin{array}{c}y_1\\y_2\\\vdots\\y_{n-1}\\y_n\end{array}\right.\right)=\left(\begin{array}{c}f_1\\f_2\\\vdots\\f_{n-1}\\f_n\end{array}\right)
1l21l3⋱⋱1ln1
y1y2⋮yn−1yn
=
f1f2⋮fn−1fn
y
1
=
f
1
,
y
i
=
f
i
−
l
i
⋅
y
i
−
1
(
i
=
2
,
3
⋯
n
)
y_1 = f_1,y_i = f_i - l_i \cdot y_{i-1} (i=2,3\cdots n)
y1=f1,yi=fi−li⋅yi−1(i=2,3⋯n)
解
U
x
=
y
Ux = y
Ux=y:(赶)
(
u
1
d
1
u
2
d
2
⋱
⋱
u
n
−
1
d
n
−
1
u
n
)
(
x
1
x
2
⋮
x
n
−
1
x
n
)
=
(
y
1
y
2
⋮
y
n
−
1
y
n
)
\left.\begin{pmatrix}u_1&d_1&&&\\&u_2&d_2&&\\&&\ddots&\ddots&\\&&&u_{n-1}&d_{n-1}\\&&&&u_n\end{pmatrix}\left(\begin{array}{c}x_1\\x_2\\\vdots\\x_{n-1}\\x_n\end{array}\right.\right)=\left(\begin{array}{c}y_1\\y_2\\\vdots\\y_{n-1}\\y_n\end{array}\right)
u1d1u2d2⋱⋱un−1dn−1un
x1x2⋮xn−1xn
=
y1y2⋮yn−1yn
x
n
=
y
n
u
n
,
x
i
=
(
y
i
−
d
i
⋅
x
i
+
1
)
u
i
(
i
=
n
−
1
,
⋯
,
2
,
1
)
x_n = \dfrac{y_n}{u_n}, x_i = \dfrac{(y_i-d_i\cdot x_{i+1})}{u_i}(i=n-1 ,\cdots,2, 1)
xn=unyn,xi=ui(yi−di⋅xi+1)(i=n−1,⋯,2,1)
这样 x x x 就求出来了
三、算法
四、北太天元源代码
function [x]=tridiag_chase(A,f)
% 追赶法解三对角方程组
% 输入: 适用的三对角矩阵A, 右端向量f
% 输出: 解,列向量的形式 x
% 创建时间: 1/26/2024
% 版本: 1.0
n = length(A);
% 将三对角提取出来
b = diag(A,0); a = diag(A,-1); c = diag(A,1);
% 处理一下角标 a是从a_2开始, l从l_2 开始
a = cat(1,[0],a); % a = [0, diag(A,-1)]
u = zeros(1,n);l = zeros(1,n);
u(1) = b(1);
for i = 2:1:n
l(i) = a(i)/u(i-1);
u(i) = b(i)-l(i)*c(i-1);
end
% Ly = b
y = zeros(1,n);
y(1) = f(1);
for i =2:1:n
y(i) = f(i)-l(i)*y(i-1);
end
% Ux= y
x = zeros(n,1);
x(n) = y(n)/u(n);
for i =n-1:-1:1
x(i) = (y(i) - c(i)* x(i+1))/u(i);
end
end
保存为 tridiag_chase.m
文件
简单测试一下
在 10、100、500 、1000阶 三对角方程组下, 追赶法与gauss列主元消去法 的时间消耗对比
% file need: tridiag_chase.m, gsem_column.m
% time: 1/26/2024
%%
clc,clear all;
n = 10; % 方程组的阶数 10 100 500 1000
A = diag(2*ones(n,1)) + diag(-1*ones(n-1,1),1) + diag(-1*ones(n-1,1),-1);
f = (1:n)';
t1 = tic;
x1 = tridiag_chase(A,f);
toc(t1);
t2 = tic;
x2 = gsem_column(A,f);
toc(t2);
delta = norm(abs(x1-x2));
n | 追赶法 | Gauss列主元 | delta |
---|---|---|---|
10 | 0.242069 s | 0.253921 s | 0 |
100 | 0.249970 s | 0.997883 s | 0 |
500 | 0.373002 s | 19.068616 s | 0 |
1000 | 0.440046 s | 81.370982 s | 0 |
随着方程组阶数的增大、其优势愈加明显。
其中用到的 Gauss列主元消去法 ,见左方蓝色字体。