1. 程式人生 > 其它 >平方根法求解對稱正定方程組

平方根法求解對稱正定方程組

技術標籤:數值分析人工智慧數理基礎線性代數演算法矩陣

1.對稱正定矩陣三角分解或Cholesky分解定理

如果 A A A n n n階對稱正定矩陣,則存在一個實的非奇異下三角矩陣 L L L使 A = L L T A=LL^T A=LLT,當限定 L L L的對角元素為正時,這種分解是唯一的.
下面用直接分解方法來確定計算 L L L元素的遞推公式.因為
A = [ l 11 l 21 l 22 ⋮ ⋮ ⋱ l n 1 l n 2 … l n n ] [ l 11 l 21 … l n 1 l 22 … l n 2 ⋱ ⋮ l n n ] A=\begin{bmatrix} l_{11}&&&\\ l_{21}&l_{22}&&\\ \vdots&\vdots&\ddots&\\ l_{n1}&l_{n2}&\ldots&l_{nn} \end{bmatrix} \begin{bmatrix} l_{11}&l_{21}&\ldots&l_{n1}\\ &l_{22}&\ldots&l_{n2}\\ &&\ddots&\vdots\\ &&&l_{nn} \end{bmatrix}

A=l11l21ln1l22ln2lnnl11l21l22ln1ln2lnn
其中 l i i > 0 ( i = 1 , 2 , … , n ) . l_{ii}>0(i=1,2,\ldots,n). lii>0(i=1,2,,n).由矩陣乘法及 l j k = 0 ( 當 j < k 時 ) , 得 l_{jk}=0(當j<k時),得 ljk=0(j<k),
a i j = ∑ k = 1 n l i k l j k = ∑ k = 1 j − 1 l i k l j k + l j j l i j , a_{ij}=\sum_{k=1}^{n}l_{ik}l_{jk}=\sum_{k=1}^{j-1}l_{ik}l_{jk}+l_{jj}l_{ij},
aij=k=1nlikljk=k=1j1likljk+ljjlij,

於是得到解對稱正定方程組 A x = b Ax=b Ax=b的平方根計算公式:
對於 j = 1 , 2 , … , n j=1,2,\ldots,n j=1,2,,n
( 1 ) l j j = ( a j j − ∑ k = 1 j − 1 l j k 2 ) 1 2 ; (1)l_{jj}=(a_{jj}-\sum\limits_{k=1}^{j-1}l_{jk}^2)^{\frac{1}{2}}; (1)ljj=(ajjk=1j1ljk2)21;
( 2 ) l i j = ( a i j − ∑ k = 1 j − 1 l i k l j k ) / l j j , i = j + 1 , … , n . (2)l_{ij}=(a_{ij}-\sum\limits_{k=1}^{j-1}l_{ik}l_{jk})/l_{jj},i=j+1,\ldots,n.
(2)lij=(aijk=1j1likljk)/ljj,i=j+1,,n.

求解 A x = b , Ax=b, Ax=b,即求解兩個三角形方程組:
1. L y = b , 求 y ; Ly=b,求y;\quad\quad\quad\quad Ly=b,y; 2. L T x = y , 求 x . L^Tx=y,求x. LTx=y,x.
( 3 ) y i = ( b i − ∑ k = 1 i − 1 l i k y k ) / l i i , i = 1 , 2 , … , n . (3)y_i=(b_i-\sum\limits_{k=1}^{i-1}l_{ik}y_k)/l_{ii},i=1,2,\ldots,n. (3)yi=(bik=1i1likyk)/lii,i=1,2,,n.
( 4 ) x i = ( b i − ∑ k = i + 1 n l k i x k ) / l i i , i = n , n − 1 , … , 1. (4)x_i=(b_i-\sum\limits_{k=i+1}^{n}l_{ki}x_k)/l_{ii},i=n,n-1,\ldots,1. (4)xi=(bik=i+1nlkixk)/lii,i=n,n1,,1.

2.Python實現平方根法

# 自己原創平方根法
def cholesky_decomposition(sym_pos_define_matrix: np.ndarray, right_hand_side_vector: np.ndarray):
    rows, columns = sym_pos_define_matrix.shape
    # judge if it is a square matrix
    if rows == columns:
        # 判斷是否對稱
        if (sym_pos_define_matrix.T == sym_pos_define_matrix).all():
            for k in range(rows):  # 判斷各階順序主子式是否為0,即判定是否正定
                if det(sym_pos_define_matrix[:k + 1, :k + 1]) <= 0:
                    raise Exception("cannot decompose")
            else:
                # 初始化單位下三角矩陣L
                square_ones_matrix = np.ones((rows, columns))
                lower_triangle_matrix = np.tril(square_ones_matrix)
                for j in range(rows):
                    prod = 0
                    for k in range(j):
                        prod += lower_triangle_matrix[j, k] * lower_triangle_matrix[j, k]
                    lower_triangle_matrix[j, j] = np.sqrt(sym_pos_define_matrix[j, j] - prod)

                    for i in range(j + 1, rows):
                        prod = 0
                        for k in range(j):
                            prod += lower_triangle_matrix[i, k] * lower_triangle_matrix[j, k]
                        lower_triangle_matrix[i, j] = (sym_pos_define_matrix[i, j] - prod) / lower_triangle_matrix[j, j]

        else:
            raise Exception("error,the input matrix must be a symmetric-matrix")
    else:
        raise Exception("ERROR:please pass a square matrix.")
    return inv(lower_triangle_matrix.transpose()) @ inv(lower_triangle_matrix) @ right_hand_side_vector

3.平方根解對稱正定矩陣方程組

[ 4 2 − 4 0 2 4 0 0 2 2 − 1 − 2 1 3 2 0 − 4 − 1 14 1 − 8 − 3 5 6 0 − 2 1 6 − 1 − 4 − 3 3 2 1 − 8 − 1 22 4 − 10 − 3 4 3 − 3 − 4 4 11 1 − 4 0 2 5 − 3 − 10 1 14 2 0 0 6 3 − 3 − 4 2 19 ] [ x 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 ] = [ 0 − 6 20 23 9 − 22 − 15 45 ] \begin{bmatrix} 4&2&-4&0&2&4&0&0\\ 2&2&-1&-2&1&3&2&0\\ -4&-1&14&1&-8&-3&5&6\\ 0&-2&1&6&-1&-4&-3&3\\ 2&1&-8&-1&22&4&-10&-3\\ 4&3&-3&-4&4&11&1&-4\\ 0&2&5&-3&-10&1&14&2\\ 0&0&6&3&-3&-4&2&19 \end{bmatrix} \begin{bmatrix} x1\\ x2\\ x3\\ x4\\ x5\\ x6\\ x7\\ x8\\ \end{bmatrix}= \begin{bmatrix} 0\\-6\\20\\23\\9\\-22\\-15\\45 \end{bmatrix} 42402400221213204114183560216143321812241034334411140253101142006334219x1x2x3x4x5x6x7x8=0620239221545

4.測試

if __name__ == '__main__':
    symmetric_positive_define_matrix2 = np.array([[4, 2, -4, 0, 2, 4, 0, 0],
                                                  [2, 2, -1, -2, 1, 3, 2, 0],
                                                  [-4, -1, 14, 1, -8, -3, 5, 6],
                                                  [0, -2, 1, 6, -1, -4, -3, 3],
                                                  [2, 1, -8, -1, 22, 4, -10, -3],
                                                  [4, 3, -3, -4, 4, 11, 1, -4],
                                                  [0, 2, 5, -3, -10, 1, 14, 2],
                                                  [0, 0, 6, 3, -3, -4, 2, 19]],dtype=np.float64)
    column_vector = np.array([0, -6, 20, 23, 9, -22, -15, 45],dtype=np.float64).reshape((8, 1))
    print(cholesky_decomposition(symmetric_positive_define_matrix2, column_vector))

5.執行截圖

在這裡插入圖片描述