Транспонирование, единичная и обратная матрицы
Транспонирование меняет строки и столбцы местами; единичная матрица — это «1», а обратная — «деление» в мире матриц.
Транспонирование Aᵀ — отражение матрицы относительно главной диагонали: элемент (i, j) становится элементом (j, i).
Транспонирование: строки ↔ столбцы
Транспонировать — значит «повернуть» таблицу: то, что было строкой, становится столбцом. Матрица m×n превращается в n×m. В ML это встречается на каждом шагу: формула линейной регрессии содержит Xᵀ·X, а скалярное произведение строго записывают как aᵀ·b.
def transpose(M):
rows = len(M)
cols = len(M[0])
return [[M[i][j] for i in range(rows)] for j in range(cols)]
A = [[1, 2, 3],
[4, 5, 6]]
AT = transpose(A)
print("A (2x3):", A)
print("AT (3x2):", AT)
Вывод:
A (2x3): [[1, 2, 3], [4, 5, 6]] AT (3x2): [[1, 4], [2, 5], [3, 6]]
Единичная матрица — это «1»
Единичная матрица I — квадратная, с единицами на главной диагонали и нулями вокруг. Её преобразование — «ничего не делать»: I·v = v. Для матриц она играет роль числа 1: A·I = A. Это опорная точка для определения обратной матрицы.
def identity(n):
return [[1 if i == j else 0 for j in range(n)] for i in range(n)]
def matvec(M, v):
return [sum(M[i][j] * v[j] for j in range(len(v))) for i in range(len(M))]
I = identity(3)
for row in I:
print(row)
print("I @ [7, 8, 9] =", matvec(I, [7, 8, 9])) # вектор не изменился
Вывод:
[1, 0, 0] [0, 1, 0] [0, 0, 1] I @ [7, 8, 9] = [7, 8, 9]
Обратная матрица — это отмена
Обратная матрица A⁻¹ отменяет действие A: если A что-то преобразовала, то A⁻¹ возвращает обратно. Формально A·A⁻¹ = I. Это аналог деления: «разделить на матрицу» = «умножить на обратную». Через обратную матрицу записывают точное решение системы уравнений: x = A⁻¹·b.
Но есть нюанс: обратная существует не всегда. Если преобразование «схлопывает» пространство (например, проецирует плоскость в линию), вернуть назад нельзя — информация потеряна. Такие матрицы называют вырожденными, их определитель равен нулю. Для матрицы 2×2 обратную можно выписать формулой.
def inverse_2x2(M):
(a, b), (c, d) = M[0], M[1]
det = a * d - b * c
if det == 0:
return None # вырожденная: обратной нет
return [[ d / det, -b / det],
[-c / det, a / det]]
def matmul(A, B):
m = len(B)
return [[sum(A[i][k] * B[k][j] for k in range(m)) for j in range(len(B[0]))]
for i in range(len(A))]
A = [[4, 7],
[2, 6]]
Ainv = inverse_2x2(A)
product = matmul(A, Ainv)
# округляем, чтобы убрать крошечную погрешность чисел с плавающей точкой
product = [[round(x, 10) for x in row] for row in product]
print("A^-1 =", Ainv)
print("A * A^-1 =", product) # должна получиться единичная
Вывод:
A^-1 = [[0.6, -0.7], [-0.2, 0.4]] A * A^-1 = [[1.0, 0.0], [-0.0, 1.0]]
Итог
- Транспонирование меняет строки и столбцы местами: (i, j) → (j, i).
- Единичная матрица I — это «1» для умножения: I·v = v, A·I = A.
- Обратная A⁻¹ отменяет преобразование: A·A⁻¹ = I; существует не всегда.
- Вырожденная матрица (det = 0) необратима — преобразование теряет информацию.