一个方阵可分解成两个以上矩阵的乘积,当给定一些约束后,这些分解将是唯一的.对矩阵进行三角分解实际上只是将矩阵分解成两个三角形矩阵的乘积,这样对任意方程组的求解问题就转化为三角形方程组的求解问题,方便计算,
定义1对于n阶矩阵 A A A
A = ( a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋯ ⋯ ⋯ ⋯ a n 1 a n 2 ⋯ a n n ) A = \begin{pmatrix} a_{11}&a_{12}&\cdots&a_{1n}\\ a_{21}&a_{22}&\cdots&a_{2n}\\ \cdots&\cdots&\cdots&\cdots\\ a_{n1}&a_{n2}&\cdots&a_{nn} \end{pmatrix} A=⎝ ⎛a11a21⋯an1a12a22⋯an2⋯⋯⋯⋯a1na2n⋯ann⎠ ⎞
若存在n阶下三角方阵L和上三角方阵U,使得A=LU﹐则称方阵A有三角分解或LU分解.特别地,若L为单位下三角矩阵,则称它为 Doolittle分解.若U为单位上三角矩阵,则称它为Grout 分解.本文只介绍Doolittle三角分解.
定理2(存在唯一性定理)设 A A A为 n n n阶方阵,若 A A A的所有顺序主子式 Δ k , ≠ 0 ( k = 1 , 2 , . … , n ) \Delta_k,≠0(k=1,2,.…,n ) Δk,=0(k=1,2,.…,n),则 A A A可以分解为一个单位下三角矩阵L和一个上三角矩阵U的乘积,且这种分解是唯一的.
如果把非奇异矩阵 A A A分解成一个单位下三角矩阵 L L L和一个上三角矩阵 U U U的乘积
A = L U A=LU A=LU
则写成矩阵元素如下
( a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋯ ⋯ ⋯ ⋯ a n 1 a n 2 ⋯ a n n ) = ( 1 l 21 1 ⋮ ⋮ ⋱ l n 1 l n 2 ⋯ 1 ) ( u 11 u 12 ⋯ u 1 n u 22 ⋯ u 2 n ⋱ ⋮ u n n ) \begin{pmatrix} a_{11}&a_{12}&\cdots&a_{1n}\\ a_{21}&a_{22}&\cdots&a_{2n}\\ \cdots&\cdots&\cdots&\cdots\\ a_{n1}&a_{n2}&\cdots&a_{nn} \end{pmatrix}= \begin{pmatrix} 1&&&\\ l_{21}&1&&\\ \vdots&\vdots&\ddots&\\ l_{n1}&l_{n2}&\cdots&1 \end{pmatrix} \begin{pmatrix} u_{11}&u_{12}&\cdots&u_{1n}\\ &u_{22}&\cdots&u_{2n}\\ &&\ddots&\vdots\\ &&&u_{nn} \end{pmatrix} ⎝ ⎛a11a21⋯an1a12a22⋯an2⋯⋯⋯⋯a1na2n⋯ann⎠ ⎞=⎝ ⎛1l21⋮ln11⋮ln2⋱⋯1⎠ ⎞⎝ ⎛u11u12u22⋯⋯⋱u1nu2n⋮unn⎠ ⎞
式中矩阵 L L L与 U U U的元素待定.根据矩阵乘法法则,对 L U LU LU三角分解式分析如下
首先比较等式两边第1行元素,可得矩阵 U U U的第1行元素
u 1 j = a 1 j , k = 1 , 2 , ⋯ , n u_{1j}=a_{1j},\quad k=1,2,\cdots,n u1j=a1j,k=1,2,⋯,n
然后考察等式两边第1列元素,有
a i 1 = l i 1 u 11 , i = 1 , 2 , ⋯ , n a_{i1}=l_{i1}u_{11},\quad i=1,2,\cdots,n ai1=li1u11,i=1,2,⋯,n
可得 L L L的第1列元素
l i 1 = a i 1 u 11 , i = 1 , 2 , ⋯ , n l_{i1}=\frac{a_{i1}}{u_{11}},i=1,2,\cdots,n li1=u11ai1,i=1,2,⋯,n
接着比较等式两边,可得矩阵 A A A的元素 a a a等于L的第 k k k行与 U U U的第j列对应元素乘积之和,因此有
a k j = ∑ q = 1 n l k q u q j = ∑ q = 1 k − 1 l k q u q j + u k j , j = k , k + 1 , ⋯ , n a_{kj}= \sum\limits_{q=1}^nl_{kq}u_{qj}=\sum\limits_{q=1}^{k-1}l_{kq}u_{qj}+u_{kj},\quad j=k,k+1,\cdots,n akj=q=1∑nlkquqj=q=1∑k−1lkquqj+ukj,j=k,k+1,⋯,n
转换后得 U U U的第 k k k行元素
u k j = a k j − ∑ q = 1 k − 1 l k q u q j , j = k , k + 1 , ⋯ , n (3.10) u_{kj}=a_{kj}-\sum\limits_{q=1}^{k-1}l_{kq}u_{qj},\quad j=k,k+1,\cdots,n\tag{3.10} ukj=akj−q=1∑k−1lkquqj,j=k,k+1,⋯,n(3.10)
同理,由
a i k = ∑ q = 1 n l i q u q k = ∑ q = 1 k − 1 l i q u q k + l i k u k k , i = k + 1 , k + 2 , ⋯ , n a_{ik}=\sum\limits^n_{q=1}l_{iq}u_{qk}=\sum\limits_{q=1}^{k-1}l_{iq}u_{qk}+l_{ik}u_{kk},\quad i=k+1,k+2,\cdots,n aik=q=1∑nliquqk=q=1∑k−1liquqk+likukk,i=k+1,k+2,⋯,n
可得与 L L L的第 k k k列元素
l i k = a i k − ∑ q = 1 k − 1 l i q u q k u k k , i = k + 1 , k + 2 , ⋯ , n (3.11) l_{ik}=\frac{a_{ik}-\sum\limits_{q=1}^{k-1}l_{iq}u_{qk}}{u_{kk}},\quad i=k+1,k+2,\cdots,n\tag{3.11} lik=ukkaik−q=1∑k−1liquqk,i=k+1,k+2,⋯,n(3.11)
最后交替使用式 ( 3.10 ) (3.10) (3.10)和式 ( 3.11 ) (3.11) (3.11),可以逐步求出 U U U与 L L L的元素.
直接三角分解法就是将方程组
A x = b Ax=b Ax=b
转换成
L U x = b LUx=b LUx=b
令 U x = y Ux=y Ux=y,则 L y = b Ly=b Ly=b,即有
( u 11 u 12 ⋯ u 1 n u 22 ⋯ u 2 n ⋱ ⋮ u n n ) ( x 1 x 2 ⋮ x n ) = ( y 1 y 2 ⋮ y n ) \begin{pmatrix} u_{11}&u_{12}&\cdots&u_{1n}\\ &u_{22}&\cdots&u_{2n}\\ &&\ddots&\vdots\\ &&&u_{nn} \end{pmatrix}\begin{pmatrix} x_1\\x_2\\\vdots\\x_n \end{pmatrix}=\begin{pmatrix} y_1\\y_2\\\vdots\\y_n \end{pmatrix} ⎝ ⎛u11u12u22⋯⋯⋱u1nu2n⋮unn⎠ ⎞⎝ ⎛x1x2⋮xn⎠ ⎞=⎝ ⎛y1y2⋮yn⎠ ⎞
( 1 l 21 1 ⋮ ⋮ ⋱ l n 1 l n 2 ⋯ 1 ) ( y 1 y 2 ⋮ y n ) = ( b 1 b 2 ⋮ b n ) \begin{pmatrix} 1&&&\\ l_{21}&1&&\\ \vdots&\vdots&\ddots&\\ l_{n1}&l_{n2}&\cdots&1 \end{pmatrix}\begin{pmatrix} y_1\\y_2\\\vdots\\y_n \end{pmatrix}=\begin{pmatrix} b_1\\b_2\\\vdots\\b_n \end{pmatrix} ⎝ ⎛1l21⋮ln11⋮ln2⋱⋯1⎠ ⎞⎝ ⎛y1y2⋮yn⎠ ⎞=⎝ ⎛b1b2⋮bn⎠ ⎞
故有
{ y 1 = b 1 y i = b i − ∑ j = 1 i − 1 l i j y j , i = 2 , 3 , ⋯ , n (3.12) \begin{cases} y_1=b_1\\ y_i=b_i- \sum\limits_{j=1}^{i-1}l_{ij}y_j,\quad i=2,3,\cdots,n \end{cases}\tag{3.12} ⎩ ⎨ ⎧y1=b1yi=bi−j=1∑i−1lijyj,i=2,3,⋯,n(3.12)
{ x n = y n / u n n x i = ( y i − ∑ j = i + 1 n u i j y j ) / u i i , i = n − 1 , n − 2 , ⋯ , 1 (3.13) \begin{cases} x_n=y_n/u_{nn}\\ x_i=(y_i-\sum\limits_{j=i+1}^nu_{ij}y_j)/u_{ii},\quad i=n-1,n-2,\cdots,1 \end{cases}\tag{3.13} ⎩ ⎨ ⎧xn=yn/unnxi=(yi−j=i+1∑nuijyj)/uii,i=n−1,n−2,⋯,1(3.13)
说明 计算u与的过程是先行后列交替进行的,即依次先计算出 u 1 j , ( j = 1 , 2 , … , n ) u_{1j},(j=1,2,…,n) u1j,(j=1,2,…,n),再算出 L i 1 ( i = 2 , 3 , … , n ) L_{i1}(i=2,3,…,n) Li1(i=2,3,…,n);先算出 u 2 j ( j = 2 , 3 , … , n ) u_{2j} (j=2,3,…,n) u2j(j=2,3,…,n),再算出 l i 2 , ( i = 3 , 4 , … , n ) ; l_{i_2},(i = 3,4,…,n); li2,(i=3,4,…,n);其余类推,即可计算出 L 、 U L、U L、U的各元素.
def Trig_decomposition(coef_mtrix, b_mtix):
n = coef_mtrix.shape[0] # 获取方程组的行数和列数
L = np.eye(n) # 初始化矩阵L
U = np.zeros([n, n]) # 初始化矩阵U
U[0] = coef_mtrix[0]
L[1:, 0] = coef_mtrix[1:, 0] / U[0, 0]
for k in range(1, n):
# 计算L、U矩阵
for j in range(k, n):
U[k, j] = coef_mtrix[k, j] - np.dot(L[k], U[:, j])
for i in range(k + 1, n):
L[i, k] = (coef_mtrix[i, k] - np.dot(L[i], U[:, k])) / U[k, k]
y = np.zeros([n, 1]) # 初始化矩阵y
for i in range(n): # 计算矩阵y
if i == 0:
y[i] = b_mtix[i]
else:
y[i] = b_mtix[i] - np.dot(L[i, :i], y[:i])
x = np.zeros([n, 1]) # 初始化矩阵X
for i in range(n - 1, -1, -1): # 求解矩阵X
x[i, 0] = (y[i, 0] - np.dot(U[i, i + 1:], x[i + 1:, 0])) / U[i, i]
return x
需要注意的是公式3.11和3.10中的求和刚好对应的是L和U中的某一行或某一列的元素或部分元素,所以我们可以利用numpy数组切片的方式将对应矩阵部分取出并点积刚好对应公式中的元素求和。
同样的,求解矩阵y和矩阵x我们也利用了这个特点