谁给体积加上了方向?关于行列式、叉乘和积分
对语法的妥协?矩阵行列式和有向体积
面积是什么?
一般情况不会回答”面积是什么?“这个问题,而是用某种注意力转移话术切换到如何计算面积上。
我们会说边长为 1 的正方形的面积就是 1 。以它作为基准,可以用拼图方式得到长宽分别为 a,b 的矩形的面积是 axb,当 a, b 是自然数的时候,这是一个纯粹的计数问题。
如果 a 和 b 是比例数(有理数),那么可以用切分的方式得到其面积还是 axb 。
由于实数可以写成有理数加法的极限,比如 3.1415… = 3+0.1+0.04+0.001+0.0005+… 用无限切割的方式还是能把矩形面积的 axb 代数形式推广到 a 和 b 都是实数的情况。(某种意义上说,实数的设计需求中本身包含了“极限要保持代数运算规律”这一条)
对于平行四边形可以把斜角切掉补到另一边得到一个矩形然后计算,并总结出“底面积乘以高”的快捷公式。
两个三角形可以拼成一个平行四边形,因此其面积公式是底边乘以高除以 2 。
类似地,梯形等复杂的多面体也都可以用割补法从矩形面积推广得到,圆或其他弧形也能用充满技巧的微分割圆法规约到方形去无限近似。
在理清这个过程之后,如果非要回答 "面积是什么?",那么面积是一个人为约定的相对的概念,以 1x1 的正方形为基准。
不过还是很难用语言说清楚面积是什么,它根植于人类对空间尺寸的感知上。
然而,我们可以稍微谈论计算面积过程中用到的操作的性质。
比如 2x2 的正方形面积是 4 个 1x1 正方形面积之和,说明两个不重叠的面积对象是可以相加的,更典型的是如果某条边增大 n 倍,总面积也会增大 n 倍。而能把平行四边形切下来补到另一边,说明潜意识里接受了一个协议:“平移和旋转不改变面积”。
如果接受“面积是人为约定的协议,并通过执行协议的操作规则所刻画”,还会有一个问题是,我们为什么要约定边长为 1 的正方形面积是 1, 不能是半径为 1 的圆的面积为 1 吗?
这是有明确回答的:因为好用,比如用圆的话很难去平铺计算出其他任何形状的面积,用平行四边形,梯形会稍微好一点,但平铺分割起来也比正方形麻烦,因为缺少旋转对称性(而面积在这种操作下不变,所以很依赖这种性质),更详细说明可以参考面积为什么选择以正方形为基本单元_哔哩哔哩_bilibili 及其下的一些精彩评论。
从这个讨论中也可以看到,把单位正方形面积定为 1 是面积协议里的关键条款,它可以被讨论或质疑,但最终因为经验上的方便好用性而被选中,其他的平移旋转不变性以及可加性则很难去反驳,它和人类对空间属性的感知有关,如果去掉这种约束,我们用数学捕捉的可能就不是面积,而是其他某些无用或者可能有用的概念。
我们习惯的底面积乘以高的矩形公式,只是执行面积的计算协议时遇到一些常见图形的速记公式,它并不符合直觉,也不是理所当然,只是我们习惯了,尤其是在小学不太有意识的情况通过大量做题而形成“肌肉记忆”了,这有点像你下载一个 App 后压根没看用户协议,直接拉到最后点同意了。
体积也是如此,约定单位立方体体积为 1, 然后通过可加性去扩展到更大的对象,通过平移旋转不变性去切割规约到长方体上。
提问范式的转移
21 世纪了,别再像古希腊人那样问 “xxx 是什么了”?对于任何这样的问题,我都可以回答说 “xxx 是一种信息”,然后用另一个问题去反问你: "xxx 这种信息目前是如何被处理或计算的?" 因为“这个世界是被模拟的”是无法被证伪的。
一个黑客帝国爱好者
向量视角下平行四边形的面积
向量是 "直" 的,因此用向量作为基时,编码的图形一般都是矩形,平行四边形或三角形,它使得我们不需要用无限的切割法去计算某种曲线围成的面积,从而避开了微积分。因此先梳理向量编码下平行四边形面积的计算规则。(向量,尤其是基向量更多是用来搭建空间的,这是其他图形表演的的舞台,因此行列式可以看作是计算舞台的面积,而积分则更多用来计算舞台上光怪陆离的对象内容的面积,向量也可以编码空间里复杂的对象,这会在积分一节中介绍)
下图中二维平面向量 \( \vec{a} \) 和 \( \vec{b} \) 夹角是锐角 \(\theta\),利用平行四边形面积等于底乘以高的速记公式,以二者作为邻边的平行四边形面积公式是 \( |a||b|\sin(\theta) \) ,而向量点乘的公式是 \( \vec{a} \cdot \vec{b} = |a| |b| \cos \theta \)
这与面积公式形式上非常接近,一些人难以禁受住这种相似的诱惑,试图去建立联系,由于 \( \sin(\theta) = \cos(\frac{\pi}{2}-\theta) \) ,因此可以把面积写成 \( |a||b| \cos (\frac{\pi}{2} - \theta) \) 。
而图中 \(\vec{c}\) 向量是和 \(\vec{a}\) 垂直但长度相同的向量(或者说是 \( \vec{a} \) 绕原点逆时针旋转 90 度后的复制品),\(\vec{b}\) 和 \(\vec{c}\) 之间的夹角就是 \(\frac{\pi}{2}-\theta\),于是面积公式可以用 \(\vec{b}\) 和 \(\vec{c}\) 的点乘 \(\vec{b} \cdot \vec{c}\) 表示。如果 \(\vec{a}\) 的笛卡尔坐标是 \((x, y)\),\(\vec{b}\) 是 \((u, v)\),那么由图可知 \(\vec{c}\) 的坐标表示为 \((-y, x)\),二者内积就是 \(-yu + xv\)。
而它正是以下矩阵的行列式(或称决定值): \[ \det \begin{pmatrix} x & y \\ u & v \end{pmatrix} = xv - yu \]
我们直接可以将它定义为两个行向量张成平行四边形的面积。
但这个定义很可能有问题,因为如果把 (u,v) 放在第一行, (x,y) 放在第二行,那么结果就是 uy-xv, 这是图中四边形面积的相反数。
所以把每行看作向量的话,行列式的绝对值才是张成的平行四边形的面积。
无论是把行列式的绝对值定义为面积还是证明行列式的绝对值编码了面积,上图都是二维平面行列式和平行四边形面积的关系的有力解释,因为 \(\vec{a}, \vec{b}\) 向量可以是任意的(即便是钝角也可以算)。
所以,至少对于二维平面,矩阵对角相乘再相减的一个具有空间感的纯代数规则是能和面积概念建立密切联系的。
剩下的问题是:
问:如何把这种面积的语义连同计算方式推广到三维?在三维空间,我们是计算 \(\vec{a}, \vec{b}\) 两个向量张成的平行四边形面积,还是三个向量 \(\vec{a}, \vec{b}, \vec{c}\) 张成的平行六面体体积?更高维呢?
答:任意维度的两个向量都可以张成平行四边形,我们有计算这个面积的方法,即约定一个向量为底边,然后计算其模长,再计算另一个向量到它的投影点的高,得到面积。但和行列式对应的语义是高维平行多面体的体积,而不是两个向量的面积,行列式是 n 个 n 维向量组成的矩阵才拥有的性质。
问:为什么面积会带符号,即出现“有向面积”这种概念?到了高维,符号还是只有一个正负号吗?还是会出现多个不同的“方向标示”?如果只是正负号,那取绝对值就能得到普通面积;但如果高维有更多方向,那就不是取绝对值这么简单了。
答:并不是面积会带符号,而是在向量这种数学框架下,行列式编码了面积/体积,除了面积之外它还携带了额外的信息。尽管正负号和体积绑定在一个对象中并没有把方向和长度编码在向量对象中那么自然(日常生活中长度和方向确实会在一起使用),这里正负和体积的配对是代数中独特出现的,负号不代表缺少了什么,只是标定了运算的基准。在三维空间,我们可以定义出叉乘去编码两个向量张成平行四边形的面积以及方向,而在更一般的 n 维空间,n 个向量对应的体积只有正负而没有向量所标明的方向。
接下来会对以上问题和回答进行详细展开。
从体积性质到算法
我们先考虑把平面面积扩展到三维以及 n 维立方体体积。
前文说过,即便停下来反思,还是很难说清楚面积或体积是什么,但反思中却能看出计算面积或体积中所使用到的协议条款,这些条款可以被精确描述:
- 标准单位立方体的体积为 1: 二维空间中,标准基 i,j 构成的是正方形,其面积为 1, 三维空间中,标准 i,j,k 构成的是正立方体,体积为 1 。 那维空间为: \[ \text{det}(e_1, e_2, \dots, e_n) = 1 \] 其中 \(e_1, e_2, \dots, e_n\) 是标准正交基,我们将其看作是矩阵 I 中的行向量,可简写成 \( det(I)=1 \) 。
固定其他向量,只缩放一个向量或在一个向量维度上叠加,那么体积也对应缩放或叠加。即: \[ \text{det}(\dots, \lambda u + \mu v, \dots) = \lambda \text{det}(\dots, u, \dots) + \mu \text{det}(\dots, v, \dots) \]
几何上,把一条边伸长 \(\lambda\) 倍,体积也伸长 \(\lambda\) 倍;把一条边换成两向量之和,相当于叠加了一个底边(面积)相同,高不同的多边形,那么总体积等于二者这和,见下图右侧,使用割补法可以证明 (a,b) 平行四边形面积加上 (a,c) 平行四边形面积等于 (a,b+c) 构成的平行四边形的面积。
交换任意两个向量(交换矩阵中两行),体积变号: \[ \text{det}(\dots, u, \dots, v, \dots) = -\text{det}(\dots, v, \dots, u, \dots) \]
注意这并不是面积协议的一部分,但我们在上一节二维平面上用向量形式去计算面积时会遇到符号的问题。所以加上了这一条,它是决定体积有方向的关键,可以称它为有向体积扩充协议条款。
从二维扩展到 n 维不一定是交换任意两个向量就会变号,所以这一条是可以质疑和讨论的。我们先接受它,看看会有什么结果, 并在后文分析如果删除这个性质会导向什么。
令人惊讶的是,仅从以上三条性质出发,结合矩阵的其他性质(比如乘法规则)就可以导出关于行列式的所有其他性质。
因此后文将以上三条性质称为有向体积(det)三公理。
高斯消元法
可以从导出的以下几个性质:
包含 0 行的矩阵的有向体积为 0 。
根据公理 2, 矩阵每行乘以 c, 则有向体积也乘以 c,而 0 行就相当于该行乘以 0, 提取 0 系数后乘以原矩阵 det 得到 0 。几何上也很好解释,即有一条边长度为 0 ,那么立体对象就塌缩到更低维了,体积就是 0 。
如果有两个向量相同,则它们组成的矩阵的 det 为 0 。
因为交换这两个向量后矩阵是不变的,那么 det(A)=-det(A),从而 det(A)=0 。 三维空间里的解释是,立方体有两条边重叠,因此它不是立方体,而是塌缩在一个平面上的平行四边形,三维体积为 0 。
注意如果我们删除掉公理 3:“交换任意行后行列式要取反”,则无法推导出本条结论,只能通过几何解释把本结论变成新的公理。
从这可以看出,公理 3 虽然看上去和体积的“本质”无关,但却蕴含了体积性质。
它和自然数扩展成整数后 0 的语义被扩充有密切的联系。如果只有自然数,要表达 0 ,你只能纯粹地罗列出导致 "虚无" 或者体积“塌缩”的场景,比如 “两条边重叠或共向则体积为 0”。
但有了整数和负运算之后,0 额外地充当了正数和负数的基准点,你可以更加灵活地表达 0 ,比如如果某个数和它的负数相等,那么它就是 0。
公理 3(交换两行变号)正是利用这种性质,将“对称性要求量相等而符号相反”引入了行列式。这样一来,0不再仅仅被描述为某些特殊退化情形(如两行相同)的几何结果,而可以在代数上表达为一个量与它的负量相等。
换句话说,交换公理让我们可以用正负对称的代数语言推导出 0,而不再只是列举出 0。这是对 0 态度的灵活变化,也是导致体积出现正负号的关键。
如果将矩阵 A 某行乘以 k 后加到另一行,结果矩阵的有向体积不变。
比如 \( A' = \begin{pmatrix} a & b \\ c + ka & d + kb \end{pmatrix} \) 可以拆分成矩阵的和 \(\begin{pmatrix} a & b \\ c & d \end{pmatrix} + \begin{pmatrix} a & b \\ ka & kb \end{pmatrix} \), 这相当于复用平行四边形的一条边,再额外增加一个新的边,但新的边和原始边的方向 (a,b) 相同,那么第二个新增的平行四边形面积为 0, 所以 det 不变。
以上三条推导性质表明,对矩阵做高斯消元,只要中间不涉及行交换,那么消元过程中有向体积保持不变,即便涉及到行交换,利用公理 3 ,有向体积只是变号。
高斯消元最终要么得到最后几行是 0, 这对应有向体积为 0, 要么变成一个对角矩阵,而对角矩阵相当于对角线上各个值提取成系数后乘以一个单位矩阵,根据单位矩阵的有向体积为 1 的性质,最终体积就是对角矩阵上元素的乘积。
以下用一个完整的 3x3 矩阵例子来说明(AI 生成后修改):
\[ A = \begin{pmatrix} 0 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 1 & 3 \end{pmatrix} \]
第一步,行交换: 第 1 行第 1 列是 0,无法直接消去下面两行的第 1 列,所以交换 \(R_1\) 与 \(R_2\):
\[ A \xrightarrow{R_1 \leftrightarrow R_2} B = \begin{pmatrix} 2 & 4 & 2 \\ 0 & 2 & 1 \\ 1 & 1 & 3 \end{pmatrix} \] \[ \det(B) = -\det(A) \]
第二步,用 \(R_1\) 消 \(R_3\): \(R_3 \leftarrow R_3 - \frac{1}{2} R_1\)(因为 \(B_{31}=1, B_{11}=2\))
\[ C = \begin{pmatrix} 2 & 4 & 2 \\ 0 & 2 & 1 \\ 0 & -1 & 2 \end{pmatrix} \] 行列式不变:\(\det(C) = \det(B)\)
第 3 步,消去第 3 行的第 2 列:
\(R_3 \leftarrow R_3 = R_3 + \frac{1}{2} R_2\):
\[ D = \begin{pmatrix} 2 & 4 & 2 \\ 0 & 2 & 1 \\ 0 & 0 & 2.5 \end{pmatrix} \] \(\det(D) = \det(C)\)
第 4 步,对角化(把上三角变成对角矩阵): \[ E = \begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 2.5 \end{pmatrix} \] 整个过程都是某行乘以 k 后加到另一行,不会导致有向体积变化 \(\det(E) = \det(D) \)
第 5 步,还原到单位矩阵,将对角系数提取出来:
\[ E = 2 \times 2 \times 2.5 \times I_3 \]
\(\det(E) = (2 \times 2 \times 2.5) \cdot \det(I_3)\)
且 \(\det(I_3) = 1\)(单位立方体的有向体积)
所以 \(\det(E) = 10\)
第 6 步,回推行列式:
\[ \det(A) = -\det(B) = -\det(C) = -\det(D) = -\det(E) = -10 \]
有向体积的计算共享了解方程里的高斯消元算法。
在以上例子的推理过程中,还可以得出两个新的性质:
上三角矩阵的 det 等于对角线上元素乘积。
因为从以上第三步最后是通过向上消元得到对角矩阵,这个过程中 det 不变,而对角矩阵每一行可以提取出因子最终变成对角元素乘积乘以单位矩阵 I 的 det 。
即之后我们不需要消元到对角矩阵,只要到上三角形式即可。
det(A)=0 等价于 A 是奇异的。这里奇异的定义是矩阵里行向量并不是线性独立的。
因为 det(A) 为 0 意味着消元法过程中出现了 0 行,而消元中出现 0 说明有些行可以被其他行通过线性组合的形式精确表达出来,这就是线性相关的定义。
体现在几何上,矩阵 A 是奇异的意味着某条边可以被其他边通过缩放相加所表达,说明这条边不能独立于其他边所构成的空间,某个维度塌缩了,体积为 0 。
对于 \( A = \begin{pmatrix} a & b \\ c & d \end{pmatrix} \) 消元成 \( \begin{pmatrix} a & b \\ 0 & d - \frac{bc}{a} \end{pmatrix} \), 其有向体积就是对角相乘的结果,即 \( ad-bc \), 因此通过三条公理推导的算法,至少在二维上和我们从图形中计算得到的结果是一样的。
从性质到代数
基于公理 2 ,还可以将矩阵对每一行进行拆解,以 2x2 矩阵为例
针对第一行,每次只保留第 i 个元素,其他元素都置为 0,可以拆分成两个矩阵:
\[ \det \begin{pmatrix} a & b \\ c & d \end{pmatrix} = \det \begin{pmatrix} a & 0 \\ c & d \end{pmatrix} + \det \begin{pmatrix} 0 & b \\ c & d \end{pmatrix} \]
每个拆分后的矩阵针对第二行又可以继续拆分:
\[ \det \begin{pmatrix} a & b \\ c & d \end{pmatrix} = \det \begin{pmatrix} a & 0 \\ c & 0 \end{pmatrix} + \det \begin{pmatrix} a & 0 \\ 0 & d \end{pmatrix} + \det \begin{pmatrix} 0 & b \\ c & 0 \end{pmatrix} + \det \begin{pmatrix} 0 & b \\ 0 & d \end{pmatrix} \]
对于 \(\det \begin{pmatrix} a & 0 \\ c & 0 \end{pmatrix}\) 和 \(\det \begin{pmatrix} 0 & b \\ 0 & d \end{pmatrix}\),由于行向量之间是互为倍数关系,也就是平行四边形的两个维度在同一条线上,围成的面积因此为 \(0\)。
剩下的两项: \(\det \begin{pmatrix} a & 0 \\ 0 & d \end{pmatrix} = ad \cdot \det \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix}\)。根据公理 1 单位矩阵的面积为 1,结果为 ad。
\(\det \begin{pmatrix} 0 & b \\ c & 0 \end{pmatrix} = bc \cdot \det \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}\)。根据公理 3 交换两行符号取反,结果为 -bc。
最终得到了和之前一样的结果 \[ \det \begin{pmatrix} a & b \\ c & d \end{pmatrix} = 0 + ad - bc + 0 = ad - bc \]
和上一节把矩阵变换到更简单的形式不同,以上是把矩阵拆分成更基础的形式。
总结这种拆分模式,它是递归性质的,以下用 3x3 矩阵继续按深度有限来展示:
根据公理 2, 矩阵的有向体积等于:: \[ \det \begin{pmatrix} a_{11} & 0 & 0 \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{pmatrix} + \det \begin{pmatrix} 0 & a_{12} & 0 \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{pmatrix} + \det \begin{pmatrix} 0 & 0 & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{pmatrix} \]
只关注第一项,继续等于: \[ \det \begin{pmatrix} a_{11} & 0 & 0 \\ a_{21} & 0 & 0 \\ a_{31} & a_{32} & a_{33} \end{pmatrix} + \det \begin{pmatrix} a_{11} & 0 & 0 \\ 0 & a_{22} & 0 \\ a_{31} & a_{32} & a_{33} \end{pmatrix} + \det \begin{pmatrix} a_{11} & 0 & 0 \\ 0 & 0 & a_{23} \\ a_{31} & a_{32} & a_{33} \end{pmatrix} \]
此时第一项已经出现两个维度共线,结果为 0 ,只剩下后两项:
\[ \det \begin{pmatrix} a_{11} & 0 & 0 \\ 0 & a_{22} & 0 \\ a_{31} & a_{32} & a_{33} \end{pmatrix} + \det \begin{pmatrix} a_{11} & 0 & 0 \\ 0 & 0 & a_{23} \\ a_{31} & a_{32} & a_{33} \end{pmatrix} \]
展开这里的第一项: \[ \det \begin{pmatrix} a_{11} & 0 & 0 \\ 0 & a_{22} & 0 \\ a_{31} & 0 & 0 \end{pmatrix} + \det \begin{pmatrix} a_{11} & 0 & 0 \\ 0 & a_{22} & 0 \\ 0 & a_{32} & 0 \end{pmatrix} + \det \begin{pmatrix} a_{11} & 0 & 0 \\ 0 & a_{22} & 0 \\ 0 & 0 & a_{33} \end{pmatrix} \]
此时只有最后一项不存在共线的维度,因此只有它不是 0 。
从这个过程可以发现,整个拆分是在做空间上的排列组合,3x3 的矩阵最终拆分成每行只有 1 个非 0 项,这有 3 个选择,而总的有 3 行,因此最终拆分成 \( 3^3 = 27 \) 个基础矩阵,但其中只有 \( 3! = 6 \) 个矩阵的有向体积不为 0 (公理 2 过滤了大部分的项), 它们是:
\[\begin{aligned} \det(A) = &\det \begin{pmatrix} a_{11} & 0 & 0 \\ 0 & a_{22} & 0 \\ 0 & 0 & a_{33} \end{pmatrix} + \det \begin{pmatrix} 0 & a_{12} & 0 \\ 0 & 0 & a_{23} \\ a_{31} & 0 & 0 \end{pmatrix} + \det \begin{pmatrix} 0 & 0 & a_{13} \\ a_{21} & 0 & 0 \\ 0 & a_{22} & 0 \end{pmatrix} \\ &+ \det \begin{pmatrix} a_{11} & 0 & 0 \\ 0 & 0 & a_{23} \\ 0 & a_{32} & 0 \end{pmatrix} + \det \begin{pmatrix} 0 & a_{12} & 0 \\ a_{21} & 0 & 0 \\ 0 & 0 & a_{33} \end{pmatrix} + \det \begin{pmatrix} 0 & 0 & a_{13} \\ 0 & a_{22} & 0 \\ a_{31} & 0 & 0 \end{pmatrix} \end{aligned} \]
注意后三项要回到对角矩阵,只需进行一次行交换,因此会出现负号,而第二第三项虽然也要交换才能变成对角矩阵,但交换次数是 2 ,因此没有负号出现。
最终得到行列式的莱布尼茨公式形式: \( \begin{aligned} \det(A) = \;&a_{11}(a_{22}a_{33} - a_{23}a_{32}) \\ -\; &a_{12}(a_{21}a_{33} - a_{23}a_{31}) \\ +\; &a_{13}(a_{21}a_{32} - a_{22}a_{31}) \end{aligned} \)
以上写法提取出了第一行的三个元素作为因子,而括号里每一个项都是一个子矩阵的行列式(有向体积)
\[ \det \begin{pmatrix} a_{11} & 0 & 0 \\ 0 & a_{22} & a_{23} \\ 0 & a_{32} & a_{33} \end{pmatrix} - \det \begin{pmatrix} 0 & a_{12} & 0 \\ a_{21} & 0 & a_{23} \\ a_{31} & 0 & a_{33} \end{pmatrix} + \det \begin{pmatrix} 0 & 0 & a_{13} \\ a_{21} & a_{22} & 0 \\ a_{31} & a_{32} & 0 \end{pmatrix} \]
这使得我们可以写出递归形式的代数式子,对矩阵 A 中任意元素 A[i][j], 其代数余子式 (cofactor) \( C_{ij} \) 定义为除 i 行和 j 列外剩下元素组成的矩阵的行列式乘以 \( (-1)^{i+j} \), 最终 A 的行列式可以写成:
det(A)= \( a_{11}C_{11}+a_{12}C_{12}+\dots+ a_{1n}C_{1n} \)
继续封装,可以把它写成向量点乘的形式 \( det(A)=A_{1} \cdot C_1 \) ,A1 是矩阵 A 的第一行, C1 是第一行各个元素的代数余子式组成的向量。
总结来说,根据协议里的三条性质,就可以得到两种计算行列式的经典方式,一是消元,二是莱布尼茨公式。
对于 nxn 矩阵,根据公理 2 可以把矩阵拆分出 \( n^n \) 个基础矩阵的和,继续用公理 2 可以知道其中大部分矩阵 det 为 0 ,过滤剩下 n! 个,然后利用 det(I)=1 以及线性缩放性质得到结果。
而代数余子式的写法是对以上底层拆分中剩下的非 0 分量提取出递推表达式,是一种更高层的符号封装。
三维叉乘与有向面积
回到具体的 3 维空间,如上图所示,我们已经知道它的体积是 \( det(\vec{a},\vec{b},\vec{c}) \) (提前约定 a,b,c 这个排列下的体积为正), 如果交换 a 和 c ,那么体积为 \( -det(\vec{c},\vec{b},\vec{a}) \), 在交换 a 和 b 得到体积为 \( det(\vec{c},\vec{a},\vec{b}) \), 写成矩阵形式是:
\[ \det \begin{pmatrix} c_1 & c_2 & c_3 \\ a_1 & a_2 & a_3 \\ b_1 & b_2 & b_3 \end{pmatrix} \]
根据行列式的代数余子式点乘写法: \( det(A)=\vec{c} \cdot \vec{C} \) , \( \vec{C} \) 是第一行各个元素的代数余子式组成的向量,它就是:
\[ (det\begin{pmatrix} a_2 & a_3 \\ b_2 & b_3 \end{pmatrix}, -det\begin{pmatrix} a_1 & a_3 \\ b_1 & b_3 \end{pmatrix}, det\begin{pmatrix} a_1 & a_2 \\ b_1 & b_2 \end{pmatrix}) \]
而如果用 \( \vec{i},\vec{j},\vec{k} \) 表示三个标准基,它就是:
\[ \vec{C} = \det\begin{pmatrix} a_2 & a_3 \\ b_2 & b_3 \end{pmatrix} \vec{i} - \det\begin{pmatrix} a_1 & a_3 \\ b_1 & b_3 \end{pmatrix} \vec{j} + \det\begin{pmatrix} a_1 & a_2 \\ b_1 & b_2 \end{pmatrix} \vec{k} \]
为了方便记忆和统一语法,数学家们发明了一个“形式化行列式”写法:
\[ \vec{C} = \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} \]
用计算机编程的术语,此时的行列式 det 函数被重载了,它能够额外支持第一个参数是向量所构成的向量。
而它返回的结果则还是一个向量。
尽管类型不同,但输出的向量的语义仍然是有向面积,只是它的方向不单有正和负,还可以是三维空间的任意方向。
回到上图,根据底面积乘以高的体积公式, \( \vec{a},\vec{b},\vec{c} \) 三个向量作为邻边张成的平行六面体体积为 a 和 b 张成的平行四边形的面积乘以高 h 。
而如果我们有一个和高 h 方向相同(向上)的向量 \( \vec{h} \),它的模长等于底面积,那么 \( \vec{c} \cdot \vec{h} \) 语义上就是底面积乘以 \( \vec{c} \) 在 \( \vec{h} \) 投影后的长度,也就是高度,即 \( \vec{c} \cdot \vec{h} \) 为平行四面体体积。
而我们已经知道其体积为 \( det(A)=\vec{c} \cdot \vec{C} \) ,所以 \( \vec{C} \) 就等于 \( \vec{h} \), 它指向高的方向,且模长等于底面积。
从 \( \vec{C} \) 的 det 定义也可以看出,它同时和 \( \vec{a},\vec{b} \) 垂直,以 \( \vec{a} \) 为例,它和 \( \vec{C} \) 的点积就是:
\[ \det \begin{pmatrix} a_1 & a_2 & a_3 \\ a_1 & a_2 & a_3 \\ b_1 & b_2 & b_3 \end{pmatrix} \]
前两个维度共线,因此结果为 0 。
外积
用编程的视角来看,叉乘可以看作是对 det 的 partial apply, 即部分求值,类似以下 python 代码:
def det(*vectors):
pass # 返回 n 个向量张成的超体积
# 3维空间下的部分求值
def cross_product(a, b):
return lambda c: det(a, b, c)
# 4维空间下的部分求值
def triple_cross_product(a, b, c):
# det(a, b, c, _) -> 需要 3 个输入才能产生一个法线方向
return lambda d: det(a, b, c, d)
按照这个思路,n 维的空间中 n-1 个向量也可以进行广义的“叉乘”得到一个和这 n-1 个向量都垂直的向量,而模长等于 n-1 个向量张成的 n-1 维平行多面体的“体积”。但三维空间中的叉乘有很具体的物理意义,比如平面法线,旋转轴等,因此应用非常广。
nxn 矩阵的 det 有 n 个向量作为输入参数,因此它实际有 n-1 种不同的部分求值形态,比如 4 维空间下只对两个向量求部分 det, 7 维空间下对 3 个向量求部分 det 。
任何部分求值都有物理意义,n 维空间中 m 个向量的 det 应该表示这 m 个向量能张成的超平行多面体在 m 维空间中的体积(不是 n 维空间,因为 m<n 的话,永远是塌缩的),但它同时也编码了方向信息,使得这个低维空间的“面积”和新的维度继续交互时能产生出新的带方向的“体积”
这就引出了外积(Exterior Product)的概念,直接定义 \( a \wedge b \) 是两个向量的交互结果,它编码了它们张成的平行四边形面积,同时它还有一个方向,为了能够适用于所有维度,这个方向不是正负号或者具体的 n 维空间的向量,而应该是一个随着空间维度动态变化的对象。
考虑 4 维空间中 a,b,c,d 四个向量张成的一个超平行六面体,我们确实可以递归地先计算 a,b 向量张成平行四边形的面积,然后计算 c 向量到 a,b 平面的投影高度,计算出 a,b,c 张成的平行多面体体积,再找到 d 到 a,b,c 空间的垂直高度相乘得到最终超多面体体积。
但在四维空间中,和向量 c 正交的空间不单单是一个平面,而是三维的子空间,所以要找到 c 向量到 a,b 平面的投影距离,不能把 a,b 规约成一个“叉乘”结果向量再和 c 进行计算,这会丢失了信息,而是要保留 a,b 交互出的面的完整信息,所以在四维空间中 \( a \wedge b \) 实际是一个编码了平面的特殊对象,而 \( a \wedge b \wedge c \) 则可以理解为四维空间中的向量,该向量可以和 d 点乘, \( a \wedge b \wedge c \wedge d \) 则是最终的带有正负号的数值,也就等于 det(a,b,c,d)。
从这个角度看,越多 \( \wedge \) 组合,携带的关于方向的信息量越低。
而由于 \( \wedge \) 可以看作是 det 的部分求值,因此有向面积协议里的三条基本公理仍然是成立的,否则在完全求值下得到的 det 会失效,不过公理 1 det(I)=1 并不是很有用,它只是 n 维空间中进行 n 次 \( \wedge \) 操作下的特殊约束,反而公理 2 和公理 3 最能刻画这种局部过程,可以写成:
\( \vec{a} \wedge (c\vec{b} + d\vec{e}) = c(\vec{a} \wedge \vec{b}) + d(\vec{a} \wedge \vec{e}) \) 以及 \( \vec{a} \wedge \vec{b} = -\vec{b} \wedge \vec{a} \)
它们就是外代数的核心运算规律。
比如从它们出发能推导出 \( \vec{a} \wedge c \vec{a} = 0 \) 等其他运算规则,这里不进行过多延伸,只是说明 det 的概念可以因为部分求值而被泛化,我们可以用 \( a \wedge b \dots \) 对象来编码面积信息以及高维空间的方向性,当参数和空间维度一样时,则变成了带正负的体积。
有向体积和代数的胜利
为什么关心行星扫过的面积? 一文中提到,人类会把地面上的“面积”概念套到天空中移动的星球的运动轨迹上,这让我感到惊叹。
和面积有关的另一个问题也会令人不解,即有向面积或有向体积。
在微积分中,一个函数如果是负的,比如在 \( (0,\pi) \) 中的 -sin(x) 函数,那么对它的积分是一个负数。
在线性代数中,平面上两个向量组成矩阵的行列式编码了两个向量作为邻边构成的平行四边形的面积,但这和向量选择的前后顺序有关,如果从向量 a 到向量 b 用右手定则是指向屏幕(或纸张)内,那么面积是负的(或正,看如何定义正负),否则是正的。
三维空间中两个向量的叉乘得到的则是一个新向量,该向量的模长等于两个向量作为邻边构成的平行四边形的面积,但它的方向则和两个向量本身方向以及计算叉乘时选择向量的顺序有关,如果交换两个向量,得到的新向量方向会相反(即乘以 -1)。
另外三维空间中两个向量无法谈论行列式,只能把三个向量组成矩阵,再求其行列式,而这个值则是三维空间平行六面体的有向体积。
现在问题是,是什么导致面积出现了方向,体积出现了正负(也可以认为是方向)?
过去我很难回答这个问题,只能说数学上是这样的。
但读完 语法和语义的博弈:数系是如何扩张和分化的? 整数一节,我会认为这是自然数扩展到整数之后 0 的意义被重新解释而出现的,它是人对代数运算方便性的一种妥协,或者说更像是一种额外收获。
在自然数中,0 可能代表某种虚空,而负数压根不存在。
但出于对减法的执着,人们用负数扩充了整数,此时 0 脱离了最初的 "虚空" 解释,起到了相对基准的作用。
负号给自然数增加了一个比特用来编码它和 0 基准的关系,小小的符号代价使得整数上的加减乘运算变得非常顺滑。
在此基础上扩展出的有理数和实数都继承了这种顺滑,以至于在谈论基于实数的函数性质或向量时,如果负号的意义和某种直觉不符,我们不会舍得丢弃负号,而带符号的积分和体积就出现了。
把实数用数组升维扩展出向量(也可以看作一种数)之后,它可以很好地对物理世界中的方向进行编码,而向量的加法和对向量乘以一个实数在物理上的意义非常清晰,比如往北走 3km 再往东走 4km 就是往东北方向走 5 km, 再比如向北走 1km 后再向北走 1km, 就是向北走 1km 两次,扩展出了标量乘法。
向量加法和标量乘法(主要是实数乘法)上发展出的线性代数在符号计算上同样非常顺滑。
单个向量可以编码长度和方向,两个向量则可以编码平行四边形(由于“平行”的特点,两条对边在信息上是冗余的),同理,三维或更高维的空间里的多个向量可以编码更复杂的多面体,它们足以描述整个几何对象。
当计算这些向量对应的几何体的体积时,我们当然可以用底面积乘以高的“伪直觉”习惯性公式(后文将解释为何是伪直觉)得到真正的非负的面积或体积,但它们在计算上往往非常复杂,如果不去拒绝负数所修饰的体积,就像自然数运算中不拒绝 2-3 = -1 从而扩展出整数一样,我们可以得到负体积,更贴切的是不需要用“得到”一词,因为它被称为行列式,本身有其他的意义,比如判定向量之间是否线性相关,体积只是它编码的信息之一,需要用额外的取绝对操作抽取出来。
这是代数的胜利,在代数语法优先的情况下,负数有意义,虚数有意义,负体积有意义,复阻抗和复概率有意义,负质量、负概率、正电子等也可能会有意义,只要它没有和现有其他逻辑体系产生矛盾,那么符号的活动本身就能给外部世界反哺意义,人们会反过来去给新的符号搜集故事,自然界有时候也会递补上迟到的证据。
积分
另一个和有方向面积相关的是积分。
\( \int_a^b f(x) dx \) 积分公式中,哪些部分会有出现方向?
符号是抽象的,应该回到积分的最初语义下,它近似于把 [a,b] 切分成多个区间,每个区间选一个 f(xi) 值作为矩形的高度,计算出区间面积然后求和,而如果把细分的区间缩小到极限,最终结果就等于积分(这还是一种)。
可以写成 \( \lim_{n\to\infty} \sum_1^{n} \frac{b-a}{n}f(\frac{i}{n}) \), 这里 (b-a)/n 是划分成 n 个区间后各个区间的宽度,这个公式称为积分的黎曼和形式
以上公式中 \( f(\frac{i}{n}) \) 本身就有正负,所以可以回答是 f(x) 带有方向。
但问题不止于此,因为在从如果计算 \( \int_b^a f(x) dx \) ,那么结果是 \( - \int_a^b f(x) dx \), 所以从这里看到,积分上下限也决定了符号
而积分上下限的方向来自于黎曼和 \( \sum f(x_i)\Delta x_i \) 中的 \( \Delta x_i \) ,它其实是一个向量,而 dx 是其极限情况下无穷小但还是有方向的量,或者说它是纯粹的方向。
而真正要回到和直觉上相符合的纯粹非负面积的定义,则需要引入测度,而这在数学史上也是比有向面积更晚的事情了。