首页 / 模块 1 · 线性代数与微积分 / 第 2 课(共 10 课)

矩阵即线性变换

从零到前沿 ML 自学课程 · 阶段0:数学与工具基础 · 能力点:矩阵 = 线性变换——看懂神经网络每一层 Wx+b 在做什么

读完这一课,你将能够

  • 读出任意 \(2\times2\) 矩阵把 \(\hat{\imath},\hat{\jmath}\) 搬到的两个落点(即两列),并用列视角手算 \(Av\),说出它把向量搬到了哪
  • 判断一个变换是否线性(保加法、保数乘、原点不动),并说清 \(Wx+b\) 为什么是仿射而非线性
  • 对给定矩阵算 \(\det\),并用大小、符号、为零三种情形解释面积缩放、定向翻转、压扁降维的几何后果
  • 用 \((AB)x=A(Bx)\) 把矩阵乘法理解为变换复合,举例说明 \(AB\neq BA\),并默念形状契约 \((m\times n)(n\times p)=(m\times p)\)
  • 对一个被压扁的矩阵亲手数出秩与零空间,验证"秩 + 零空间维 = 列数"

上一课我们确立了"万物皆向量",并用点积衡量两个向量的关系。这一课,我们让整个空间动起来:矩阵不再是一张死板的数表,而是一台变换空间的机器——它把每个向量搬到新位置,让网格被缩放、旋转、剪切、压扁。理解了这一点,你就拿到了打开线性代数(以及神经网络)的钥匙。

记号衔接:沿用上一课的约定,向量记作斜体 \(v\)(默认是列向量),矩阵记作大写 \(A\)。零向量特别记作粗体 \(\mathbf{0}\),以便和标量 \(0\) 区分开——本课里只有零向量加粗,普通向量都用斜体。

一、矩阵的双重身份

一个矩阵 \(A\) 同时是两样东西:

这门课最重要的心态转变:不要把 \(Av\) 看成"一堆乘加运算的结果",而要看成"把向量 \(v\) 搬到了哪里"。整张数表,编码的是"空间该怎么动"。

二、矩阵的列 = 基向量变换后的落点

这是全课最重要的一句话,值得你停下来反复咀嚼。

回忆平面里的两个基向量 basis vector

\[ \hat{\imath}=\begin{bmatrix}1\\0\end{bmatrix},\qquad \hat{\jmath}=\begin{bmatrix}0\\1\end{bmatrix}. \]

任何向量都是它们的线性组合,例如 \(v=\begin{bmatrix}x\\y\end{bmatrix}=x\,\hat{\imath}+y\,\hat{\jmath}\)。

线性变换有个关键性质:只要知道 \(\hat{\imath}\) 和 \(\hat{\jmath}\) 被搬到哪里,就知道所有向量被搬到哪里。这一步用到下一节会正式讲的两条性质——把和拆开(可加性)、把标量提到前面(齐次性)。我们一步步展开,看清楚它不是黑魔法而是机械的两步:

\[ A\,v = A(x\,\hat{\imath}+y\,\hat{\jmath}) \underset{\text{可加性}}{=} A(x\,\hat{\imath})+A(y\,\hat{\jmath}) \underset{\text{齐次性}}{=} x\,(A\hat{\imath}) + y\,(A\hat{\jmath}). \]

现在看 \(A=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\) 怎么作用在基向量上:

\[ A\hat{\imath}=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\begin{bmatrix}1\\0\end{bmatrix}=\begin{bmatrix}2\\0\end{bmatrix},\qquad A\hat{\jmath}=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\begin{bmatrix}0\\1\end{bmatrix}=\begin{bmatrix}1\\3\end{bmatrix}. \]

看出来了吗?\(A\hat{\imath}\) 恰好是 \(A\) 的第一列,\(A\hat{\jmath}\) 恰好是 \(A\) 的第二列。这不是巧合——这就是矩阵的定义方式。

要点

矩阵的每一列,就是对应基向量变换后的落点。于是矩阵-向量乘法 \(Av\) 等于"用 \(v\) 的分量去加权矩阵的各列":

\[ \begin{bmatrix} a & b \\ c & d \end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix} = x\begin{bmatrix}a\\c\end{bmatrix}+y\begin{bmatrix}b\\d\end{bmatrix}. \]

这叫"列视角",是理解一切矩阵运算的根基。

矩阵的列是基向量变换后的落点 1 2 3 1 3 î ĵ 变换前(标准基) A 作用 [[2,1],[0,3]] 2 3 î→(2,0) A 的第1列 ĵ→(1,3) A 的第2列 变换后(网格仍平行等距) ● 原点不动;矩阵的列 = 基向量的像
矩阵的列 = 基向量变换后的落点。左图为原始坐标网格,标出单位基向量 i 帽=(1,0)(红)与 j 帽=(0,1)(蓝)。右图为经 A=[[2,1],[0,3]] 变换后:i 帽落到 (2,0)(红,恰是 A 的第一列),j 帽落到 (1,3)(蓝,恰是 A 的第二列)。两图都画淡灰网格线,变换后网格线仍保持平行且等距、原点不动,直观展示'矩阵的列就是基向量的像'。

例题

用 \(A=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\) 作用在 \(v=\begin{bmatrix}1\\1\end{bmatrix}\)。

用列视角:\(Av = 1\cdot\begin{bmatrix}2\\0\end{bmatrix}+1\cdot\begin{bmatrix}1\\3\end{bmatrix}=\begin{bmatrix}2+1\\0+3\end{bmatrix}=\begin{bmatrix}3\\3\end{bmatrix}.\)

验算(逐行点积):第一行 \(2\cdot1+1\cdot1=3\);第二行 \(0\cdot1+3\cdot1=3\)。两种算法一致,得 \(\begin{bmatrix}3\\3\end{bmatrix}\)。

三、什么样的变换才算"线性"

上一节我们已经反复用到"线性变换"这个词,现在给它一个精确的定义。不是任何把向量搬来搬去的规则都叫线性变换——线性变换必须满足三条性质:

  1. 保持加法(可加性):\(A(u+v)=Au+Av\)。
  2. 保持数乘(齐次性):\(A(c\,v)=c\,(Av)\)。
  3. 原点不动:\(A\,\mathbf{0}=\mathbf{0}\)(这其实是齐次性取 \(c=0\) 的推论)。

回头看第二节那个把 \(Av\) 拆成 \(x(A\hat{\imath})+y(A\hat{\jmath})\) 的等式:第一步"把和拆开"正是性质 1,第二步"把标量提出来"正是性质 2。所以"列视角"不是凭空的魔法,而是这两条性质的直接推论。

用 3Blue1Brown 的直觉说:线性变换就是那种"网格线始终保持平行且等距,原点钉死不动"的变形。允许拉伸、旋转、斜切;但不允许把直网格弯成曲线,也不允许整体平移让原点跑掉。

这解释了一个常见困惑:神经网络里的 \(Wx+b\),那个 \(+b\)(平移)不是线性变换(它让原点动了),严格说是"仿射 affine"变换。这里先给仿射一个正面定义记住:仿射变换 = 一个线性变换再加一个平移,即 \(x\mapsto Ax+b\);当 \(b=\mathbf{0}\) 时它就退化成线性变换。后面讲神经网络层时还会回到这点。

四、五种最常见的 2D 变换

下表把几何动作翻译成矩阵。建议你对每个矩阵都心算一下它把 \(\hat{\imath},\hat{\jmath}\)(即两列)搬到了哪里。

变换矩阵几何效果
缩放 scaling\(\begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix}\)横向拉 \(s_x\) 倍、纵向拉 \(s_y\) 倍
旋转 rotation\(\begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}\)绕原点逆时针转 \(\theta\)
剪切 shear\(\begin{bmatrix} 1 & k \\ 0 & 1 \end{bmatrix}\)把竖直网格斜推成平行四边形
反射 reflection\(\begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}\)沿 \(x\) 轴镜像翻转
投影 projection\(\begin{bmatrix} 1 & 0 \\ 0 & 0 \end{bmatrix}\)把整个平面压扁到 \(x\) 轴上
单位正方形在缩放、旋转、剪切、反射四种变换下的形变2x2四宫格,每格以淡灰虚线单位正方形为参照,展示变换后的淡黄实线形状,并标注对应的2x2矩阵。缩放[[2,0],[0,1]]012旋转 45°[[c,−s],[s,c]]45°01剪切[[1,1],[0,1]]012反射[[1,0],[0,−1]]FF0
单位正方形在四种基本变换下的形变。以淡黄单位正方形为基准,分别展示缩放(横向拉长成矩形)、旋转(整体逆时针转 45° 仍是正方形)、剪切(顶边右推成平行四边形)、反射(沿 x 轴翻到下方)。每格标注对应矩阵,网格线在前三种保持平行等距,帮助读者把矩阵和几何动作绑定记忆。

旋转矩阵从哪来?

用列视角秒推:逆时针转 \(\theta\) 后,\(\hat{\imath}=(1,0)\) 落到 \((\cos\theta,\sin\theta)\),\(\hat{\jmath}=(0,1)\) 落到 \((-\sin\theta,\cos\theta)\)。把这两个落点当列拼起来,就是旋转矩阵:

\[ R(\theta)=\begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}. \]

例题:旋转 90°

取 \(\theta=90^\circ\),\(\cos90^\circ=0,\ \sin90^\circ=1\),于是 \(R=\begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix}\)。

作用在 \(\begin{bmatrix}3\\2\end{bmatrix}\) 上:\(R\begin{bmatrix}3\\2\end{bmatrix}=\begin{bmatrix}0\cdot3+(-1)\cdot2\\ 1\cdot3+0\cdot2\end{bmatrix}=\begin{bmatrix}-2\\3\end{bmatrix}.\)

几何检验:\((3,2)\) 在第一象限,逆时针转 90° 应进入第二象限(\(x\) 变负、\(y\) 变正),\((-2,3)\) 正符合。口诀:旋转 90° 就是 \((x,y)\mapsto(-y,x)\)。

五、行列式:面积的缩放因子

变换把空间拉伸或压缩,那"被放大了多少倍"?答案就是行列式 determinant,记作 \(\det A\) 或 \(|A|\)。对 \(2\times2\):

\[ \det\begin{bmatrix} a & b \\ c & d \end{bmatrix}=ad-bc. \]

要点:行列式的三层含义

  • 大小:\(|\det A|\) = 面积(三维则是体积)的缩放倍数。变换前面积为 1 的单位正方形,变换后面积变成 \(|\det A|\)。
  • 符号:\(\det A>0\) 保持定向;\(\det A<0\) 说明空间被翻转了(像照镜子,左右手互换)。还记得第四节的反射 \(\begin{bmatrix}1&0\\0&-1\end{bmatrix}\) 吗?它的 \(\det=1\cdot(-1)-0\cdot0=-1<0\),正是它把右手系翻成左手系——这就是符号为负最干净的几何实例。
  • 为零:\(\det A=0\) 意味着空间被压扁、降维——面积塌成 0,变换不可逆 non-invertible(信息丢失,搬不回来)。
行列式作为带符号的面积缩放因子 1 2 3 4 单位正方形 面积 = 1, det = 1 1 2 3 4 A = [[2,1],[0,3]] 面积 = 6 = det A det > 0, 定向保持 1 2 3 4 含反射变换 det < 0, 定向翻转 退化变换 det = 0, 压扁成一维 面积 = 0, 不可逆 行列式 = 带符号的面积缩放因子:|det| 是面积放大倍数,符号记录定向是否翻转
行列式 = 带符号的面积缩放因子。左:单位正方形面积为 1。中:经 A=[[2,1],[0,3]] 变换成平行四边形,面积变为 6 = det A > 0,定向保持(角点逆时针顺序不变)。右:经含反射的变换 det < 0,平行四边形被翻面,定向反转,用顺/逆时针小箭头标注定向翻转。det=0 的情形单独画成一条线段,表示空间被压扁、面积归零。

例题:验证面积缩放

仍用 \(A=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\),先算 \(\det A=2\cdot3-1\cdot0=6\)。

把单位正方形的四个角 \((0,0),(1,0),(1,1),(0,1)\) 逐个变换(用列视角,\(A\) 的两列是 \((2,0)\) 和 \((1,3)\)):

  • \((0,0)\mapsto(0,0)\)(原点不动)
  • \((1,0)\mapsto(2,0)\)(即第一列)
  • \((1,1)\mapsto(2,0)+(1,3)=(3,3)\)(两列之和)
  • \((0,1)\mapsto(1,3)\)(即第二列)

变换后是顶点为 \((0,0),(2,0),(3,3),(1,3)\) 的平行四边形。它由两条边向量 \((2,0)\) 与 \((1,3)\) 张成,面积 = \(|2\cdot3-0\cdot1|=6\),正好等于 \(\det A=6\)。单位正方形(面积 1)被放大成面积 6,缩放因子 = 行列式。验证成功。

易错

\(\det\) 只对方阵有定义(输入输出维数相同才谈得上"面积/体积缩放")。另外别把"\(\det A=0\) 不可逆"忘了:它等价于"两列线性相关、把空间压扁"。一旦压扁,多个不同向量会被搬到同一点,再也分不开——这正是下面"零空间"的来源。

六、矩阵乘法 = 变换的复合

如果先做变换 \(B\)、再做变换 \(A\),整体效果是什么?把它作用在 \(x\) 上就是 \(A(Bx)\)。我们定义矩阵乘积 \(AB\),使得

\[ (AB)\,x = A\,(B\,x)\quad\text{对所有 } x \text{ 成立}. \]

也就是说,矩阵乘法 \(AB\) 就是"先 \(B\) 后 \(A\)"这个复合变换对应的那个矩阵。注意书写顺序:靠近 \(x\) 的先作用,所以要从右往左读。(记个口诀:谁挨着 \(x\),谁先上场。)

复合变换:先 B 后 A 等于 AB,从右往左读x=(2,1)① 原始先做 B(剪切)Bx=(3,1)② 经 B 后再做 A(拉伸)A(Bx)=(7,3)③ 经 A 后(AB)x = A(Bx),从右往左读靠近 x 的先作用 · 一般地 AB ≠ BA
复合变换:先 B 后 A,等于矩阵相乘 AB。三联图从左到右:原始单位正方形与向量 x;经剪切 B 后变成平行四边形、x 移到 Bx;再经拉伸 A 后得到最终形状、向量到达 A(Bx)。下方标注 (AB)x = A(Bx),强调'靠近 x 的先作用、从右往左读',并提示一般 AB≠BA。

为什么一般 \(AB\neq BA\)?

因为"先剪切后旋转"和"先旋转后剪切"在几何上根本是两件事。举例,取旋转 90° 的 \(A=\begin{bmatrix}0&-1\\1&0\end{bmatrix}\) 与缩放 \(B=\begin{bmatrix}2&0\\0&1\end{bmatrix}\):

\[ AB=\begin{bmatrix}0&-1\\1&0\end{bmatrix}\begin{bmatrix}2&0\\0&1\end{bmatrix}=\begin{bmatrix}0&-1\\2&0\end{bmatrix},\qquad BA=\begin{bmatrix}2&0\\0&1\end{bmatrix}\begin{bmatrix}0&-1\\1&0\end{bmatrix}=\begin{bmatrix}0&-2\\1&0\end{bmatrix}. \]

两者不等,所以矩阵乘法不满足交换律。(但满足结合律 \((AB)C=A(BC)\),这正是复合变换天然成立的。)

例题:验证复合 = 相乘

取剪切 \(B=\begin{bmatrix}1&1\\0&1\end{bmatrix}\) 与拉伸 \(A=\begin{bmatrix}2&1\\0&3\end{bmatrix}\),作用向量 \(x=\begin{bmatrix}2\\1\end{bmatrix}\)。

路线一(分两步):先算 \(Bx=\begin{bmatrix}1\cdot2+1\cdot1\\0\cdot2+1\cdot1\end{bmatrix}=\begin{bmatrix}3\\1\end{bmatrix}\),再算 \(A(Bx)=\begin{bmatrix}2\cdot3+1\cdot1\\0\cdot3+3\cdot1\end{bmatrix}=\begin{bmatrix}7\\3\end{bmatrix}.\)

路线二(先乘矩阵):\(AB=\begin{bmatrix}2\cdot1+1\cdot0 & 2\cdot1+1\cdot1\\ 0\cdot1+3\cdot0 & 0\cdot1+3\cdot1\end{bmatrix}=\begin{bmatrix}2&3\\0&3\end{bmatrix}\),再算 \((AB)x=\begin{bmatrix}2\cdot2+3\cdot1\\0\cdot2+3\cdot1\end{bmatrix}=\begin{bmatrix}7\\3\end{bmatrix}.\)

两条路线都得 \(\begin{bmatrix}7\\3\end{bmatrix}\),验证 \((AB)x=A(Bx)\)。顺带一提 \(\det(AB)=\det A\cdot\det B=6\cdot1=6\):复合变换的面积缩放,就是各步缩放因子相乘。

七、形状契约:维数怎么对上

到这里前六节用的都是 \(2\times2\) 方阵——输入和输出都在同一个平面里。但矩阵不必是方的。一个 \(m\times n\) 矩阵代表一个把 \(n\) 维向量送到 \(m\) 维空间的线性变换(\(n\) 列、每列是 \(m\) 维落点)。这意味着它可以改变维数

先用一个最小的非方阵建立画面:

\[ P=\begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \end{bmatrix}. \]

它是 \(2\times3\),把三维向量送到二维。看它怎么作用:\(P\begin{bmatrix}x\\y\\z\end{bmatrix}=\begin{bmatrix}x\\y\end{bmatrix}\)——它丢掉了 \(z\) 坐标,把 3D 空间压扁投影到 \(xy\) 平面上,这正是一次"降维"。反过来,一个 \(3\times2\) 矩阵则把平面"嵌入"到三维空间里(升维)。"\(m\neq n\) 到底在做什么",答案就是在维数之间搬运

乘法要能进行,必须满足形状契约

\[ (m\times n)\,(n\times p)=(m\times p). \]

要点

左矩阵的列数必须等于右矩阵的行数(中间的 \(n\) 要相消),结果矩阵的形状是"外侧两个数" \(m\times p\)。在 ML 里 99% 的形状报错都是这条契约没对上——养成在脑中默念形状的习惯。

八、秩与零空间:被压扁到几维

当 \(\det A=0\)(或更一般地,非方阵情形),空间被压扁了。两个概念精确描述"压扁的后果":

例题:亲手数出秩与零空间

对投影矩阵 \(P=\begin{bmatrix}1&0\\0&0\end{bmatrix}\),我们把三件事都算出来:

  • 列空间(决定秩):两列是 \((1,0)\) 与 \((0,0)\)。第二列是零向量、毫无贡献,输出只能落在第一列张成的 \(x\) 轴上。所以列空间 = \(x\) 轴(一维),秩 = 1
  • 零空间:解 \(Pv=\mathbf{0}\),即 \(\begin{bmatrix}1&0\\0&0\end{bmatrix}\begin{bmatrix}a\\b\end{bmatrix}=\begin{bmatrix}a\\0\end{bmatrix}=\begin{bmatrix}0\\0\end{bmatrix}\),要求 \(a=0\)、\(b\) 任意。于是零空间是全体 \(\begin{bmatrix}0\\t\end{bmatrix}\),正是整条 \(y\) 轴(一维),一个基是 \(\begin{bmatrix}0\\1\end{bmatrix}\)。
  • 当场兑现守恒律:秩 1 +(零空间维数)1 = 2 = 输入维数(列数)。

这条"秩 + 零空间维 = 列数"的守恒律叫秩-零化度定理 rank–nullity theorem。直觉是:输入的每一维,要么被保留到输出里(贡献给秩),要么被压到原点(贡献给零空间),不会凭空消失。后续课会给出正式证明。

ML 和 ML 的联系

1. 神经网络每一层 = 线性变换 + 平移 + 非线性。一层的计算是 \(h=\sigma(Wx+b)\):权重矩阵 \(W\) 是线性变换(把上一层的特征"掰弯"重组),\(b\) 是平移——\(Wx+b\) 合起来正是上一节说的仿射变换(线性变换 + 平移),外面再套的 \(\sigma\)(如 ReLU)是非线性。正因为线性变换的复合还是线性变换(\(A(Bx)=(AB)x\)),如果没有中间的非线性,再多层叠起来也等价于单个矩阵 \(W=W_3W_2W_1\)——深度就白费了。非线性是深度网络的灵魂,而你刚证明的复合律正是"为什么需要它"的数学原因。

2. 注意力机制里的 \(QK^\top\) 就是一批线性变换 + 两两点积。把输入经线性变换得到查询 \(Q\) 和键 \(K\)(各是 \(Wx\) 形式),\(QK^\top\) 的第 \(i,j\) 个元素正是第 \(i\) 个查询向量与第 \(j\) 个键向量的点积——也就是上一课讲的"用点积衡量相似度",被矩阵乘法一次性批量算完。线性变换 + 点积,就是 Transformer 的核心算子。

九、用 numpy 把这一切跑一遍

下面的代码只用 numpy 和 print,几秒跑完。它打印基向量落点、行列式、并验证 \(A(Bx)=(AB)x\) 以及 \(\det(AB)=\det A\det B\)。

import numpy as np

A = np.array([[2., 1.],
              [0., 3.]])

# 1) 矩阵的列 = 基向量变换后的落点
i_hat = np.array([1., 0.])
j_hat = np.array([0., 1.])
print("A @ i_hat =", A @ i_hat, "  <- 应等于 A 的第一列", A[:, 0])
print("A @ j_hat =", A @ j_hat, "  <- 应等于 A 的第二列", A[:, 1])

# 2) 行列式 = 面积缩放因子
print("det(A) =", round(np.linalg.det(A), 6))   # 期望 6.0

# 单位正方形四角 -> 验证面积
square = np.array([[0, 0], [1, 0], [1, 1], [0, 1]]).T  # 每列一个角
print("正方形四角变换后(每行一个角):")
print((A @ square).T)

# 3) 旋转 90 度: (x,y) -> (-y,x)
theta = np.pi / 2
R = np.array([[np.cos(theta), -np.sin(theta)],
              [np.sin(theta),  np.cos(theta)]])
print("R @ [3,2] =", np.round(R @ np.array([3., 2.]), 6))  # 期望 [-2, 3]

# 4) 复合变换 = 矩阵相乘
B = np.array([[1., 1.],
              [0., 1.]])           # 剪切
x = np.array([2., 1.])
print("A @ (B @ x) =", A @ (B @ x))   # 分两步
print("(A @ B) @ x =", (A @ B) @ x)   # 先乘矩阵, 两者应相同

# 5) 乘法不可交换 + 行列式可乘
print("AB =\n", A @ B)
print("BA =\n", B @ A, "  <- 与 AB 不同")
print("det(A)*det(B) =", round(np.linalg.det(A) * np.linalg.det(B), 6),
      " det(AB) =", round(np.linalg.det(A @ B), 6))

运行后你会看到:基向量落点恰是 \(A\) 的两列;\(\det A=6\) 与四角围成的面积一致;\(R[3,2]^\top=[-2,3]^\top\);两条复合路线都给 \([7,3]^\top\);而 \(AB\neq BA\),但 \(\det(AB)=\det A\det B=6\)。

调一调,观察现象

下面三个小实验都只用 numpy 和 print,几秒跑完。每个都先猜结果再运行,重点是把"改一个数 → 几何上发生了什么"对应起来。

实验一:调剪切强度 k,看基向量落点变、行列式不变

改什么:把剪切矩阵 \(\begin{bmatrix}1&k\\0&1\end{bmatrix}\) 里的 \(k\) 从 0 调到 1 再到 3。

预期现象:\(\hat{\jmath}\) 的落点从 \((0,1)\) 滑到 \((1,1)\) 再到 \((3,1)\)(竖直网格越推越斜),但三种情况 \(\det\) 全是 \(1.0\)。

为什么:剪切只把平行四边形"推歪",底和高没变,面积不变,所以行列式恒为 1——这正是第五节"行列式 = 面积缩放因子"的体现。

import numpy as np
for k in [0., 1., 3.]:
    S = np.array([[1., k],
                  [0., 1.]])
    print("k =", k,
          " j_hat 落点 =", S @ np.array([0., 1.]),
          " det =", round(np.linalg.det(S), 6))

实验二:交换两行,看行列式符号翻转

改什么:把 \(A=\begin{bmatrix}2&1\\0&3\end{bmatrix}\) 的第一行和第二行对调。

预期现象:\(\det A = 6.0\),交换两行后变成 \(-6.0\),大小不变、符号翻了。

为什么:交换两行相当于额外做了一次反射,把空间的定向翻转了一次(右手系变左手系),所以行列式由正变负——正对应第五节"\(\det<0\) 表示翻转"。

import numpy as np
A = np.array([[2., 1.],
              [0., 3.]])
A_swap = A[[1, 0], :]          # 对调两行
print("det(A)      =", round(np.linalg.det(A), 6))       # 期望 6.0
print("det(行交换) =", round(np.linalg.det(A_swap), 6))   # 期望 -6.0

实验三:换不同矩阵,看 det 落在哪个区间

改什么:分别取旋转矩阵、缩放 \(\mathrm{diag}(2,5)\)、投影 \(\begin{bmatrix}1&0\\0&0\end{bmatrix}\),各算一次行列式。

预期现象:旋转的 \(\det=1.0\)(保面积、不翻转),缩放的 \(\det=10.0\)(面积放大 \(2\times5\) 倍),投影的 \(\det=0.0\)(被压扁、不可逆)。

为什么:旋转只转不缩、缩放按两轴倍数相乘放大面积、投影把平面压到一条线上面积塌成 0——三档分别对应行列式 \(=1\)、\(>1\)、\(=0\) 三种几何命运。

import numpy as np
th = 0.7
R = np.array([[np.cos(th), -np.sin(th)],
              [np.sin(th),  np.cos(th)]])     # 旋转
D = np.diag([2., 5.])                         # 缩放
P = np.array([[1., 0.],
              [0., 0.]])                      # 投影
print("det(旋转) =", round(np.linalg.det(R), 6))   # 期望 1.0
print("det(缩放) =", round(np.linalg.det(D), 6))   # 期望 10.0
print("det(投影) =", round(np.linalg.det(P), 6))   # 期望 0.0

动手练习

  1. 手算 + 列视角。给定 \(M=\begin{bmatrix}3&-1\\2&2\end{bmatrix}\),(a) 写出它把 \(\hat{\imath},\hat{\jmath}\) 搬到的落点;(b) 用列视角算 \(M\begin{bmatrix}1\\2\end{bmatrix}\);(c) 算 \(\det M\) 并说出面积放大几倍、有没有翻转。
    import numpy as np
    M = np.array([[3., -1.], [2., 2.]])
    # TODO: 打印 M 的两列、M @ [1,2]、det(M)
    print(M[:, 0], M[:, 1])
    print(M @ np.array([1., 2.]))
    print(round(np.linalg.det(M), 6))
    
  2. 旋转复合。构造旋转 30° 与旋转 60° 的矩阵,验证它们相乘等于旋转 90° 的矩阵(提示:转 30° 再转 60° 当然等于转 90°)。
    import numpy as np
    def rot(t):
        return np.array([[np.cos(t), -np.sin(t)],
                         [np.sin(t),  np.cos(t)]])
    # TODO: 比较 rot(60度) @ rot(30度) 与 rot(90度)
    print(np.round(rot(np.pi/3) @ rot(np.pi/6), 6))
    print(np.round(rot(np.pi/2), 6))
    
  3. 压扁、零空间与守恒律。对投影矩阵 \(P=\begin{bmatrix}1&0\\0&0\end{bmatrix}\):(a) 写出它零空间的一个基向量(一个非零 \(v\) 使 \(Pv=\mathbf{0}\));(b) 说出它的秩等于几;(c) 验证"秩 + 零空间维 = 2"这条守恒律;(d) 顺手算 \(\det P\) 确认它为 0。
    import numpy as np
    P = np.array([[1., 0.], [0., 0.]])
    # TODO: 找零空间的基, 数秩, 验证守恒律
    v = np.array([0., 1.])             # 零空间的一个基向量?
    print("P @ v =", P @ v)            # 期望 [0, 0]
    print("rank(P) =", np.linalg.matrix_rank(P))   # 期望 1
    print("det(P) =", round(np.linalg.det(P), 6))  # 期望 0.0
    
  4. 不可交换的几何(含 det<0)。取剪切 \(S=\begin{bmatrix}1&1\\0&1\end{bmatrix}\) 与反射 \(F=\begin{bmatrix}1&0\\0&-1\end{bmatrix}\),算 \(SF\) 与 \(FS\),确认不相等,并各自把 \(\begin{bmatrix}1\\1\end{bmatrix}\) 变换一遍看落点差别;再算 \(\det F\) 确认它是负的(反射翻转了定向)。
  5. 形状契约。随机生成一个 \(2\times3\) 矩阵和一个 \(3\times4\) 矩阵相乘,打印结果形状,确认是 \(2\times4\);再试着把它们反过来乘,观察 numpy 报什么错。

掌握自检

下一课,我们把"点积"升级为内积,用它一次讲透度量、正交、投影、最小二乘——也就是机器学习里"拟合"与"误差最小化"的几何本质。