Произведение матриц как композиция
Перемножить две матрицы — значит склеить два преобразования в одно: сначала одно, потом другое.
Произведение матриц $AB$ — это матрица преобразования, которое получается, если сначала применить $B$, а затем $A$.
Правило «строка на столбец» для умножения матриц на первый взгляд выглядит произвольным. Но за ним стоит ясная геометрия: умножение — это композиция функций. Если $B$ поворачивает, а $A$ растягивает, то $AB$ — «повернуть, потом растянуть». Это и объясняет, почему порядок важен.
Правило умножения
Элемент результата в строке $i$ и столбце $j$ — скалярное произведение $i$-й строки $A$ на $j$-й столбец $B$:
$$(AB)_{ij} = \sum_{t} A_{it} \, B_{tj}$$
Чтобы умножение было определено, число столбцов $A$ должно совпадать с числом строк $B$. Почему именно так? Потому что $AB$ применённое к вектору $\vec{v}$ должно давать $A(B\vec{v})$ — сначала $B$ действует на $\vec{v}$, потом $A$ на результат. Раскрыв это, мы и получаем правило строка-на-столбец.
Композиция и порядок
$$ (AB)\vec{v} = A(B\vec{v}) $$
Справа налево читается как «сначала $B$, затем $A$». Поэтому в общем случае $AB \neq BA$: повернуть-потом-растянуть и растянуть-потом-повернуть дают разный результат.
import math
def matmul(A, B):
n, m, k = len(A), len(B[0]), len(B)
return [[sum(A[i][t] * B[t][j] for t in range(k))
for j in range(m)] for i in range(n)]
def rot(theta):
c, s = math.cos(theta), math.sin(theta)
return [[c, -s], [s, c]]
# два поворота на 90 = один поворот на 180
R90 = rot(math.pi / 2)
R180 = matmul(R90, R90)
print("R90 * R90 =", [[round(x, 3) for x in row] for row in R180])Вывод:
R90 * R90 = [[-1.0, -0.0], [0.0, -1.0]]
Композиция подтверждается
Два поворота по $90°$ дали матрицу $\begin{bmatrix} -1 & 0 \\ 0 & -1 \end{bmatrix}$ — это поворот на $180°$, который переворачивает любой вектор. Математика композиции в точности совпала с геометрией: «дважды повернуть на $90°$» = «повернуть на $180°$».
Как работает под капотом
Тройной цикл в matmul буквально считает формулу $\sum_t A_{it} B_{tj}$: внешние индексы $i, j$ пробегают позиции результата, а внутренний $t$ — общую размерность, по которой идёт суммирование. Умножение матриц ассоциативно ($A(BC) = (AB)C$), что соответствует «применить три преобразования подряд можно группировать как угодно», но не коммутативно. Единичная матрица $I$ (единицы на диагонали) играет роль «ничего не делать»: $AI = IA = A$.
Частые ошибки
- Читать $AB$ как «сначала $A$, потом $B$». Наоборот: преобразования применяются справа налево, сначала $B$.
- Ожидать, что $AB = BA$. Для матриц это почти никогда не так — порядок преобразований важен.
- Перемножать матрицы несогласованных размеров. Число столбцов левой обязано равняться числу строк правой.
Итог
- Произведение матриц = композиция преобразований: $(AB)\vec{v} = A(B\vec{v})$.
- Правило строка-на-столбец вытекает из требования $A(B\vec{v})$.
- Умножение ассоциативно, но не коммутативно: $AB \neq BA$.
- Единичная матрица $I$ — нейтральный элемент: $AI = IA = A$.