Как в цикле Python получить промежуточные матрицы?

Рейтинг: 0Ответов: 1Опубликовано: 27.05.2023

Исходная матрица через подстановку справа к ней единичной и преобразования становится обратной (метод Гаусса). В процессе образуются промежуточные матрицы, которые следует выводить в консоль.

В результате трансформации левая часть примет треугольный вид, а затем – вид единичной матрицы. Вот эти промежуточные результаты и нужно выводить – т.е. склеенную матрицу размера n×2n, где слева будет сначала постепенно получаться треугольная матрица, а затем единичная. А справа, соответственно, будет постепенно формироваться обратная матрица.

Понятно, что рецепт таков: после каждого преобразования надо выводить matrix (лежит в списке matrix_bank).Но в итоге получаю первоначальную и сразу финальную матрицы.

def inverse_matrix(matrix_origin):
    """
    Функция получает на вход матрицу, затем добавляет к ней единичную матрицу,
    проводит элементарные преобразования по строкам с первоначальной, добиваясь получения слева единичной матрицы.
    В этом случае справа окажется матрица, которая является обратной к заданной первоначально
    """

    # 1. создаем пустой список для сбора строк для промежуточных матриц
    inverse_matrix.matrix_bank = []

    # 2. Склеиваем 2 матрицы: слева - первоначальная, справа - единичная
    inverse_matrix.n = matrix_origin.shape[0]
    matrix = np.hstack((matrix_origin, np.eye(inverse_matrix.n)))

    # 2.1. Поместим исходную матрицу в банк матриц
    for strings in matrix:
        inverse_matrix.matrix_bank.append(strings.tolist())

    # 3. проведем преобразования строк путем деления на диагональные элементы и вычитания строк
    for nrow, row in enumerate(matrix):
        # nrow равен номеру строки
        # row содержит саму строку матрицы
        # 3.1. определим диагональный элемент
        divider = row[nrow]
        # 3.2. разделим значения строки на диагональный элемент:
        row /= divider
        # 3.3. поместим в список промежуточную матрицу
        inverse_matrix.matrix_bank.append(matrix)
        # 3.4. теперь вычитаем приведенную строку из всех нижележащих строк:
        for lower_row in matrix[nrow + 1:]:
            # 3.4.1. элемент строки в колонке nrow
            factor = lower_row[nrow]
            # 3.4.2. вычитаем, чтобы получить ноль в колонке nrow
            lower_row -= factor * row
            # 3.4.3. снова заносим в список промежуточную матрицу
#             inverse_matrix.matrix_bank.append(matrix)

    # 4. продолжим преобразоания строк методом "обратного" хода
    for nrow in range(len(matrix) - 1, 0, -1):
        row = matrix[nrow]
        for upper_row in matrix[:nrow]:
            factor = upper_row[nrow]
            # Вычитаем целую строку:
            upper_row -= factor * row
#             inverse_matrix.matrix_bank.append(matrix)
    
    for el in inverse_matrix.matrix_bank:
        print(el, '\n')
    
    # 5. Создаем обратноую матрицу из элементов справа от разделительной прямой
    return matrix[:, inverse_matrix.n:].copy()


matrix = np.array([[3.8, 6.7, -1.2],
                   [6.4, 1.3, -2.7],
                   [2.4, -4.5, 3.5]])

inverse_matrix(matrix)

Ответы

▲ 1Принят

В python в переменной хранятся не сами матрицы, а ссылки на них поэтому нужно добавить .copy:

import numpy as np


def inverse_matrix(matrix_origin):
    """
    Функция получает на вход матрицу, затем добавляет к ней единичную матрицу,
    проводит элементарные преобразования по строкам с первоначальной, добиваясь получения слева единичной матрицы.
    В этом случае справа окажется матрица, которая является обратной к заданной первоначально
    """

    # 1. создаем пустой список для сбора строк для промежуточных матриц
    inverse_matrix.matrix_bank = []

    # 2. Склеиваем 2 матрицы: слева - первоначальная, справа - единичная
    inverse_matrix.n = matrix_origin.shape[0]
    matrix = np.hstack((matrix_origin, np.eye(inverse_matrix.n)))

    # 2.1. Поместим исходную матрицу в банк матриц
    for strings in matrix:
        inverse_matrix.matrix_bank.append(strings.tolist())

    # 3. проведем преобразования строк путем деления на диагональные элементы и вычитания строк
    for nrow, row in enumerate(matrix):
        # nrow равен номеру строки
        # row содержит саму строку матрицы
        # 3.1. определим диагональный элемент
        divider = row[nrow]
        # 3.2. разделим значения строки на диагональный элемент:
        row /= divider
        # 3.3. поместим в список промежуточную матрицу
        inverse_matrix.matrix_bank.append(matrix.copy())
        # 3.4. теперь вычитаем приведенную строку из всех нижележащих строк:
        for lower_row in matrix[nrow + 1:]:
            # 3.4.1. элемент строки в колонке nrow
            factor = lower_row[nrow]
            # 3.4.2. вычитаем, чтобы получить ноль в колонке nrow
            lower_row -= factor * row
            # 3.4.3. снова заносим в список промежуточную матрицу
    #             inverse_matrix.matrix_bank.append(matrix.copy())

    # 4. продолжим преобразоания строк методом "обратного" хода
    for nrow in range(len(matrix) - 1, 0, -1):
        row = matrix[nrow]
        for upper_row in matrix[:nrow]:
            factor = upper_row[nrow]
            # Вычитаем целую строку:
            upper_row -= factor * row
    #             inverse_matrix.matrix_bank.append(matrix.copy())

    for el in inverse_matrix.matrix_bank:
        print(el, '\n')

    # 5. Создаем обратноую матрицу из элементов справа от разделительной прямой
    return matrix[:, inverse_matrix.n:].copy()


matrix = np.array([[3.8, 6.7, -1.2],
                   [6.4, 1.3, -2.7],
                   [2.4, -4.5, 3.5]])

inverse_matrix(matrix)