行列式
矩阵可以把平面拉伸、剪切、旋转,但有一件事对所有形状都一样:面积被放大了同一个倍数。这个倍数就是行列式。它为正,空间保持朝向;为负,空间被翻了面;为零,空间被压扁,再也回不来。
1为什么机器人需要它
行列式只是一个数,却能一眼看出一个矩阵"好不好用"。机器人里有三个场合天天碰到它。
- 奇异位形。机械臂的雅可比矩阵 \(J\) 把关节速度变成手端速度。一旦 \(\det J = 0\),手端就丢了一个运动方向:不管关节怎么转,手都不能往那个方向动。手臂完全伸直就是典型例子(本课第 8 节会亲手试;3.3、3.4 节会深入)。
- 手性(handedness)。你用标定数据拟合出一个"旋转矩阵",或者从文件里读到一个"旋转",它的行列式却是 \(-1\)。那不是旋转,而是带镜像的变换。机器人会很听话地伸向目标的镜像位置,左手变右手,而且没有任何报错。这是机器人代码里的经典 bug。
- 概率密度的变换。变量经过线性(或局部线性)变换后,概率密度要除以 \(|\det|\):同样多的概率被摊到了面积放大后的区域上。粒子滤波、扩展卡尔曼滤波和之后的归一化流(normalizing flow)都离不开它。
2直觉:同一个面积倍数
回到 1.3 节的实验室。\(\ihat\) 被送到第一列,\(\jhat\) 被送到第二列,面积为 1 的单位正方形变成了一个平行四边形。这个平行四边形的面积,就是本课的主角。
但这只是一个正方形。换成一个圆、一个三角形、一个机器人的轮廓,会怎样?想一想:把任何形状切成很多很多小方格。线性变换把网格变成平行、等距的平行四边形网格,每一个小方格都变成同样大小的平行四边形。所以每个小格子的面积都乘以同一个数,加起来,整块区域的面积也乘以这个数。
这个数叫行列式,记作 \(\det A\)。它还带一个符号:如果变换把平面"翻了面"(像照镜子,\(\ihat\) 转到了 \(\jhat\) 的顺时针一侧),我们就记为负数。
行列式是矩阵作用下面积(三维里是体积)的缩放倍数,对所有形状相同。\(|\det A| > 1\) 放大,\(|\det A| < 1\) 缩小,\(\det A < 0\) 表示空间被翻了面,\(\det A = 0\) 表示空间被压到更低的维度(一条线,甚至一个点)。
3动手玩:行列式实验室
拖动红色 Aî 和绿色 Aĵ 的箭头尖,或者直接改矩阵里的数,或者点一个预设。图里有三样东西:单位正方形(它的像是平行四边形)、一块不规则的"轮廓",以及一个不对称的字母 F。虚线是变换前,实色是变换后。小弧线从 Aî 转向 Aĵ:逆时针说明朝向保持,顺时针说明被翻了面,这时平行四边形变紫,F 变成镜像。
- 让 \(\det A = 2\)(误差 ±0.05)。不止一种做法,试试看能找到几种。
- 做出一个保持面积(\(\det A = 1\))但形状变了的矩阵,而且它不是旋转。提示:剪切。
- 找一个非零矩阵,让 \(\det A = 0\)。单位正方形变成了什么?
- 让平面翻面(\(\det A < 0\)),但不要用纯镜像(对角线上只有 ±1 的那种)。提示:把 Aî 和 Aĵ 互换位置,看看会怎样。
小游戏:估一估面积
下面随机给一个矩阵,单位正方形被变成了平行四边形。不要算,凭眼睛估计它的 \(\det\):数一数平行四边形盖住了几个原来的方格(每格面积 1),注意颜色和 F 的方向(紫色表示负)。用滑块给出你的猜测,点"检查"。误差在 10% 以内算猜中。
- 累计猜中 3 次(误差在 10% 以内)。
4第二视角:\(ad - bc\) 从哪里来
二阶行列式的公式 \(\det\begin{bmatrix}a&b\\c&d\end{bmatrix} = ad - bc\) 看起来像是凭空冒出来的。其实它就是一幅小图。平行四边形的两条边是 \((a, c)\) 和 \((b, d)\):先用一个长方形把它框住,再把四周多出来的角减掉,剩下的就是它。
按"下一步",一步步看。(图里取 \(a,b,c,d\) 全为正、\(\det > 0\);其他情形思路一样,只是要小心符号。)
- 走到最后一步,然后拖动一个箭头尖,确认剩下的面积始终等于 \(ad - bc\)。
有符号面积:两个向量围成的平行四边形
公式里没有绝对值,所以 \(ad - bc\) 可以是负的。把两列记作 \(\mathbf u = (a, c)\)、\(\mathbf w = (b, d)\),则 \(\det[\mathbf u\ \mathbf w] = u_x w_y - u_y w_x\) 是 \(\mathbf u\) 和 \(\mathbf w\) 围成的平行四边形的有符号面积:\(\mathbf w\) 在 \(\mathbf u\) 的逆时针一侧(左边)为正,在顺时针一侧(右边)为负,两者共线时为 0。等价地,\(\det[\mathbf u\ \mathbf w] = |\mathbf u||\mathbf w|\sin\theta\),\(\theta\) 是从 \(\mathbf u\) 转到 \(\mathbf w\) 的有向夹角。这就是二维叉积;1.8 节会用它做"左转还是右转"的判断,并推广到三维。
- 让 u 和 w 保持足够长(都大于 0.8),但面积为 0(共线)。
- 点"交换 u 与 w",观察符号怎么变。交换两列,行列式发生了什么?
5第三视角:复合时面积相乘
1.4 节说过,先做 \(B\) 再做 \(A\) 就是乘积 \(AB\)。既然每个矩阵都对所有面积乘一个固定倍数,那么两步下来,面积就连续乘了两次:\(B\) 乘以 \(\det B\),\(A\) 再乘以 \(\det A\)。所以
拖动阶段滑块(或点"播放"),看单位正方形先被 \(B\) 变换、再被 \(A\) 变换,面积一步步变化。可以改两个矩阵,也可以点例子。
- 让 \(A\) 和 \(B\) 各自都翻面(行列式都为负),看乘积会怎样。负负得正,翻两次又翻回来了。
- 让 \(B\) 把平面压扁(\(\det B = 0\)),而 \(A\) 的行列式的绝对值大于 0.5。后面的 \(A\) 能把它"救回来"吗?
- 让 \(\det(AB) = 1\),同时 \(A\) 和 \(B\) 的行列式都不是 1(偏离 1 超过 0.4):一个放大,一个正好缩回去。
逆矩阵:\(AA^{-1} = I\),且 \(\det I = 1\),所以 \(\det(A^{-1}) = 1/\det A\)。压扁不可逆:\(\det A = 0\) 时 \(1/\det A\) 不存在。平面被压到一条线上后,不同的点已经叠在了一起,没有任何矩阵能把它们重新分开,这是 1.6 节要讲的内容。上面的第二个任务就是这个道理:只要 \(B\) 压扁了平面,不管后面接什么,乘积的行列式永远是 0。
6三维:体积与手性
一切照搬到三维:\(3\times3\) 矩阵把单位立方体变成一个平行六面体(parallelepiped),它的体积就是 \(|\det A|\),三条棱是 \(A\) 的三列。符号讲的是手性:右手系的三根轴 \((\ihat, \jhat, \khat)\) 被送到 \((A\ihat, A\jhat, A\khat)\) 后,如果仍然满足右手定则(右手四指从 \(A\ihat\) 弯向 \(A\jhat\),拇指指向 \(A\khat\) 一侧),则 \(\det A > 0\);如果变成了左手系,则 \(\det A < 0\)。\(\det A = 0\) 时立方体被压成一块平板、一条线,甚至一个点。
选一个预设或编辑矩阵,拖动画面转动视角。
- 让右手系变成左手系:右上角的标签变成"左手系"。提示:交换两列。
- 让立方体塌成一个平面(\(\det \approx 0\),矩阵非零)。三列之间是什么关系?
7再看数学
提示:把鼠标悬停在公式中带底色的符号上,FIG 2 中对应的元素会被高亮。
用三条性质定义
行列式是方阵的一个数,把方阵看成 \(n\) 个列向量 \([\mathbf a_1\ \cdots\ \mathbf a_n]\),它由三条性质唯一确定:
- 单位不变:\(\det I = 1\)。单位正方形(立方体)体积为 1。
- 对每一列线性:把某一列放大 \(s\) 倍,行列式放大 \(s\) 倍;\(\det[\mathbf u+\mathbf u',\ \mathbf w] = \det[\mathbf u,\ \mathbf w] + \det[\mathbf u',\ \mathbf w]\)。几何上:拉长一条边,面积同比例变化。
- 交替:交换两列,行列式变号。于是两列相同时行列式为 0(与自己交换,结果既不变又变号,只能是 0)。结合第 2 条还能推出:把一列加上另一列的倍数(剪切)不改变行列式,因为 \(\det[\mathbf u + s\mathbf w,\ \mathbf w] = \det[\mathbf u,\ \mathbf w] + s\det[\mathbf w,\ \mathbf w] = \det[\mathbf u,\ \mathbf w]\)。
二阶与三阶公式
几何定义:\(S\) 取任意形状,面积比都是同一个数。二阶的具体公式是 \(ad-bc\)(第 4 节已经看到它从哪来):
三阶可以沿第一行做余子式展开(cofactor expansion),符号按 \(+,-,+\) 交替:
最右边是三列 \(\mathbf a, \mathbf b, \mathbf c\) 的混合积(triple product,1.8 节),它给出平行六面体的有符号体积。算一个例子:\(A = \begin{bmatrix}2&0&1\\1&3&2\\0&1&1\end{bmatrix}\),展开得 \(2(3\cdot1-2\cdot1) - 0 + 1(1\cdot1-3\cdot0) = 2 + 1 = 3\)。用混合积核对:三列是 \(\mathbf a=(2,1,0)\)、\(\mathbf b=(0,3,1)\)、\(\mathbf c=(1,2,1)\),\(\mathbf b\times\mathbf c = (1,1,-3)\),\(\mathbf a\cdot(1,1,-3) = 2+1+0 = 3\)。一致。
常用性质
| 性质 | 几何含义 |
|---|---|
| \(\det(AB) = \det A\,\det B\) | 先后两次变换,面积倍数相乘(FIG 6) |
| \(\det A^{\top} = \det A\) | 用行围成的平行四边形,面积与用列围成的相同 |
| \(\det(cA) = c^{n}\det A\) | 每个方向都放大 \(c\) 倍,\(n\) 维体积放大 \(c^n\)(二维面积放大 \(c^2\),不是 \(c\)) |
| \(\det A^{-1} = 1/\det A\) | 逆变换把面积倍数倒过来 |
| \(\det A = 0 \iff\) 列线性相关 \(\iff A\) 不可逆 | 平行四边形(六面体)塌了;压扁的空间无法复原(1.6 节) |
| 三角矩阵:对角元之积 | 这也是用 LU 分解算行列式的原理 |
| 旋转 \(\det R = +1\),镜像 \(\det = -1\) | 旋转不改变面积和朝向;镜像不改变面积,但翻面(1.10 节) |
教科书里的余子式展开要做约 \(n!\) 次乘法,\(n=20\) 就已经不可能。数值库(NumPy、Eigen、LAPACK)先做 LU 分解 \(PA = LU\),行列式就是 \(U\) 对角线之积乘以置换的符号,代价约 \(n^3\)。矩阵稍大时行列式很容易上溢或下溢(\(100\times100\) 的 \(0.1I\) 的行列式是 \(10^{-100}\)),所以常算它的对数 np.linalg.slogdet。
8机器人中的它:奇异位形与手性检查
两连杆机械臂:行列式何时为零
把雅可比 \(J\) 当成"把关节速度变成手端速度的矩阵":\(\dot{\mathbf x} = J\dot{\mathbf q}\)(它怎么来的是 3.3、3.4 节的内容)。\(J\) 的第 1 列是只转关节 1 时手端的速度,第 2 列是只转关节 2 时的速度。两个关节速度都在 \([0,1]\) 内时,手端的速度就落在 \(J\) 的两列围成的速度平行四边形里,它的面积是 \(|\det J|\)。对平面两连杆臂(杆长 \(\ell_1,\ell_2\)),
(\(s_1=\sin\theta_1\),\(c_{12}=\cos(\theta_1+\theta_2)\),依此类推。)注意 \(\det J\) 只和肘关节角 \(\theta_2\) 有关,与肩关节角 \(\theta_1\) 无关:手臂整体转一个角度,只是把速度平行四边形整个转一下,面积不变。\(\theta_2 = 0\)(手臂完全伸直)或 \(\theta_2 = \pm\pi\)(完全折叠)时 \(\det J = 0\),两列平行,平行四边形塌成线段:手端不能沿手臂方向运动。\(\theta_2\) 的符号决定 \(\det J\) 的符号:肘朝两侧弯,是两种"手性"不同的位形。
拖动肘部(圆圈)或手端,或者用滑块。右侧小图画出 \(\det J\) 随 \(\theta_2\) 的变化。
- 把机械臂带到奇异位形(\(|\det J| < 0.07\))。平行四边形变成了什么?手端被"锁"住了哪个方向?
- 让 \(\det J\) 分别取到一次明显为正、一次明显为负(绝对值大于 0.3)。你是怎么过去的?必须经过什么?
凡是"估计出来"或"从文件里读出来"的旋转矩阵,都应该检查 assert abs(np.linalg.det(R) - 1) < 1e-6(同时 \(R^\top R = I\),1.10 节)。常见的出错来源:(1) 基于 SVD 的位姿拟合(如 Kabsch / Umeyama 算法)在点几乎共面或噪声较大时,可能返回 \(\det R = -1\) 的"最佳正交矩阵",必须修正符号:\(R = V\,\mathrm{diag}(1,1,\operatorname{sign}\det(VU^\top))\,U^\top\)(SVD 见 1.12 节);(2) 左手系与右手系之间的转换:Unity 用左手系,ROS 用右手系,从一个引擎搬位姿到另一个,要做一次镜像,漏掉就是镜像世界;(3) 图像坐标 \(y\) 轴朝下,相机内参和坐标轴的约定一旦写错一个符号,也会让整个场景左右翻转。
9常见误区
不对。\(\det(0.1\,I_3) = 0.1^3 = 0.001\),可这个矩阵是均匀缩小,处处表现良好,求逆一点问题也没有。行列式把"整体尺度"和"有多扁"混在了一起。衡量"快要奇异"要用与尺度无关的量:奇异值之比,即条件数(1.12 节)。反过来也成立:\(\operatorname{diag}(10^6, 10^{-6})\) 的行列式是 1,却极其病态。
不成立。行列式对乘积友好(\(\det AB = \det A\det B\)),对和不友好。反例:\(A = I\),\(B = -I\)(二维)。\(\det A = \det B = 1\),可 \(A + B = 0\),\(\det(A+B) = 0 \ne 2\)。同理 \(\det(cA) = c^n\det A\),而不是 \(c\det A\)。
只有方阵才有。\(3\times2\) 的矩阵把平面送进三维空间,\(ad-bc\) 这类公式根本写不出来,"翻面"也没有意义(在三维里平面可以随意翻转)。它的面积缩放倍数依然存在,等于 \(\sqrt{\det(A^\top A)}\)(所有奇异值之积),但永远非负。机械臂的雅可比如果不是方阵(冗余臂),\(\det J\) 没有意义,该用奇异值或 Yoshikawa 可操作度 \(\sqrt{\det(JJ^\top)}\)(1.12 节)。
它只告诉你面积倍数,不告诉你形状怎么变。单位矩阵、旋转、剪切 \(\begin{bmatrix}1&1\\0&1\end{bmatrix}\) 的行列式全是 1,形状却天差地别(FIG 2 的第二个任务)。要知道"拉伸了多少、朝哪个方向",要看奇异值(1.12 节)和特征值(1.11 节)。
展开公式适合手算 \(2\times2\)、\(3\times3\)。它的运算量按 \(n!\) 增长:\(10\times10\) 要三百多万次乘法,\(20\times20\) 要 \(10^{18}\) 次以上。代码里用 LU 分解(\(n^3\)),并且尽量不要判断 "det == 0" 来决定能否求逆:浮点数里几乎永远不会恰好等于 0,该看条件数或最小奇异值。
10小练习
11延伸阅读
- 3Blue1Brown, Essence of Linear Algebra — 第 6 章 "The determinant"(行列式)
- G. Strang, Introduction to Linear Algebra, Ch. 5 — 行列式(性质、余子式、体积)
- K. Lynch & F. Park, Modern Robotics, §5.3 — 奇异位形分析
- J. Ström et al., Immersive Linear Algebra — 行列式一章,带可拖动的交互插图