改进平方根法解对称正定方程组

1.改进平方根法

对称阵的三角分解定理

A A A n n n阶对称矩阵,且 A A A的所有顺序主子式均不为零,则 A A A可唯一分解为 A = L D L T , A=LDL^T, A=LDLT,
其中 L L L为单位下三角矩阵, D D D为对角矩阵.即
A = [ 1 l 21 1 ⋮ ⋮ ⋱ l n 1 l n 2 … 1 ] [ d 1 d 2 ⋱ d n ] [ 1 l 21 … l n 1 1 … l n 2 ⋱ ⋮ 1 ] A=\begin{bmatrix} 1&&&\\ l_{21}&1&&\\ \vdots&\vdots&\ddots&\\ l_{n1}&l_{n2}&\ldots&1 \end{bmatrix} \begin{bmatrix} d_1&&&\\ &d_2&&\\ &&\ddots&\\ &&&d_n \end{bmatrix} \begin{bmatrix} 1&l_{21}&\ldots&l_{n1}\\ &1&\ldots&l_{n2}\\ &&\ddots&\vdots\\ &&&1\end{bmatrix} A=1l21ln11ln21d1d2dn1l211ln1ln21
由矩阵乘法,并注意 l j j = 1 , l j k = 0 ( j < k ) , 得 l_{jj}=1,l_{jk}=0(j<k),得 ljj=1,ljk=0(j<k),
a i j = ∑ k = 1 n ( L D ) i k ( L T ) k j = ∑ k = 1 n l i k d k l j k = ∑ k = 1 j − 1 l i k d k l j k + l i j d j l j j a_{ij}=\sum_{k = 1}^{n}(LD)_{ik}(L^T)_{kj}=\sum_{k = 1}^{n}l_{ik}d_kl_{jk}=\sum_{k = 1}^{j-1}l_{ik}d_kl_{jk}+l_{ij}d_jl_{jj} aij=k=1n(LD)ik(LT)kj=k=1nlikdkljk=k=1j1likdkljk+lijdjljj
于是得到计算 L L L的元素及 D D D的对角元素公式:
对于 i = 1 , 2 , … , n . i=1,2,\ldots,n. i=1,2,,n.
( 1 ) l i j = ( a i j − ∑ k = 1 j − 1 l i k d k l j k ) / d j , j = 1 , 2 , … , i − 1 (1)l_{ij}=(a_{ij}-\sum\limits_{k = 1}^{j-1}l_{ik}d_kl_{jk})/d_j,j=1,2,\ldots,i-1 (1)lij=(aijk=1j1likdkljk)/dj,j=1,2,,i1
( 2 ) d i = a i i − ∑ k = 1 i − 1 l i k 2 d k . ( i ) (2)d_i=a_{ii}-\sum\limits_{k = 1}^{i-1}l_{ik}^2d_k.(i) (2)di=aiik=1i1lik2dk.(i)
为了避免重复计算,引进 t i j = l i j d j , t_{ij}=l_{ij}d_j, tij=lijdj,由(i)式得到按行计算 L , T L,T L,T元素的公式: d 1 = a 11 . d_1=a_{11}. d1=a11.
对于 i = 2 , 3 , … , n . i=2,3,\ldots,n. i=2,3,,n.
( 1 ) t i j = a i j − ∑ k = 1 j − 1 t i k l j k , j = 1 , 2 , … , i − 1 ; (1)t_{ij}=a_{ij}-\sum\limits_{k=1}^{j-1}t_{ik}l_{jk},j=1,2,\ldots,i-1; (1)tij=aijk=1j1tikljk,j=1,2,,i1;
( 2 ) l i j = t i j / d j , j = 1 , 2 , … , i − 1 ; (2)l_{ij}=t_{ij}/d_j,j=1,2,\ldots,i-1; (2)lij=tij/dj,j=1,2,,i1;
( 3 ) d i = a i i − ∑ k = 1 i − 1 t i k l i k . (3)d_i=a_{ii}-\sum\limits_{k = 1}^{i-1}t_{ik}l_{ik}. (3)di=aiik=1i1tiklik.
求解 L y = b , D L T x = y Ly=b,DL^Tx=y Ly=b,DLTx=y计算公式:
( 4 ) { y 1 = b 1 ; y i = b i − ∑ k = 1 i − 1 l i k y k , i = 2 , 3 , … , n . (4)\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} (4)y1=b1;yi=bik=1i1likyk,i=2,3,,n.
5 ) { x n = y n / d n ; x i = y i / d i − ∑ k = i + 1 n l k i x k , i = n − 1 , n − 2 , … , 1. 5)\begin{cases} x_n=y_n/d_n;\\ x_i=y_i/d_i-\sum\limits_{k=i+1}^{n}l_{ki}x_k,i=n-1,n-2,\ldots,1. \end{cases} 5)xn=yn/dn;xi=yi/dik=i+1nlkixk,i=n1,n2,,1.

2.Python实现改进平方根

# 自己原创改进平方根
def improved_square_root(symmetric_positive_define_matrix: np.ndarray, right_hand_side_vector: np.ndarray):
    rows, columns = symmetric_positive_define_matrix.shape
    # judge if it is a square matrix
    if rows == columns:
        # 判断是否对称
        if (symmetric_positive_define_matrix.T == symmetric_positive_define_matrix).all():
            for k in range(rows):  # 判断各阶顺序主子式是否为0,即判定是否正定
                if det(symmetric_positive_define_matrix[:k + 1, :k + 1]) == 0:
                    raise Exception("error, cannot decompose")
            else:
                # 初始化单位下三角矩阵L
                square_ones_matrix = np.ones((rows, columns))
                lower_triangle_matrix = np.tril(square_ones_matrix)
                diagonal_matrix = np.diag(np.diag(square_ones_matrix))
                t = lower_triangle_matrix @ diagonal_matrix
                diagonal_matrix[0, 0] = symmetric_positive_define_matrix[0, 0]
                for i in range(1, rows):
                    for j in range(i):
                        prod = 0
                        for k in range(j):
                            prod += t[i, k] * lower_triangle_matrix[j, k]
                        t[i, j] = symmetric_positive_define_matrix[i, j] - prod
                        lower_triangle_matrix[i, j] = t[i, j] / diagonal_matrix[j, j]
                    prod = 0
                    for k in range(i):
                        prod += t[i, k] * lower_triangle_matrix[i, k]
                    diagonal_matrix[i, i] = symmetric_positive_define_matrix[i, i] - prod

                return inv(
                    lower_triangle_matrix @ diagonal_matrix @ lower_triangle_matrix.T) @ right_hand_side_vector
                # 自己写的发现第一个解x0=1.,而不是1.11111111,有精度损失,所以采用矩阵运算
                # # Ly=b,此处不指定双精度浮点数据类型,则可能会损失精度,导致结果偏差太大
                # y = np.ones_like(right_hand_side_vector, dtype=np.float64)
                # for i in range(rows):
                #     prod = 0
                #     for k in range(i):
                #         prod += lower_triangle_matrix[i, k] * y[k, 0]
                #     y[i, 0] = right_hand_side_vector[i, 0] - prod
                # # DL^Tx=y,此处不指定双精度浮点数据类型,则可能会损失精度,导致结果偏差太大
                # x = np.ones_like(right_hand_side_vector, dtype=np.float64)
                # x[rows - 1, 0] = y[rows - 1, 0] / diagonal_matrix[rows - 1, rows - 1]
                # for i in range(rows - 2, 0, -1):
                #     prod = 0
                #     for k in range(i + 1, rows):
                #         prod += lower_triangle_matrix[k, i] * x[k, 0]
                #     x[i, 0] = y[i, 0] / diagonal_matrix[i, i] - prod
                # return x

                # for i in range(rows):
                #     for j in range(i):
                #         prod = 0
                #         for k in range(j):
                #             prod += lower_triangle_matrix[i, k] * diagonal_matrix[k, k] * lower_triangle_matrix[j, k]
                #         lower_triangle_matrix[i, j] = (symmetric_positive_define_matrix[i, j] - prod) / diagonal_matrix[
                #             j, j]
                #     prod = 0
                #     for k in range(i):
                #         prod += lower_triangle_matrix[i, k] * diagonal_matrix[k, k] * lower_triangle_matrix[i, k]
                #     diagonal_matrix[i, i] = symmetric_positive_define_matrix[i, i] - prod
        else:
            raise Exception("error,the input matrix must be a symmetric-matrix")
    else:
        raise Exception("ERROR:please pass a square matrix.")

3.用改进平方根解对称正定方程组

[ 2 − 1 1 − 1 − 2 3 1 3 1 ] [ x 1 x 2 x 3 ] = [ 4 5 6 ] . \begin{bmatrix} 2&-1&1\\ -1&-2&3\\ 1&3&1 \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ x_3 \end{bmatrix}= \begin{bmatrix} 4\\ 5\\ 6 \end{bmatrix}. 211123131x1x2x3=456.

4.测试

if __name__ == '__main__':
    # 改进平方根法测试成功,来源详见李庆扬数值分析第5版P177,e.g.10
    symmetric_positive_define_matrix1 = np.array([[2, -1, 1], [-1, -2, 3], [1, 3, 1]])
    column_vector = np.array([4, 5, 6]).reshape((3, 1))
    print(improved_square_root(symmetric_positive_define_matrix1, column_vector))

5.运行截图

在这里插入图片描述

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值