ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

线性代数知识点总结:用NumPy断言核对行列式、矩阵与方程组

线性代数知识点总结:用NumPy断言核对行列式、矩阵与方程组

简介:这份线性代数知识点总结文档面向高校理工科学生、考研复习者及需要夯实数学基础的工程技术人员,围绕向量空间、线性变换与线性方程组等核心内容,帮助读者系统梳理课程脉络并查漏补缺。压缩包内仅含1个docx文件,体积约572KB,轻量便携,适合打印或导入平板逐章标注。文档从二阶、三阶行列式入手,依次讲解全排列与逆序数、n阶行列式定义、对换、行列式性质、按行(列)展开、克拉默法则,并延伸到矩阵定义、矩阵加法、数乘与矩阵乘法等运算,对易混概念和常用计算法则作了归纳。已有4605人学习下载,可作为课堂同步笔记、期末复习提纲或考研首轮梳理材料,便于快速定位公式、性质与典型方法,建立从行列式到矩阵的知识框架。

1. 线性代数知识点总结:一份能对着页码回查的计算骨架

线性代数最难受的地方不是不会算,而是算完不知道对不对。行列式展开少一个负号、矩阵左右一换结果全变、秩算到最后差一行,这些错误在考试里没人提醒,在工作里代价更大——图形变换、最小二乘拟合、降维里矩阵一错,后面全是垃圾。这份《线性代数知识点总结》走的是另一条路:不追求定理讲得漂亮,而是把行列式、矩阵、初等变换、向量组四条主线按教材顺序压成一份可以逐条对照的骨架,每节后面挂着 P1、P5、P16、P53 这样的页码,缺哪块翻回去补。它适合正在跟课、需要一份和教材对齐的复习清单的人,也适合工作几年后想把矩阵运算重新捡起来、又不想重啃整本教材的从业者。

2. 从行列式切入:逆序数、六条性质与展开定理的计算链

2.1 为什么逆序数排在对角线法则后面而不是前面

教材的顺序是先给二阶、三阶的对角线法则,再补全排列与逆序数,最后才给 n 阶定义。乍看绕,其实这个顺序是对的:先让人建立“行列式是一个数”的直觉,再用逆序数把符号规则统一起来。如果一上来就摆 $(-1)^t$ 的公式,多数人会在正负号上翻车,而且错完还不知道错在哪一步。笔记保留了原顺序,把逆序数放在第一节末尾,这个编排我认可。

逆序数的手算有两种走法,笔记里都给了,实际用的时候要挑:排列乱、元素少,从前往后数每个元素后面比它小的个数;排列接近自然顺序,从后往前数每个元素前面比它大的个数更省事。

算法数的是什么适合场景常见错法
从前往后每个元素右侧比它小的个数排列较乱、n 较小最后几个元素漏数
从后往前每个元素左侧比它大的个数排列接近顺序下标位置对错行
逐位累加每次把元素挪到正确位置的距离需要同时写出对换次数只算总数不算过程

拿排列 32514 走一遍:3 右边比它小的有 2、1,贡献 2;2 右边比它小的有 1,贡献 1;5 右边比它小的有 1、4,贡献 2;1 和 4 后面没有更小的,各贡献 0。总数 5,是奇数,所以它是奇排列。这个数会直接进 n 阶行列式的符号项,算错一个,整项的正负就反了。

提示:逆序数不是“有多少对逆序元素”的另一种说法,它就是那个总数。做题时先写清楚每个元素的贡献,再求和,比心算靠谱得多。

2.2 六条性质里真正高频的只有三条

笔记把行列式的六条性质列全了:转置不变、换行变号、某行乘 k、两行成比例为零、某行可拆成两行之和、某行的 k 倍加到另一行值不变。列全是必要的,但真到动手算的时候,用得上的是另外三条的组合。

高频的是性质 6(倍加不变)、性质 2(换行变号)和性质 3 的推论(整行提公因子)。性质 6 是化三角的主力,性质 2 是为性质 6 服务的——消元时如果主元位置是 0,必须换行,换完记得给结果乘 -1。这一步是手算里最容易丢符号的地方。性质 4 和性质 5 更像是“看出来就省事”的捷径,比如发现两行成比例,直接写 0,不用再往下算。

化上三角是通用路径,流程固定:

  1. 从左到右逐列处理,用第 1 行消掉第 1 列下方所有非零元;
  2. 主元为 0 时与下方非零行互换,记一次变号;
  3. 处理完第 1 列,再拿第 2 行消第 2 列下方,依此类推;
  4. 得到上三角后,把主对角线元素相乘,乘上中途记录的符号。

拿一个三阶的例子走完整流程,$D=\begin{vmatrix}1&2&3\4&5&6\7&8&10\end{vmatrix}$。第二行减第一行的 4 倍,得 $(0,-3,-6)$;第三行减第一行的 7 倍,得 $(0,-6,-11)$;第三行再减第二行的 2 倍,得 $(0,0,1)$。上三角的主对角线是 1、-3、1,乘积 -3。全程没有换行,符号不用调整。

注意:对角线法则只对二阶和三阶成立。四阶以上套对角线公式,结果一定错,而且错得很像对的——因为它恰好算出了某一组项的和,只是漏掉了其余项。

2.3 用代码把性质逐条验证一遍

手算最容易自我欺骗:算错了,再算一遍还是同样的错。用几行代码把性质跑成断言,是把“我以为对”变成“确实对”的最快办法。下面这段只依赖 NumPy,把三角行列式、换行变号、数乘、成比例为零四条一起验了。

import numpy as np np.set_printoptions(precision=4, suppress=True) # 用例 1:上三角行列式等于主对角线元素之积 U = np.array([[2., 7., 1.], [0., 3., 5.], [0., 0., 4.]]) print("det(U) =", np.linalg.det(U), "对角线乘积 =", np.prod(np.diag(U)), "一致 =", np.isclose(np.linalg.det(U), np.prod(np.diag(U)))) # 用例 2:性质 2,互换两行行列式变号 A = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 10.]]) # 故意选 det != 0 的矩阵,否则符号错误会被 0 掩盖 A_swap = A[[1, 0, 2], :] # 交换第 0 行与第 1 行,其余不动 print("det(A) =", np.linalg.det(A), "det(A_swap) =", np.linalg.det(A_swap)) print("变号校验 =", np.isclose(np.linalg.det(A) + np.linalg.det(A_swap), 0)) # 用例 3:性质 3,某一行乘 k,行列式整体乘 k k = 5.0 A_k = A.copy() A_k[2, :] = A_k[2, :] * k # 只放大第 2 行,不能整矩阵乘 k print("k*det(A) =", k * np.linalg.det(A), "det(A_k) =", np.linalg.det(A_k)) # 用例 4:性质 4,两行成比例,行列式为 0 B = np.array([[1., 2., 3.], [2., 4., 6.], # 第 1 行 = 2 × 第 0 行 [7., 8., 10.]]) print("成比例行列式 =", np.linalg.det(B)) # 结果应为 0.0

四段代码分别对应一节笔记内容,逻辑很清楚:用例 1 验的是推论 2,用例 2 验的是性质 2,用例 3 验的是性质 3,用例 4 验的是性质 4。参数上唯一要留意的是np.isclose的默认容差,浮点运算下det很少精确等于整数,直接写==会得到 False,让人误以为是定理错了。另外A_swap = A[[1, 0, 2], :]是行索引重排,写A[[0, 1, 2], :]就是原地不动,这类索引顺序错位在批量验证时非常常见。

2.4 按行展开与代数余子式:手算和代码要对得上

展开定理的表述不复杂:n 阶行列式等于任意一行各元素与对应代数余子式乘积之和。真正卡人的是两个细节,一是余子式要划掉第 i 行第 j 列,二是符号 $(-1)^{i+j}$ 不能漏。笔记里专门标了“异乘变零”的推论:某一行元素乘另一行对应元素的代数余子式,求和为 0。这条推论在做题时能快速排除选项,在验证代码时也是很好的断言。

上面那个三阶例子按第一行展开:$1\times(5\times10-6\times8) - 2\times(4\times10-6\times7) + 3\times(4\times8-5\times7) = 1\times2 - 2\times(-2) + 3\times(-3) = 2+4-9=-3$,和化三角的结果一致。两条路径必须收敛到同一个数,否则一定是某一步的符号或余子式划错了。手算时我一般两种方法各走一半:化三角求值,展开定理只用来验算某一行,两边对上就停。

3. 矩阵与求逆:乘法条件、伴随矩阵与分块的三条落地路径

3.1 矩阵运算的三条硬约束,错一条后面全废

矩阵这块的坑不在公式多,而在约束多,而且约束往往被跳过。第一条:加法只在同型矩阵之间成立,$m\times n$ 和 $m\times n$ 才能加。第二条:乘法要求左矩阵的列数等于右矩阵的行数,$A_{m\times s}B_{s\times n}$ 才有意义,结果是 $m\times n$。第三条最隐蔽:矩阵数乘和行列式数乘不是一回事,$|kA|=k^n|A|$,不是 $k|A|$。

第三条的杀伤力在于它看起来“显然”。三阶方阵乘 2,行列式放大 8 倍而不是 2 倍,因为每一行都提了一个 2 出来。笔记里特意把“矩阵的数乘运算与行列式的数乘运算不同”单列成一句总结性提示,这个位置放得对,它是整章最高频的失分点。

还有一条不算约束但同样关键:矩阵乘法不满足交换律。两个非零矩阵相乘还可能是零矩阵,这在标量运算里不可能出现。判断 $AB=BA$ 是否成立,只能老实算两遍,别靠直觉。

3.2 逆矩阵的两条路线:伴随矩阵和初等变换怎么选

可逆的判定只有一条:$|A|\neq0$,也就是非奇异。求逆有两条路,选哪条取决于矩阵规模和使用场景。

路线公式或操作适合规模计算量级主要风险
伴随矩阵法$A^{-1}=A^*/A$二阶、三阶手算
初等行变换$(A\mid E)\to(E\mid A^{-1})$三阶以上约 $O(n^3)$中途做列变换、行变换方向反
分块对角各块分别求逆再拼回有明显块结构取决于块大小块顺序拼反

伴随矩阵法的价值在理论推导,比如证明 $AA^*=|A|E$、推逆矩阵性质,手算只在小矩阵上划算。三阶以上老老实实做初等行变换,把 $A$ 和单位阵并排写,只允许行变换,化成左边是 $E$ 时,右边就是 $A^{-1}$。这里有个血泪经验:一旦中途手滑做了列变换,左边化不成 $E$,很多人会以为矩阵不可逆,其实是操作错了。

提示:伴随矩阵满足 $AA^*=A^A=|A|E$,这是验算逆矩阵最省事的断言。只要 $A^$ 里有一个代数余子式算错,乘出来的对角元就不全等于 $|A|$。

3.3 分块矩阵和秩:把高阶问题拆成低阶

分块的目的只有一个,把大矩阵拆成能单独处理的子块。分块对角阵最有用:主对角线上是若干方阵,其余块全零,那么它的行列式等于各块行列式之积,求逆就是各块分别求逆再放回原位,秩等于各块秩之和。这三条结论在解高阶问题时能省掉大量计算。

秩的定义有两个等价说法:最高阶非零子式的阶数,或者行阶梯形中非零行的行数。手算一律用后者,因为化行阶梯形的同时就把方程组解的情况一起判了。要记住的边界有:$R(A)\le\min(m,n)$、$R(A)=R(A^T)$、$R(AB)\le\min(R(A),R(B))$、$R(A+B)\le R(A)+R(B)$。最后这条是小于等于不是等于,很多人会写成等号。

分块矩阵乘法还有个容易忽略的前提:$A$ 的列分法必须和 $B$ 的行分法一致,否则块之间对不上,乘出来是错的,而且错得毫无提示。做分块乘法前先把两边的分块线画出来对齐,比事后检查快得多。

3.4 用代码核对伴随矩阵与逆矩阵

伴随矩阵手算极易出错,用代码复现一遍是最快的对账方式。下面这段按定义逐元素求代数余子式,再转置得到 $A^$,最后验 $AA^=|A|E$。

import numpy as np def cofactor_matrix(M): """按定义求伴随矩阵 A*:先求代数余子式矩阵,再转置""" n = M.shape[0] C = np.zeros_like(M, dtype=float) for i in range(n): for j in range(n): minor = np.delete(np.delete(M, i, axis=0), j, axis=1) # 划去第 i 行、第 j 列 C[i, j] = ((-1) ** (i + j)) * np.linalg.det(minor) # 代数余子式 A_ij return C.T # 转置才是伴随矩阵 A = np.array([[1., 2., 3.], [2., 5., 3.], [1., 0., 8.]]) detA = np.linalg.det(A) Astar = cofactor_matrix(A) print("det(A) =", detA) print("A @ A* =\n", A @ Astar) # 应等于 detA * E print("断言 AA* = |A|E:", np.allclose(A @ Astar, detA * np.eye(3))) print("逆矩阵 = A*/|A| =\n", Astar / detA) print("与 numpy 求逆一致:", np.allclose(Astar / detA, np.linalg.inv(A)))

这段代码的教学价值大于生产价值。cofactor_matrix里两层循环各调一次np.linalg.det,复杂度是 $O(n^5)$ 级别,四阶以上就明显变慢,实际工程里直接用np.linalg.inv或解线性方程,不要拿它算大矩阵。参数上要注意np.delete的axis顺序:先删行(axis=0)再删列(axis=1),顺序反了虽然维度还对,但索引含义会错位。最后那个np.allclose才是重点,把 $A^{-1}=A^*/|A|$ 这个公式变成一行可执行的判断,比盯着纸面推十遍都可靠。

4. 初等变换与线性方程组:四个必须排查的判定坑

4.1 秩算错:把“看起来像零”的行当成非零行

现象:化完行阶梯形,非零行数数出来比正确答案多一行,导致 $R(A)$ 偏大,方程组解的判定整个反过来。

原因大多出在分数运算上。手算化阶梯形时,某一行本该被消成全零,因为前一步的分数化简没做干净,剩下一个极小的非零数,眼睛一扫就当成了非零行。另一种情况是阶梯线画错,把两行合并成一个台阶,非零行数直接少算。

解决分三步:第一,消元时统一用分数或统一保留两位小数,不要混用;第二,化完之后从最后一行往上倒着检查,每一行的首个非零元所在列必须严格递增,不递增说明还有行没消干净;第三,用代码复核,np.linalg.matrix_rank一行就能给出秩,和手算结果对不上就以代码为准再回头找。做完阶梯形别急着往下判解,先花三十秒确认阶梯线是标准的。

4.2 基础解系个数写成 n 或 n-R(A)+1

现象:齐次方程组 $Ax=0$ 求通解,自由未知量取多了或取少了,通解里多一个或少一个任意常数。

原因是对“基础解系含有 $n-R(A)$ 个向量”这条结论记成了“$n$ 个”或者“$R(A)$ 个”。$n$ 是未知量个数,$R(A)$ 是系数矩阵的秩,两者相减才是自由度的个数。化成行最简形后,主元所在的列对应非自由未知量,其余列才是自由未知量,自由未知量的个数必须和 $n-R(A)$ 对得上,这是硬校验。

解决的办法很朴素:写完行最简形,先数主元个数,它等于 $R(A)$;再用 $n$ 减一次,得到应该有几个自由变量;最后逐个令自由变量取单位向量,写出基础解系。三步数字对不上,一定是行最简形还没化到位,回去继续消,不要硬写答案。

注意:非齐次方程组的通解是“特解 + 对应齐次方程组通解”,特解来自行最简形里常数项那一列,不要漏掉,也不要把特解再乘任意常数。

4.3 克拉默法则被用在方程个数不等于未知量个数的场合

现象:四个方程三个未知量的方程组,硬套克拉默法则算出一组数,代入原方程却不成立。

原因是克拉默法则的前提被跳过了:它只适用于方程个数与未知量个数相等、且系数行列式 $D\neq0$ 的情形。方程多于未知量时,$D$ 根本构不成方阵;方程少于未知量时,$D=0$ 或者无解,法则都不适用。笔记里在第七节专门标了这条限制,位置很靠前,但实际做题时最容易被忽略,因为公式本身太好用。

解决路径是先判型再选法:数一遍方程个数 $m$ 和未知量个数 $n$,$m\neq n$ 直接放弃克拉默法则,改用增广矩阵化行阶梯形判秩;$m=n$ 时先算 $D$,$D=0$ 也不能用,因为有可能是无解或无穷多解,只有 $D\neq0$ 才能保证唯一解。这一步花不了一分钟,能省掉后面全部返工。

4.4 把 $R(A)$ 和 $R(A,b)$ 混着用,解的判定整条错位

现象:非齐次方程组明明无解,判定成了无穷多解;或者有唯一解,判定成了无解。

原因是增广矩阵的秩和系数矩阵的秩分不清。正确判定是三条:$R(A)\neq R(A,b)$ 时无解;$R(A)=R(A,b)=n$ 时唯一解;$R(A)=R(A,b)<n$ 时无穷多解。很多人只记住“秩小于 n 就有无穷多解”,漏掉了前提是系数矩阵和增广矩阵的秩相等。而 $R(A,b)$ 至少等于 $R(A)$,可能大 1,这多出来的 1 就是矛盾方程的标志。

排查顺序建议固定下来:先化增广矩阵到行阶梯形,同时读出两个秩,比较;相等再和 $n$ 比;不相等立即判无解,不用往后算。这个顺序反过来做,很容易先入为主地往“有解”方向推。

5. 把笔记跑成回归测试:十条断言和三个自检习惯

一份数学笔记最大的问题是它不会报错。定理抄错了、符号写反了,纸面上完全看不出来,直到考试或者上项目才爆。我现在的做法是:每整理完一章,就把能验证的结论写成断言,跑一遍。

import numpy as np def check(name, cond): print(("PASS" if cond else "FAIL"), name) A = np.array([[1., 2., 3.], [2., 5., 3.], [1., 0., 8.]]) B = np.array([[2., 0., 0.], [0., 3., 0.], [0., 0., 4.]]) # 对角阵,用来验分块结论 check("三角行列式 = 对角线乘积", np.isclose(np.linalg.det(np.triu(A)), np.prod(np.diag(np.triu(A))))) check("|A^T| = |A|", np.isclose(np.linalg.det(A.T), np.linalg.det(A))) check("|kA| = k^n|A|", np.isclose(np.linalg.det(3 * A), 3 ** 3 * np.linalg.det(A))) check("det(AB) = det(A)det(B)", np.isclose(np.linalg.det(A @ B), np.linalg.det(A) * np.linalg.det(B))) check("可逆 <=> det != 0", np.isclose(np.linalg.det(A) != 0, True)) check("AA^{-1} = E", np.allclose(A @ np.linalg.inv(A), np.eye(3))) check("R(A) = R(A^T)", np.linalg.matrix_rank(A) == np.linalg.matrix_rank(A.T)) check("分块对角阵 det = 各块 det 之积", np.isclose(np.linalg.det(B), 2 * 3 * 4)) check("齐次方程 R(A)=n 只有零解", np.linalg.matrix_rank(A) == 3) check("克拉默前提:D != 0 时解唯一", np.linalg.matrix_rank(A) == np.linalg.matrix_rank(np.c_[A, np.ones(3)]))

这十条断言覆盖了行列式性质、矩阵行列式、逆矩阵、秩、方程组判定五块,跑一次不到一秒。写法上有两个细节值得说:一是一定要用np.isclose而不是==,浮点误差会让正确的定理显示成 FAIL;二是每条断言的名字要写清楚它验的是哪条结论,半年后回头看还能立刻定位。参数上基本不用调,唯一要改的是矩阵规模,三阶够用,想验分块结论就换成四阶对角块。

除了代码,还有三个习惯值得固定下来。第一,凡是有“只适用于”字样的结论,一律单独抄在一张纸上:对角线法则只适用二三阶、克拉默法则只适用方程个数等于未知量个数、逆矩阵只对方阵定义、行变换不能中途换成列变换。这四个“只”字是整份笔记里信息密度最高的部分。第二,每次化行阶梯形之后强制数一遍主元个数和自由变量个数,两个数字加起来必须等于未知量个数,不相等就说明有一步错了。第三,笔记里凡是标了“课本上没有”的扩展内容,单独标一个记号,复习时先过主线再过扩展,别让扩展内容挤掉主干的记忆空间。

从那以后我每次把一份数学笔记整理完,都会先写一组断言跑一遍,跑不通就说明笔记本身有问题,而不是我记性不好。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进