Приведение матрицы к треугольному виду

def Gauss(A):
    for k in range(len(A) - 1):
        At = A.copy()
        for i in range(len(A)):
          for j in range(len(A)):
              if(i <= k): A[i][j] = At[i][j]
              elif(i > k and j > k): A[i][j] = round(At[i][j] - (At[i][k] / At[k][k]) * At[k][j], 4)
              elif(i > k and j <= k): A[i][j] = 0
    return A

with open('matrix.txt') as f:
    matrix = [list(map(float, row.split())) for row in f.readlines()]

M = Gauss(matrix)
for i in range(len(M)): print(*M[i])

Не понимаю, почему никаких изменений в матрице не происходит на 7 строке, притом что если убрать строку 8, то изменения будут?


Ответы (1 шт):

Автор решения: Stanislav Volodarskiy

Вот ваш код с отладочной печатью:

def Gauss(A):
    for k in range(len(A) - 1):
        At = A.copy()
        for i in range(len(A)):
            assert At[i] is A[i]
            for j in range(len(A)):
                if(i <= k): A[i][j] = At[i][j]
                elif(i > k and j > k):
                    print('use', i, k)
                    A[i][j] = round(At[i][j] - (At[i][k] / At[k][k]) * At[k][j], 4)
                elif(i > k and j <= k):
                    print('clear', i, j)
                    A[i][j] = 0
    return A

matrix = [[2, 1], [4, 1]]

M = Gauss(matrix)
for i in range(len(M)):
    print(*M[i])

Он печатает следущее:

clear 1 0
use 1 0
2 1
0 1.0

assert показывает что копирование не удалось. Массивы A и At используют одни и те же строки. Строка clear 1 0 показывает что стёрт элемент матрицы, а строка use 1 0 показывает что стёртое значение используется в вычислениях.

P.S. Гауссово исключение можно написать без изготовления копий матрицы, если делать это аккуратно.

→ Ссылка