系列 · 线性代数 · 第 4 篇

线性代数(四):行列式的秘密

行列式不只是繁琐的计算 -- 它度量的是变换对空间的拉伸或压缩程度。本章给出行列式的几何直觉、关键性质和实际应用。

跳出公式:行列式到底是什么#

$$ \det\begin{pmatrix}a & b\\ c & d\end{pmatrix} = ad - bc. $$

记住公式,代入数字,算出结果——这种教法完全忽略了行列式的本质。

线性代数(四):行列式的秘密 — 章节概览图

一句话点明核心:

行列式 $\det(A)$ 就是变换 $A$ 对面积(2D)或体积(3D)的缩放倍数。

一旦理解了这一点,行列式的各种性质就不再是死记硬背的规则,而是可以直观看到的事实:

  • $\det(AB) = \det(A)\det(B)$ :两次缩放的倍数自然相乘。
  • $\det(A) = 0$ :空间被压平,信息丢失。
  • $\det(A^{-1}) = 1/\det(A)$ :逆变换必须把缩放还原。
  • 行列式的符号:表示空间是否发生了翻转(像镜子成像一样)。

本章内容#

  • 行列式在 2D 和 3D 中的几何意义
  • 行列式的符号说明了什么(方向性)
  • $\det = 0$ 的含义(奇异矩阵、信息丢失)
  • 核心性质及其几何直观解释
  • 三种计算行列式的方法
  • 应用:克拉默法则、面积/体积公式、雅可比行列式

前置知识#


二维行列式:面积缩放因子#

从单位正方形开始#

在平面上,单位正方形是最简单的参考对象。它的四个顶点分别是 $(0,0)$$(1,0)$$(1,1)$$(0,1)$ ,由标准基向量 $\vec{e}_1 = (1,0)$$\vec{e}_2 = (0,1)$ 张成,面积正好是 $1$

一个 $2 \times 2$ 矩阵 $A = \begin{pmatrix}a & b\\ c & d\end{pmatrix}$ 把基向量映射到矩阵的两列:

  • $\vec{e}_1 \;\mapsto\; (a, c)$ —— 第一列
  • $\vec{e}_2 \;\mapsto\; (b, d)$ —— 第二列
$$ \text{面积} = |ad - bc| = |\det(A)|. $$

这就是二维行列式的意义。

行列式 = 面积缩放因子:单位正方形被矩阵 $A$
 变成一个平行四边形,其面积等于 $|\det A|$
。

一个具体例子#

$$ A = \begin{pmatrix}3 & 1\\ 0 & 2\end{pmatrix}, \qquad \det(A) = 3\cdot 2 - 1\cdot 0 = 6. $$

单位正方形(面积 $1$ )变成了面积为 $6$ 的平行四边形。平面里的所有图形都被同一个倍数缩放:面积为 $\pi$ 的圆变成面积为 $6\pi$ 的椭圆,面积为 $0.5$ 的三角形变成面积为 $3$ 的三角形。矩阵不关心形状,只决定局部面积的缩放比例。

复印机的类比#

$$ A = \begin{pmatrix}2 & 0\\ 0 & 2\end{pmatrix}, \qquad \det(A) = 4. $$

宽度变成原来的 $2$ 倍,高度也变成原来的 $2$ 倍,但面积变成原来的 $4$(不是 $2$ 倍)。这就是线性变换中让人意外的地方,而行列式直接告诉你这个倍数。

三种变换,三种行列式#

为了更直观地理解,看三个不同的 $A$ 对同一个单位正方形的作用:

同样的输入,三种不同的行列式:错切保持面积不变,拉伸让面积翻倍,压缩让面积减半。

  • 错切(Shear)$\det = 1$ :平行四边形倾斜了,但面积没变。想象把一摞书顶部往一边推一推,总体积不会变。
  • 拉伸$\det = 2$ :某个方向拉长一倍,面积也跟着翻倍。
  • 压缩$\det = 0.5$ :某个方向压扁一半,面积变成一半。

这些变换形状各不相同,但行列式抓住了它们共同的一个数字:面积的变化量。

行列式的符号:方向#

绝对值 $|\det(A)|$ 表示大小,符号表示方向。

  • $\det(A) > 0$ :变换保持方向。逆时针的环路还是逆时针。
  • $\det(A) < 0$ :变换翻转方向。逆时针变成顺时针,就像镜子的效果。

例子:沿 $y$ 轴反射#

$$ A = \begin{pmatrix}-1 & 0\\ \phantom{-}0 & 1\end{pmatrix}, \qquad \det(A) = -1. $$
  • $|\det| = 1$ :面积不变。
  • 负号表示翻转。在透明纸上写字,举起来对着镜子看,看到的就是 $A$ 的效果。

反射把右手系变成左手系;行列式变为 $-1$
。

手套的比喻#

拿一只右手手套。旋转、拉伸、挤压它,它还是右手手套。但如果你把它从里往外翻,它就变成了左手手套。这种“翻面”操作正是负行列式的作用。旋转和拉伸会让 $\det > 0$ ,而反射会改变符号。

行列式为零:空间被压扁#

面积缩放因子是 $0$ ,变换后的面积自然就是 $0$ 。在二维情况下,这只有一个可能:整个平面被压缩到一条直线上(极端情况下甚至缩成一个点)。

例子#

$$ A = \begin{pmatrix}1 & 2\\ 2 & 4\end{pmatrix}, \qquad \det(A) = 1\cdot 4 - 2\cdot 2 = 0. $$

第二列 $(2, 4)$ 恰好是第一列 $(1, 2)$ 的两倍。两个基向量都被映射到同一条直线——也就是过原点、方向为 $(1, 2)$ 的那条直线。整个平面的点都被压到这条直线上,二维空间直接坍塌成了一维。

当 $\det = 0$
,整个平面被压到一条更低维的子空间上。原来不同的点会被送到同一处。

为什么不可逆#

把一张二维照片压成一条线,还能还原吗?显然不行。原本不同的点现在挤到了同一个位置,根本分不清谁是谁。信息已经丢失,所以 $A^{-1}$ 根本不存在。

$$ \det(A) = 0 \;\Longleftrightarrow\; A\text{ 不可逆(奇异)}\;\Longleftrightarrow\; A\text{ 的列向量线性相关}. $$

这也提供了一个快速判断线性相关的方法:计算行列式即可。

三维行列式:体积缩放因子#

线性代数(四):行列式的秘密 — 章节小结图

二维讲的内容可以直接搬到三维。单位立方体由 $\vec{e}_1, \vec{e}_2, \vec{e}_3$ 构成,一个 $3 \times 3$ 矩阵会把它变成一个斜着的盒子——平行六面体。行列式的值就是这个盒子的(带符号)体积。

三维中,$3\times 3$
 矩阵将单位立方体映射为平行六面体;$|\det A|$
 就是它的体积。

公式#

$$ \det\begin{pmatrix}a & b & c\\ d & e & f\\ g & h & i\end{pmatrix} = a(ei - fh) - b(di - fg) + c(dh - eg). $$ $$ \det(A) = \vec{v}_1 \cdot (\vec{v}_2 \times \vec{v}_3), $$

这也是计算平行六面体(带符号)体积的标准方法。

三维中的负号#

如果三维行列式为负,说明右手坐标系被翻转成了左手坐标系(比如对某个轴做反射)。反射、点反演或者奇数次镜像翻转都会让 $\det < 0$


行列式的性质——全是几何#

把行列式理解成缩放因子后,那些代数性质就不再是死记硬背的规则,而是关于缩放的直观描述。

乘法性:$\det(AB) = \det(A)\det(B)$ #

$B$ 把体积缩放 $\det(B)$ 倍,接着 $A$ 再缩放 $\det(A)$ 倍。总的缩放倍数就是两者的乘积。就像复印机先放大 $1.5\times$ ,再放大 $3\times$ ,最终面积变成 $4.5\times$

两次变换接连作用:每次按自己的行列式倍数缩放面积,合成后的行列式就是两者乘积。

转置不变:$\det(A^T) = \det(A)$ #

把行换成列,体积缩放因子不变。从几何上看,转置后的平行六面体形状变了,但体积一样——这是理论中的一个小奇迹。

逆矩阵:$\det(A^{-1}) = 1/\det(A)$ #

如果 $A$ 把体积放大 $k$ 倍,那么 $A^{-1}$ 必须把它缩小 $k$ 倍。代数上验证:$\det(A)\det(A^{-1}) = \det(I) = 1$

行交换:行列式变号#

交换两行,行列式乘以 $-1$ 。交换两个基向量等于翻转坐标系的手性,符号自然反过来。

行倍乘:行列式跟着倍乘#

把某一行乘以 $k$ ,行列式也乘以 $k$ 。你把一个基向量拉长 $k$ 倍,平行四边形的面积也就扩大 $k$ 倍。

推论$\det(kA) = k^n \det(A)$ ,因为 $k$ 同时作用在 $n$ 行上。

行加法:行列式不变#

把一行加上另一行的常数倍,行列式不变。

这是一个错切操作:平行四边形形状变了,但面积没变。想象一摞牌被斜推一下,每张牌错开,但整摞的体积没变。

正是这一条让高斯消元法计算行列式变得简单:消元过程不会改变行列式,只需记录行交换的符号变化和行倍乘的影响。

几种特殊矩阵#

矩阵类型行列式
单位矩阵 $I$$1$
对角矩阵对角元素之积
三角矩阵(上或下三角)对角元素之积

三角矩阵这条特别重要:任何矩阵都能通过行变换化成三角形式,化完之后行列式只剩下一连串乘法。

怎么算行列式#

$2 \times 2$ :直接套公式#

$$ \det\begin{pmatrix}a & b\\ c & d\end{pmatrix} = ad - bc. $$

$3 \times 3$ :Sarrus 法则#

$$ \det\begin{pmatrix}1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9\end{pmatrix} = (1\cdot 5\cdot 9 + 2\cdot 6\cdot 7 + 3\cdot 4\cdot 8) - (3\cdot 5\cdot 7 + 2\cdot 4\cdot 9 + 1\cdot 6\cdot 8) = 0. $$

结果是 $0$ ,因为每一行都是上一行加一个常数——行之间线性相关。

注意: Sarrus 法则只适用于 $3 \times 3$ 矩阵。别试图把它推广到 $4 \times 4$ 或更大的矩阵,那样会算错。

通用方法:余子式(Laplace)展开#

$$ \det(A) = \sum_{j=1}^{n} (-1)^{i+j} a_{ij}\, M_{ij}, $$

其中 $M_{ij}$余子式,也就是删掉第 $i$ 行和第 $j$ 列后剩下的 $(n-1)\times(n-1)$ 子矩阵的行列式。符号 $(-1)^{i+j}$ 像棋盘格一样交替变化;比如 $3 \times 3$ 矩阵的第一行符号是 $+, -, +$

余子式展开的图示:选一行,每个元素乘以“删掉它所在行列”后的子矩阵行列式,按棋盘格符号交替加减。

实用技巧:选含零最多的行或列展开,零项直接省略,计算量会少很多。

实际计算大矩阵:高斯消元#

余子式展开的复杂度是 $O(n!)$ ,到了 $n = 10$ 左右就跑不动了。实际计算时,我会用初等行变换把矩阵化成上三角形式(每步操作对行列式的影响是已知的),然后把对角线元素相乘。复杂度是 $O(n^3)$ ——这正是 numpy.linalg.det 内部的实现方式。

1
2
3
4
5
6
7
import numpy as np

A = np.array([[3, 1], [2, 4]])
print(f"det(A) = {np.linalg.det(A):.1f}")   # 10.0

B = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(f"det(B) = {np.linalg.det(B):.1f}")   # 0.0(含浮点噪声)

克拉默法则#

$$ x_i = \frac{\det(A_i)}{\det(A)}, $$

这里 $A_i$ 是把矩阵 $A$ 的第 $i$ 列替换成向量 $\vec{b}$ 后得到的新矩阵。

例子

$$ \begin{cases} 2x + y = 5 \\ 3x + 4y = 11 \end{cases} $$ $$ \det(A) = 8 - 3 = 5,\quad \det(A_1) = 20 - 11 = 9,\quad \det(A_2) = 22 - 15 = 7, $$

于是解得 $x = 9/5,\; y = 7/5$

几何意义:在二维情况下,$\det(A_1)/\det(A)$ 就是“替换第一列后平行四边形的面积”与“原平行四边形面积”的比值,这个比值正好对应 $x$ 。克拉默法则本质上是在用面积比例求解方程组。

注意:克拉默法则虽然形式优美,但实际计算效率很低(即使最优实现也需要 $O(n^4)$ ,而高斯消元法只需 $O(n^3)$ )。它适合用来证明理论性质,或者处理 $2 \times 2$$3 \times 3$ 的符号计算问题,千万别用它去解大规模方程组。

应用#

三角形面积#

$$ \text{面积} = \tfrac{1}{2}\left|\det\begin{pmatrix} x_2 - x_1 & x_3 - x_1 \\ y_2 - y_1 & y_3 - y_1 \end{pmatrix}\right|. $$

这个公式实际上是在计算两条边张成的平行四边形面积的一半。

叉积与行列式#

$$ \vec{a} \times \vec{b} = \det\begin{pmatrix} \vec{i} & \vec{j} & \vec{k} \\ a_1 & a_2 & a_3 \\ b_1 & b_2 & b_3 \end{pmatrix}. $$

叉积的模长 $\|\vec{a}\times\vec{b}\|$ 就是向量 $\vec{a}$$\vec{b}$ 张成的平行四边形的面积。从本质上说,这就是一个隐藏在 $2 \times 2$ 行列式中的几何量。

雅可比行列式#

$$ \iint f(x, y)\, dx\, dy = \iint f\bigl(x(u, v),\, y(u, v)\bigr) \left|\det \frac{\partial(x, y)}{\partial(u, v)}\right| du\, dv. $$

这里的 雅可比行列式 $\left|\det\frac{\partial(x,y)}{\partial(u,v)}\right|$ 是局部面积缩放的比例因子。它实际上是变量替换在每一点上的线性近似的行列式值。从几何上看,就是把“行列式等于面积缩放”的定理应用到每个无穷小的面元上。

$$ \left|\det \frac{\partial(x, y)}{\partial(r, \theta)}\right| = \det\begin{pmatrix} \cos\theta & -r\sin\theta \\ \sin\theta & \phantom{-}r\cos\theta \end{pmatrix} = r. $$

这就是微积分里常见的 $dx\,dy = r\,dr\,d\theta$ 中 “$r$ ” 的来源。以前可能靠背诵记住它,现在可以直接通过行列式推导出来。

行列式与线性方程组的解#

对于方阵 $A$ 的线性方程组 $A\vec{x} = \vec{b}$ ,可以根据行列式的值判断解的情况:

条件结果
$\det(A) \neq 0$存在唯一解
$\det(A) = 0$ ,齐次($\vec{b} = 0$存在非平凡解
$\det(A) = 0$$\vec{b} \neq 0$无解 或 无穷多解

Python:直观理解行列式#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import numpy as np
import matplotlib.pyplot as plt

def show_determinant(A):
    """展示矩阵 A 如何变换单位正方形,并显示面积变化。"""
    square = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]).T
    transformed = A @ square
    det = np.linalg.det(A)

    fig, axes = plt.subplots(1, 2, figsize=(12, 5))

    axes[0].fill(square[0], square[1], alpha=0.3, color="#2563eb")
    axes[0].set_title("单位正方形(面积 = 1)")
    axes[0].set_xlim(-3, 3); axes[0].set_ylim(-3, 3)
    axes[0].set_aspect("equal"); axes[0].grid(True, alpha=0.3)

    color = "#10b981" if det > 0 else ("#f59e0b" if det < 0 else "#94a3b8")
    axes[1].fill(transformed[0], transformed[1], alpha=0.3, color=color)
    axes[1].set_title(f"变换后(面积 = {abs(det):.2f}, det = {det:.2f})")
    axes[1].set_xlim(-3, 3); axes[1].set_ylim(-3, 3)
    axes[1].set_aspect("equal"); axes[1].grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

show_determinant(np.array([[2, 0], [0, 1.5]]))   # 拉伸,det = 3
show_determinant(np.array([[1, 0.5], [0, 1]]))    # 错切,det = 1
show_determinant(np.array([[-1, 0], [0, 1]]))     # 反射,det = -1

自己再试试几个矩阵吧,尤其是 $\det = 0$ 的情况——你会看到平行四边形直接变成一条线。


总结#

思维模型#

看到行列式的时候,别想着“我要算出一个数字”。而是问自己:

“这个变换对空间的大小和方向做了什么?”

  • $|\det(A)|$ —— 空间的面积或体积被放大了多少倍
  • $\det > 0$ —— 方向保持不变
  • $\det < 0$ —— 方向翻转了(镜像效果)
  • $\det = 0$ —— 空间被压平了,信息丢失,矩阵不可逆

关键性质一览#

性质公式直观理解
乘法性$\det(AB) = \det(A)\det(B)$缩放倍数直接相乘
转置不变$\det(A^T) = \det(A)$行和列的作用是对称的
逆矩阵$\det(A^{-1}) = 1/\det(A)$抵消原来的缩放效果
整体倍乘$\det(kA) = k^n \det(A)$$k$$n$ 个维度同时起作用

为什么没人用余子式展开计算行列式#

余子式公式看起来很美,递归定义也很优雅,但它的速度慢得让人无法接受。假设 $T(n)$ 是用余子式展开法计算 $n \times n$ 行列式所需的乘法次数。根据递推公式 $T(n) = n \cdot T(n-1)$ ,可以得出 $T(n) = n!$ 。当 $n=20$ 时,需要 $2.4 \times 10^{18}$ 次乘法——单核 CPU 算几十年都搞不定。而当 $n=50$ 时,乘法次数甚至超过了地球上原子的总数。

$$ \det A = (-1)^{\text{交换次数}} \prod_{i=1}^n U_{ii}. $$

LU 分解的计算复杂度是 $\tfrac{2}{3}n^3$ FLOPs,而计算 $U$ 的对角元乘积只需要线性时间。因此,行列式的计算复杂度从 $\Theta(n!)$ 降到了 $\Theta(n^3)$ 。以 $n=20$ 为例,效率提升了 $3 \times 10^{14}$ 倍。

这里有两个实用建议:

  • 计算 $\det A$ 时用到的 LU 分解,还可以用来求 $A^{-1}$ 和任意右端项 $Ax=b$ 的解。如果需要同时计算行列式和解方程,千万别分别调用 np.linalg.detnp.linalg.solve。改用 scipy.linalg.lu_factor 分解一次,结果可以重复利用。
  • 对于对称正定矩阵, Cholesky 分解更快,只需 $\tfrac{1}{3}n^3$ FLOPs。分解形式是 $A=LL^T$ ,行列式可以直接写成 $\det A = (\prod L_{ii})^2$

所以,余子式公式虽然漂亮,但它只适合留在教科书里,用来解释行列式是什么。真要动手算,我会利用行列式的乘法性质 $\det(LU) = \det L \cdot \det U$ ,再加上一个简单的事实:三角矩阵的行列式就是对角元的乘积。

slogdet 技巧:行列式下溢时怎么办#

第一次实现高斯分布的极大似然估计时,你就会遇到这个问题。对数似然中包含 $\log\det\Sigma$ ,其中 $\Sigma$ 是协方差矩阵。假设一个 $200\times 200$ 的协方差矩阵,特征值都在 $0.01$ 左右,那么行列式的值大约是 $0.01^{200}=10^{-400}$ 。在双精度浮点数中,这个值直接变成 $0$ (双精度最小正数约为 $5\times 10^{-324}$ )。于是,np.log(np.linalg.det(Sigma)) 返回 -inf,训练过程直接崩溃。

解决办法很简单:永远不要直接计算行列式。 numpy 提供了 np.linalg.slogdet,它会分别返回符号和对数绝对值:

1
2
3
4
5
import numpy as np
Sigma = 0.01 * np.eye(200)
print(np.linalg.det(Sigma))         # 0.0  —— 下溢
sign, logabsdet = np.linalg.slogdet(Sigma)
print(sign, logabsdet)              # 1.0  -921.034...
$$ \log|\det A| = \sum_{i=1}^n \log|U_{ii}|. $$

多个小数相乘容易下溢,但它们的对数相加不会。这种技巧在很多地方都能看到: HMM 中的 log 概率、能量模型中的 log 配分函数、 normalising flow 中的 log Jacobian。只要遇到“大量因子相乘,每个因子可能很小或很大”的情况,就该想到用 log 空间处理。

还有一个好习惯:如果需要比较两个行列式的大小或符号,直接比较它们的对数值即可。如果确实需要行列式的值,最后再用公式 $\det A = \mathrm{sign}\cdot e^{\log|\det A|}$ 计算,尽量避免这么做。


下一步#

第 5 章 :线性方程组与列空间
这一章会把前面讲过的所有内容——矩阵、变换、行列式——整合起来,研究 $A\vec{x} = \vec{b}$ 是否有解、有多少解,以及解的结构是什么样子。重点是三个核心概念:列空间(矩阵 $A$ 能覆盖哪些向量?)、零空间(哪些向量会被压缩成零?)和(还剩下多少个有效维度?)。对于方阵来说,行列式仍然是关键;但如果是非方阵或者秩亏的情况,就需要更精细的工具了。

本系列

线性代数 18 篇

  1. 01 线性代数(一):向量的本质——不仅仅是箭头
  2. 02 线性代数(二):线性组合与向量空间
  3. 03 线性代数(三):矩阵作为线性变换
  4. 04 线性代数(四):行列式的秘密 当前
  5. 05 线性代数(五):线性方程组与列空间
  6. 06 线性代数(六):特征值与特征向量
  7. 07 线性代数(七):正交性与投影——当向量互不干扰
  8. 08 线性代数(八):对称矩阵与二次型
  9. 09 线性代数(九):奇异值分解 SVD
  10. 10 线性代数(十):矩阵范数与条件数——数值计算的健康体检
  11. 11 线性代数(十一):矩阵微积分与优化——从梯度到反向传播
  12. 12 线性代数(十二):稀疏矩阵与压缩感知——少即是多的数学奇迹
  13. 13 线性代数(十三):张量与多线性代数——从标量到高维数据立方体
  14. 14 线性代数(十四):随机矩阵理论——混沌中的秩序
  15. 15 线性代数(十五):机器学习中的线性代数——从 PCA 到推荐系统
  16. 16 线性代数(十六):深度学习中的线性代数——从全连接到 Transformer
  17. 17 线性代数(十七):计算机视觉中的线性代数——从像素到三维重建
  18. 18 线性代数(十八):前沿应用与总结——量子计算、GNN、大模型,与十八章回望

读有所得?

GitHub 关注我 → 新文周更

GitHub