Застрял в матрице обратного алгоритма - PullRequest
0 голосов
/ 10 ноября 2019

Я хочу получить обратную матрицу в чистом 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 Ответ

1 голос
/ 10 ноября 2019

Вот ваш код с устраненными ошибками. Трудно описать все проблемы с кодом. Похоже, вы пытаетесь изучить 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]

Обратите внимание, что из-за неизбежных ошибок округления произведение исходной матрицы с ее обратнойпочти никогда точная единичная матрица. Это будет приближение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...