Python PLU(LUP)分解失败,主对角线上为零

Python PLU(LUP)分解失败,主对角线上为零,python,algorithm,numpy,math,matrix,Python,Algorithm,Numpy,Math,Matrix,我试着用高斯消去法来写。我发现这个算法: def plu(A): #Get the number of rows n = A.shape[0] #Allocate space for P, L, and U U = A.copy() L = np.eye(n, dtype=np.double) P = np.eye(n, dtype=np.double) #Loop over rows for i in

我试着用高斯消去法来写。我发现这个算法:

def plu(A):
    
    #Get the number of rows
    n = A.shape[0]
    
    #Allocate space for P, L, and U
    U = A.copy()
    L = np.eye(n, dtype=np.double)
    P = np.eye(n, dtype=np.double)
    
    #Loop over rows
    for i in range(n):
        
        #Permute rows if needed
        for k in range(i, n): 
            if ~np.isclose(U[i, i], 0.0):
                break
            U[[k, k+1]] = U[[k+1, k]]
            P[[k, k+1]] = P[[k+1, k]]
            
        #Eliminate entries below i with row 
        #operations on U and #reverse the row 
        #operations to manipulate L
        factor = U[i+1:, i] / U[i, i]
        L[i+1:, i] = factor
        U[i+1:] -= factor[:, np.newaxis] * U[i]
        
    return P, L, U
使用法线矩阵时,它运行良好,但当主对角线上出现0时,它会中断。例如,使用此矩阵:

[[1,  0,  26, 10],
 [60, 0,  75, 50],
 [45, 90, 31, 100],
 [30, 45, 10, 0]]
PLU
的乘法不会得到原始矩阵

因此,我尝试修复算法:当行交换时,它们只在
p
U
中交换,因此我在内部循环中添加
L[[k,k+1]]=L[[k+1,k]]
,以在
L
中交换它。此外,我还更改了
L
的初始化:在开始时,我用零填充L
L=np.zero,就像(A)
一样,并在末尾添加标识矩阵
L+=np.eye(n,dtype=np.double)

但当左上角元素为0时,该算法的固定版本给出了错误的结果。你知道我做错了什么吗?

我想我会改正的

def get_plu_decomposition(A):
    n = A.shape[0]
    U = csr_matrix(A.copy())
    L = csr_matrix(np.zeros_like(A))
    P = csr_matrix(np.eye(n, dtype=np.double))

    for i in range(n - 1):
        index = np.argmax(abs(U[i:, i]))
        if not U[i:, i][index] != 0:
            continue
        index += i
        if index != i:
            U[[index, i]] = U[[i, index]]
            P[[index, i]] = P[[i, index]]
            L[[index, i]] = L[[i, index]]
        factor = U[i + 1:, i] / U[i, i]
        L[i + 1:, i] = factor
        U[i + 1:] -= factor * U[i]

    L += csr_matrix(np.eye(n, dtype=np.double))
    P = P.transpose()

    assert (np.allclose(A, (P@L@U).toarray()))

    return P, L, U

问题在于交换行和转置p矩阵

我会选择数字配方,而不是维基百科的文章:
def get_plu_decomposition(A):
    n = A.shape[0]
    U = csr_matrix(A.copy())
    L = csr_matrix(np.zeros_like(A))
    P = csr_matrix(np.eye(n, dtype=np.double))

    for i in range(n - 1):
        index = np.argmax(abs(U[i:, i]))
        if not U[i:, i][index] != 0:
            continue
        index += i
        if index != i:
            U[[index, i]] = U[[i, index]]
            P[[index, i]] = P[[i, index]]
            L[[index, i]] = L[[i, index]]
        factor = U[i + 1:, i] / U[i, i]
        L[i + 1:, i] = factor
        U[i + 1:] -= factor * U[i]

    L += csr_matrix(np.eye(n, dtype=np.double))
    P = P.transpose()

    assert (np.allclose(A, (P@L@U).toarray()))

    return P, L, U