不选主元的矩阵三角分解法

1.矩阵三角分解原理

A A A为非奇异矩阵,且有分解式 A = L U , A=LU, A=LU,
A = [ a 11 a 12 … a 1 n a 21 a 21 … a 2 n ⋮ ⋮ ⋮ a n 1 a n 1 … a n n ] A=\begin{bmatrix} a_{11}&a_{12}&\ldots&a_{1n}\\ a_{21}&a_{21}&\ldots&a_{2n}\\ \vdots&\vdots&&\vdots\\ a_{n1}&a_{n1}&\ldots&a_{nn} \end{bmatrix} A=a11a21an1a12a21an1a1na2nann
其中 L L L为单位下三角矩阵, U U U为上三角矩阵,即
A = [ 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 ] A=\begin{bmatrix} 1&&&\\ l_{21}&1&&\\ \vdots&\vdots&\ddots&\\ l_{n1}&l_{n2}&\ldots&1 \end{bmatrix} \begin{bmatrix} u_{11}&u_{12}&\ldots&u_{1n}\\ &u_{22}&\ldots&u_{2n}\\ &&\ddots&\vdots\\ &&&u_{nn} \end{bmatrix} A=1l21ln11ln21u11u12u22u1nu2nunn
下面说明 L , U L,U L,U的元素可以由 n n n步直接定出,其中第 r r r步定出 U U U的第 r r r行和 L L L的第 r r r列.由上述分解式有 a 1 i = u 1 i , i = 1 , 2 , … , n , a_{1i}=u_{1i},i=1,2,\ldots,n, a1i=u1i,i=1,2,,n,
得到 U U U的第 1 1 1行元素;
a i 1 = l i 1 u 11 , l i 1 = a i 1 / u 11 , i = 2 , 3 , … , n , a_{i1}=l_{i1}u_{11},l_{i1}=a_{i1}/u_{11},i=2,3,\ldots,n, ai1=li1u11,li1=ai1/u11,i=2,3,,n,
得到 L L L的第 1 1 1列元素.
设已经定出 U U U的第1行到第 r − 1 r-1 r1列元素.有上述分解式,利用矩阵乘法(注意当 r < k , l r k = 0 r <k,l_{rk}=0 r<k,lrk=0),有 a r i = ∑ k = 1 n l r k u k i = ∑ k = 1 r − 1 l r k u k i + u r i , a_{ri}=\sum_{k = 1}^{n}l_{rk}u_{ki}=\sum_{k = 1}^{r-1}l_{rk}u_{ki}+u_{ri}, ari=k=1nlrkuki=k=1r1lrkuki+uri,
u r i = a r i − ∑ k = 1 r − 1 l r k u k i , i = r , r + 1 , … , n . u_{ri}=a_{ri}-\sum_{k = 1}^{r-1}l_{rk}u_{ki},i=r,r+1,\ldots,n. uri=arik=1r1lrkuki,i=r,r+1,,n.
又由该分解式有 a i r = ∑ k = 1 n l i k u k r = ∑ k = 1 r − 1 l i k u k r + l i r u r r . a_{ir}=\sum_{k = 1}^{n}l_{ik}u_{kr}=\sum_{k = 1}^{r-1}l_{ik}u_{kr}+l_{ir}u_{rr}. air=k=1nlikukr=k=1r1likukr+lirurr.
总结上述讨论,得到直接三角分解法解 A x = b Ax=b Ax=b(要求 A A A的所有顺序主子式都不为零)的计算公式.

  1. u 1 i = a 1 i ( i = 1 , 2 , … , n ) , l i 1 = a i 1 / u 11 , i = 2 , 3 , … , n . u_{1i}=a_{1i}(i=1,2,\ldots,n),l_{i1}=a_{i1}/u_{11},i=2,3,\ldots,n. u1i=a1i(i=1,2,,n),li1=ai1/u11,i=2,3,,n.
    计算 U U U的第 r r r行, L L L的第 r r r列元素 ( r = 2 , 3 , … , n ) : (r=2,3,\ldots,n): (r=2,3,,n):
  2. u r i = a r i − ∑ k = 1 r − 1 l r k u k i , i = r , r + 1 , … , n ; u_{ri}=a_{ri}-\sum\limits_{k = 1}^{r-1}l_{rk}u_{ki},i=r,r+1,\ldots,n; uri=arik=1r1lrkuki,i=r,r+1,,n;
  3. l i r = ( a i r − ∑ k = 1 r − 1 l i k u k r ) / u r r , i = r + 1 , … , n , 且 r ≠ n . l_{ir}=(a_{ir}-\sum\limits_{k = 1}^{r-1}l_{ik}u_{kr})/u_{rr},i=r+1,\ldots,n,\text{且}r \ne n. lir=(airk=1r1likukr)/urr,i=r+1,,n,r=n.
    求解 L y = b , U x = y Ly=b,Ux=y Ly=b,Ux=y的计算公式:
  4. { y 1 = b 1 , y i = b i − ∑ k = 1 i − 1 l i k y k , i = 2 , 3 , … , n ; \begin{cases} y_1=b_1,\\ y_i=b_i-\sum\limits_{k = 1}^{i-1}l_{ik}y_k,i=2,3,\ldots,n; \end{cases} y1=b1,yi=bik=1i1likyk,i=2,3,,n;
  5. { x n = y n / u n n , x i = ( y i − ∑ k = i + 1 n u i k x k ) / u i i , i = n − 1 , n − 2 , … , 1. \begin{cases} x_n=y_n/u_{nn},\\ x_i=(y_i-\sum\limits_{k=i+1}^{n}u_{ik}x_k)/u_{ii},i=n-1,n-2,\ldots,1. \end{cases} xn=yn/unn,xi=(yik=i+1nuikxk)/uii,i=n1,n2,,1.

2.Python实现不选主元矩阵三角分解

# 自己原创
def triangle_decomposition(coefficient_matrix: np.ndarray):
    """
    实现方程Ax=b系数矩阵A的Doolittle decomposition
    :param coefficient_matrix: 初始系数矩阵A
    :return: 单位下三角矩阵L,上三角矩阵U
    """
    # first step: evaluate the decomposition condition
    rows, columns = coefficient_matrix.shape
    if rows == columns:  # judge if it is a square matrix
        for k in range(rows):  # 判断各阶顺序主子式是否为0
            if det(coefficient_matrix[:k + 1, :k + 1]) == 0:
                raise Exception("cannot decompose ")
        else:
            # directive triangle  decomposition
            # 初始化
            square_ones_matrix = np.ones((rows, columns))
            lower_triangle_matrix = np.tril(square_ones_matrix)
            upper_triangle_matrix = np.triu(square_ones_matrix)
            # 计算第1行的U(1,i),第1列的L(i,1)
            upper_triangle_matrix[0, :] = coefficient_matrix[0, :]
            lower_triangle_matrix[1:, 0] = coefficient_matrix[1:, 0] / upper_triangle_matrix[0, 0]
            # 计算第row行的U(row,i),第row列的L(i,row)
            for row in range(1, rows - 1):

                for i in range(row, rows):
                    # 定义一个累积和变量
                    row_i_prod = 0
                    for k in range(row):
                        row_i_prod += lower_triangle_matrix[row, k] * upper_triangle_matrix[k, i]
                    upper_triangle_matrix[row, i] = coefficient_matrix[row, i] - row_i_prod

                for i in range(row + 1, rows):
                    # 定义一个累积和变量
                    i_row_prod = 0
                    for k in range(row):
                        i_row_prod += lower_triangle_matrix[i, k] * upper_triangle_matrix[k, row]
                    lower_triangle_matrix[i, row] = (coefficient_matrix[i, row] - i_row_prod) / upper_triangle_matrix[
                        row, row]

            # 定义一个累积和变量,单独计算n行n列的U(n,n)
            row_i_prod = 0
            for k in range(rows - 1):
                row_i_prod += lower_triangle_matrix[rows - 1, k] * upper_triangle_matrix[k, rows - 1]
            upper_triangle_matrix[rows - 1, rows - 1] = coefficient_matrix[rows - 1, rows - 1] - row_i_prod

            return lower_triangle_matrix, upper_triangle_matrix
    else:
        raise Exception("ERROR:please pass a square matrix.")
# 自己原创
def directive_triangle_decomposition(coefficient_matrix: np.ndarray, right_hand_side_vector: np.ndarray,
                                     decomposition_function=triangle_decomposition):
    """
    实现方程Ax=b系数矩阵A directive triangle decomposition
    :param decomposition_function: 三角分解函数
    :param coefficient_matrix: 初始系数矩阵A
    :param right_hand_side_vector: 初始常数列向量b
    :return: 解向量x
    """
    l, u = decomposition_function(coefficient_matrix)
    rows, columns = coefficient_matrix.shape
    # Ly=b,此处不指定双精度浮点数据类型,则可能会损失精度,导致结果偏差太大
    y = np.ones_like(right_hand_side_vector, dtype=np.float64)
    y[0, 0] = right_hand_side_vector[0, 0]
    for row in range(1, rows):
        # 定义一个累积和变量
        i_k_prod = 0
        for k in range(row):
            i_k_prod += l[row, k] * y[k, 0]
        y[row, 0] = right_hand_side_vector[row, 0] - i_k_prod

    # Ux=y,此处不指定双精度浮点数据类型,则可能会损失精度,导致结果偏差太大
    x = np.ones_like(right_hand_side_vector, dtype=np.float64)
    x[rows - 1] = y[rows - 1] / u[rows - 1, rows - 1]
    for row in range(rows - 2, 0, -1):
        i_k_prod = 0
        for k in range(row + 1, rows):
            i_k_prod += u[row, k] * x[k, 0]
        x[row, 0] = (y[row, 0] - i_k_prod) / u[row, row]

    return x

3.解方程

用直接三角分解法解 [ 1 2 3 2 5 2 3 1 5 ] [ x 1 x 2 x 3 ] = [ 14 18 20 ] \begin{bmatrix} 1&2&3\\ 2&5&2\\ 3&1&5 \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ x_3 \end{bmatrix}= \begin{bmatrix} 14\\ 18\\ 20 \end{bmatrix} 123251325x1x2x3=141820

4.测试

if __name__ == '__main__':
# 直接三角分解法-不选主元三角分解法测试成功,来源详见李庆扬数值分析第5版P153,e.g.5
    square_matrix = np.array([[1, 2, 3], [2, 5, 2], [3, 1, 5]])
    column_vector = np.array([14, 18, 20]).reshape((3, 1))
    print(directive_triangle_decomposition(square_matrix, column_vector))

5.运行结果

在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值