Doolittle三角矩阵分解

有关Doolittle三角矩阵分解的思路和代码实现。

什么是Doolittle分解

首先对一个行列式不为零的矩阵来说,一定可以通过初等行变换 将 该矩阵转化成一个初等矩阵和一个上三角矩阵相乘的形式。
A = L ⋅ U A=L\cdot U A=LU
此时如果L 是一个单位下三角矩阵 ,表明矩阵A 可以进行Doolittle 分解 ,当然,Doolittle分解的三角形 并不唯一;
设矩阵D是 可逆对角矩阵,则有
D ⋅ D − 1 = E D \cdot D^{-1}=E DD1=E,故
A = L ⋅ D ⋅ D − 1 ⋅ U A=L\cdot D \cdot D^{-1} \cdot U A=LDD1U
同时,又可变化为

A = ( L ⋅ D ) ⋅ ( D − 1 ⋅ U ) A=(L\cdot D )\cdot( D^{-1} \cdot U) A=(LD)(D1U)
就相当于,又产生了一组 L 和 U。
Doolittle 分解唯一的充要条件是 N-1 阶顺序主子式大于零,如果在n-1阶子式中有不为零的项,可通过初等行变换,消除这种现象。

使用程序进行矩阵分解。

首先将一个矩阵分解为两个矩阵的乘积可以通过待定系数法 进行实现,矩阵如下所示。

{ a 11 a 12 a 13 a 21 a 22 a 23 a 31 a 32 a 33 } = { 1 0 0 l 21 1 0 l 31 l 32 1 } ⋅ { r 11 r 12 r 13 0 r 22 r 23 0 0 r 33 } \left\{ \begin{matrix} a_{11}& a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{matrix} \right\} =\left\{ \begin{matrix} 1& 0 & 0 \\ l_{21} & 1 & 0 \\ l_{31} & l_{32} & 1 \end{matrix} \right\} \cdot \left\{ \begin{matrix} r_{11}& r_{12} & r_{13} \\ 0 & r_{22} & r_{23} \\ 0 & 0 & r_{33} \end{matrix} \right\} a11a21a31a12a22a32a13a23a33=1l21l3101l32001r1100r12r220r13r23r33
容易求得 矩阵L的第一列和矩阵U的第一行比较容易计算,即 满足如下公式

{ r 1 , j = a 1 , j j ⊂ { 1 , 2 , 3... n } l i , 1 = a i , 1 a 1 , 1 j \begin{cases} r_{1 ,j} =a_{1,j} & j \subset \{1,2,3...n\} \\ l_{i,1}= \frac{a_{i,1}}{a_{1,1}} & j \end{cases} {r1,j=a1,jli,1=a1,1ai,1j{1,2,3...n}j
同时此公式可以作为矩阵的初始化 使用。
下面开始计算非特殊位置
{ r i , j = a i , j − ∑ m = 1 i − 1 l i , m ⋅ r m , j i ⊂ { 2 , 3 , . . n } , j ⊂ { i , i + 1... n } l j , i = a j , i − ∑ m = 1 i − 1 l j , m ⋅ r m , i i ⊂ { 2 , 3 , . . n − 1 } , j ⊂ { i + 1... n } \begin{cases} r_{i,j}=a_{i,j}-\sum_{m=1}^{i-1}l_{i,m}\cdot r_{m,j} &i \subset\{2,3,..n\},j \subset\{i,i+1...n\}\\ \\ l_{j,i}=a_{j,i}-\sum_{m=1}^{i-1}l_{j,m}\cdot r_{m,i} &i \subset\{2,3,..n-1\},j \subset\{i+1...n\}\\ \end{cases} ri,j=ai,jm=1i1li,mrm,jlj,i=aj,im=1i1lj,mrm,ii{2,3,..n},j{i,i+1...n}i{2,3,..n1},j{i+1...n}
经过分析可知 ,求元素l或r的任意元素,只和其所在行列的上层元素有关,如
将l和u矩阵合并在一起,就会有如下结果
{ r 11 r 12 r 13 l 21 r 22 r 23 l 31 l 32 r 33 } \left\{ \begin{matrix} r_{11}& r_{12} & r_{13} \\ l_{21} & r_{22} & r_{23} \\ l_{31} & l_{32} & r_{33} \end{matrix} \right\} r11l21l31r12r22l32r13r23r33
如果求 r 22 r_{22} r22 就需要知道 r 12 r_{12} r12 l 21 l_{21} l21的值,即
在这里插入图片描述所以说,我们可以用迭代的方式求出两个矩阵的所有元素。

同时,i和j,k的元素有重叠的部分,可以放在一个for循环之下执行。
{ i ⊂ { 2 , 3 , . . n } j ⊂ { i , i + 1... n } \begin{cases} i \subset\{2,3,..n\}\\j \subset\{i,i+1...n\} \end{cases} {i{2,3,..n}j{i,i+1...n}
{ i ⊂ { 2 , 3 , . . n − 1 } , j ⊂ { i + 1... n } \begin{cases} i \subset\{2,3,..n-1\},\\j \subset\{i+1...n\} \end{cases} {i{2,3,..n1},j{i+1...n}

取重合部分 , i ⊂ [ 2 , 3 , . . n − 1 ] , j ⊂ [ i + 1 , i + 2..... n ] i\subset[2,3,..n-1],j\subset[i+1,i+2.....n] i[2,3,..n1],j[i+1,i+2.....n] 进行大循环,同时我们可以使用if 判断 来去除一些元素

#初始化 第一行 和第一列
lu[0]=A[0]
for i in range(1,n):# n 是矩阵的阶数
    lu[i][0]=A[i][0]/A[0][0]
# 初始化结束,求其他数值
for  i in range(1,n):
    for j in range(i,n):
        lu[i][j]=A[i][j]-sum([lu[i][k]*lu[k][j] for k in range(0,i)])
        if i< n-1 and j!=i:# 通过判断排除 这里是由ij 代替了k
            lu[j][i]=(A[j][i]-sum([lu[j][k]*lu[k][i] for k in range(0,i)]))/lu[i][i]
     

完整代码

# Doolittle.py
A=[[2,2,-5],[1,-3,1],[1,5,2]]
A=[[2,-1,0,1],[1,3,0,1],[0,1,-1,2],[1,0,0,1]]
n=len(A)
# //创建一个和矩阵A同阶的矩阵
lu=[[0 for i in range(n)] for j in range(n)]
# 初始化
lu[0]=A[0]
for i in range(1,n):
    lu[i][0]=A[i][0]/A[0][0]
# 初始化结束
for  i in range(1,n):
    for j in range(i,n):
        lu[i][j]=A[i][j]-sum([lu[i][k]*lu[k][j] for k in range(0,i)])
        if i< 4-1 and j!=i:
            lu[j][i]=(A[j][i]-sum([lu[j][k]*lu[k][i] for k in range(0,i)]))/lu[i][i]


#将大矩阵可视化分解
L=[[0 for i in range(n)] for j in range(n)]
U=[[0 for i in range(n)] for j in range(n)]
for  i in range(0,n):
    for j in range(0,n):
        if i==j:
            L[i][j]=1
            U[i][j]=lu[i][j]
        if i>j:
            L[i][j]=lu[i][j]
        else:
            U[i][j]=lu[i][j]
print("原矩阵")
print("\n".join(["".join(str(i)) for i in A]))
print("矩阵L")
print("\n".join(["".join(str(i)) for i in L]))
print("矩阵U")
print("\n".join(["".join(str(i)) for i in U]))


测试用例
原矩阵
[2, 2, -5]
[1, -3, 1]
[1, 5, 2]
矩阵L
[1, 0, 0]
[0.5, 1, 0]
[0.5, -1.0, 1]
矩阵U
[2, 2, -5]
[0, -4.0, 3.5]
[0, 0, 8.0]
原矩阵
[2, -1, 0, 1]
[1, 3, 0, 1]
[0, 1, -1, 2]
[1, 0, 0, 1]
矩阵L
[1, 0, 0, 0]
[0.5, 1, 0, 0]
[0.0, 0.2857142857142857, 1, 0]
[0.5, 0.14285714285714285, -0.0, 1]
矩阵U
[2, -1, 0, 1]
[0, 3.5, 0.0, 0.5]
[0, 0, -1.0, 1.8571428571428572]
[0, 0, 0, 0.4285714285714286]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值