陷入矩阵逆算法

时间:2019-11-10 14:15:19

标签: python matrix

我想在纯Python中获得矩阵的逆,并且将其卡在逆中 对于逆,我正在使用线性行减少方法。我想知道如何对矩阵执行运算,使其变为单位矩阵,并对矩阵进行相同的运算,使其变为逆矩阵。这是代码,请注意其他功能也支持

matrix1 = array([
    [2,3,4],
    [8,9,4],
    [3,4,8]
    ])


def inverse():
    # 0,0  1,1   2,2
    if len(matrix1) != len(matrix1[0]):
        return ZeroDivisionError
    #list1 = []
    flag = 0
    for i in range(len(matrix1)):
        if matrix1[i][i]  != 1:
            matrix1[i][i]  //= matrix1[i][i]
            #list1.append((i,i)) 

        # 1st col to make zero values :  1,0 , 2,0 
        # 2nd col to make zero values :  0,1 , 2,1
        # 3rd col to make zero values :  0,2 , 1,2

        for j in range(len(matrix1)):

            if i != j:

                if matrix1[i][j] != 0:
                    rowsub(matrix1[i],matrix[i][j])  

                #if flag == len(matrix1):
                #break

    return matrix1
def give_identity_mat(imatrix):
    identitymat = [[0 for i in range(len(imatrix))] for i in range(len(imatrix))]

    for i in range( 0, len(imatrix)):
        identitymat[i][i] = 1

def rowadd(row1,row2,const=1):
    #  row1 + const(row2)
    # add
    for i in range(len(matrix1[row1-1])):
        matrix1[row1-1][i] += const*(matrix1[row2-1][i])

def rowsub(row1,row2,const=1):
    for i in range(len(matrix1[row1-1])):
        matrix1[row1-1][i] -= const*(matrix1[row2-1][i])

def issquare(M):
    if len(M[0]) == len(M):
        return True
    else:
        return False

def multiply(row,num):
    for i in range(len(matrix1[row-1])):
        matrix1[row-1][i] *= num

def divide(row,num):
    for i in range(len(matrix1[row-1])):
        matrix1[row-1][i] = matrix1[row-1][i] // num

1 个答案:

答案 0 :(得分:1)

这是您的代码,消除了错误。很难描述代码中的所有问题。您似乎试图通过实现一个涉及的算法来学习Python。也许最好从简单的练习开始。

一些建议:

  • 尽量不要在其他函数中直接更改全局变量(例如matrix1)。尝试始终将它们作为参数。
  • 在普通的Python矩阵中,列表列表只是表示。
  • 在Python3中,“ //”用于整数除法。对于整数除法5 // 2等于2,仅是除法的整数部分。对于矩阵的元素,您需要使用一个“ /”的浮点除法。 5 / 2等于结果的浮动版本2.5
  • 索引从0开始,而不是从1开始。当参数从1开始编号时,这非常令人困惑。最好只是坚持从0开始。
  • 我还没有执行必须在列中搜索非零元素的步骤。
  • 对于该算法,您需要两个矩阵:一个给定的输入矩阵和一个逐步建立的输出矩阵。
def test_calculating_the_inverse_matrix():
    matrix1 = [
        [2, 3, 4],
        [8, 9, 4],
        [3, 4, 8]
    ]
    inv = inverse(matrix1)
    print("The inverse matrix is:")
    for row in inv:
        print ("  ", row)

def inverse(matrix1):
    # calculate the inverse matrix of matrix1
    # algorithm:
    # - initialize invMatrix with a identity matrix of the same size as matrix1
    # - do gaussian elimination on both matrices simultaneously, converting matrix1 to an identity matrix while
    #     buidling up the inverse matrix

    if not issquare(matrix1):
        return ZeroDivisionError
    numRows = len(matrix1)
    invMatrix = give_identity_mat(numRows)

    for i in range(numRows):
        if matrix1[i][i] == 0:
            print("TODO: when a zero on the diagonal is encountered, search for a non-zero below in the same column")
            print("TODO: if a non-zero is found, exchange both rows")
            print("TODO: if no non-zero is found, the matrix has no inverse")
            return ZeroDivisionError

        if matrix1[i][i] != 1:   # we have to divide the complete row by matrix1[i][i], for both matrices
            factor = matrix1[i][i]
            divide(matrix1, i, factor)
            divide(invMatrix, i, factor)
        print(f"after dividing row {i}:")
        print("  ", matrix1)
        print("  ", invMatrix)

        for j in range(numRows):
            if i != j:
                if matrix1[j][i] != 0:
                    factor = matrix1[j][i]
                    rowsub(matrix1, i, j, factor)
                    rowsub(invMatrix, i, j, factor)
                    print(f"after subtracting row {i} from row {j}:")
                    print("  ", matrix1)
                    print("  ", invMatrix)
    return invMatrix

def give_identity_mat(num_rows):
    identitymat = [[0 for i in range(num_rows)] for i in range(num_rows)]
    for i in range( 0, num_rows):
        identitymat[i][i] = 1
    return identitymat

def rowsub(matrix, row1, row2, factor):
    # subtract row1 from row2
    for i in range(len(matrix[row2])):
        matrix[row2][i] -= factor * matrix[row1][i]

def issquare(M):
    return len(M[0]) == len(M)

def multiply(matrix, row, factor):
    for i in range(len(matrix[row])):
        matrix[row][i] *= factor

def divide(matrix, row, factor):
    for i in range(len(matrix[row])):
        matrix[row][i] /= factor


test_calculating_the_inverse_matrix()

输出:

The inverse matrix is:
   [-2.3333333333333335, 0.33333333333333337, 1.0]
   [2.1666666666666665, -0.16666666666666666, -1.0]
   [-0.20833333333333334, -0.041666666666666664, 0.25]

请注意,由于不可避免的舍入误差,原始矩阵与其逆的乘积几乎永远不是精确的单位矩阵。这将是一个近似值。