Алгебра
Матрицы и определители
Каждый кадр видеоигры-тысячи матричных умножений. Поворот камеры, анимация скелета, перспективная проекция-всё матрицы 4×4. Определитель-подпись матрицы: ноль значит "необратимо", ненулевое значение гарантирует, что трансформация сохраняет объём с точностью до знака.
- **3D-графика (OpenGL/Vulkan):** матрицы Model, View, Projection перемножаются в GPU для каждой вершины каждого кадра
- **Normalizing Flows:** log|det(J)| якобиана входит в функцию потерь генеративных моделей-нужны архитектуры с дешёвым det
- **Гомография в CV:** матрица 3×3 кодирует проективное преобразование плоскости; det ≠ 0 гарантирует обратимость отображения
Предварительные знания
Операции с матрицами
Матрица A размером m×n-прямоугольный массив чисел. Сложение и вычитание определены только для матриц одинакового размера-почленно. Умножение C = AB: C[i][j] = Σₖ A[i][k] · B[k][j], требует A ∈ ℝ^{m×n}, B ∈ ℝ^{n×p} → C ∈ ℝ^{m×p}. Транспонирование: (Aᵀ)[i][j] = A[j][i].
**Умножение некоммутативно:** AB ≠ BA в общем случае. Но ассоциативно: (AB)C = A(BC). Транспонирование произведения: (AB)ᵀ = BᵀAᵀ-порядок меняется.
В numpy используйте `@` для матричного умножения, не `*`. Оператор `*`-поэлементное умножение (Hadamard product)-частая ошибка новичков.
Матрица A размера 3×4, матрица B размера 4×2. Каков размер произведения AB?
Определитель матрицы
Определитель det(A)-скаляр, приписанный квадратной матрице. Для 2×2: det([[a,b],[c,d]]) = ad−bc. Для n×n: разложение Лапласа по строке i: det(A) = Σⱼ (−1)^(i+j) · aᵢⱼ · Mᵢⱼ, где Mᵢⱼ-определитель матрицы без строки i и столбца j.
**Геометрический смысл:** |det(A)|-объём параллелепипеда, образованного строками матрицы. Знак определяет ориентацию. det(A) = 0 тогда и только тогда, когда строки линейно зависимы.
| Свойство | Формула | Применение |
|---|---|---|
| Произведение | det(AB) = det(A)·det(B) | Проверка вычислений |
| Транспонирование | det(Aᵀ) = det(A) | Симметрия по строкам/столбцам |
| Обратная | det(A⁻¹) = 1/det(A) | Существование обратной |
| Масштабирование | det(cA) = cⁿ·det(A) | Нормировка |
Если det(A) = 3 и det(B) = 4, чему равно det(AB)?
Правило Крамера и обратная матрица
Обратная матрица A⁻¹ существует тогда и только тогда, когда det(A) ≠ 0. Формула: A⁻¹ = adj(A)/det(A), где adj(A)[i][j] = (−1)^(i+j) · Mⱼᵢ. Правило Крамера: xᵢ = det(Aᵢ)/det(A), где Aᵢ-матрица A с i-м столбцом, заменённым на b.
Правило Крамера имеет сложность O(n!) наивно или O(n⁴)-не используйте его для n > 3. На практике применяйте LU-разложение (np.linalg.solve): O(n³).
При каком условии матрица A имеет обратную?
Трансформации и Якобиан
В 3D-графике каждая геометрическая операция кодируется матрицей. Поворот, масштаб, сдвиг и перспективная проекция-матрицы 4×4 в однородных координатах. Последовательное применение трансформаций-умножение матриц (применяется справа налево).
**Якобиан**-матрица частных производных: J[i][j] = ∂fᵢ/∂xⱼ. Его определитель-коэффициент изменения объёма. В normalizing flows log|det(J)| входит в функцию потерь.
Матрица поворота R на угол θ в 2D имеет det(R) =
Ключевые идеи
- **AB ≠ BA:** умножение некоммутативно; размер A(m×n)·B(n×p) = C(m×p); используйте `@` в numpy
- **det(A):** геометрически-объём параллелепипеда; алгебраически-условие обратимости (det ≠ 0)
- **det(AB) = det(A)·det(B):** мощное мультипликативное свойство; det(R) = 1 для матриц поворота
- **np.linalg.solve(A, b)** всегда предпочтительнее inv(A) @ b-быстрее и численно устойчивее
Связанные темы
Матрицы и определители-основа всей линейной алгебры курса:
- Системы уравнений — Ax=b: разрешимость определяется det(A) и рангом-следующая тема
- Собственные значения — det(A−λI)=0-характеристический полином для нахождения λ
- SVD — SVD обобщает собственное разложение на прямоугольные матрицы
Вопросы для размышления
- Почему в GPU-шейдерах матрицы поворота хранятся как 4×4, хотя поворот в 3D-это 3×3 операция?
- В normalizing flows det(J) вычисляется для матриц размером тысячи×тысячи. Какие специальные структуры (triangular, coupling layers) делают это эффективным?
- Почему np.linalg.solve(A, b) численно устойчивее, чем np.linalg.inv(A) @ b, хотя математически эквивалентны?