☰
用Python复现线性代数:从高斯消元到奇异值分解的工程实践
2026/10/3 15:40:04 网站建设 项目流程

简介:这是一份国外经典线性代数教材《Linear Algebra with Applications》第10版全球版电子书,由Steven J. Leon与Lisette de Pillis两位数学教授合著,适合高校学生、考研者及自学读者作为系统学习或复习参考。全书共8章、556页,内容完整覆盖线性方程组、矩阵代数、行列式、向量空间、特征值、特征向量、正交化、线性变换及数值方法等核心主题,并配有大量应用实例和习题。每章末尾附有MATLAB计算练习,帮助学习者借助程序验证抽象概念,也反映了线性代数教学与技术结合的趋势,对提升动手能力很有帮助。压缩包内只有1个PDF文件,大小6.69MB,排版清晰、体积小巧,适合在电脑、平板或手机上随时阅读与检索。该资源已有1053人学习使用,无论是伴随课程进度深入理解,还是考前集中梳理,都能提供权威而完整的参考。

1. 学线性代数最怕的不是公式,是不知道这章在解决什么问题

很多人拿到Linear Algebra with Applications 10th这本书,第一反应是翻开第1章开始背消元步骤。但真正卡住你的不是消元,而是你根本不知道为什么要消元。这本书的厉害之处恰恰相反:它把“解方程组”放在最前面,不是为了让你刷题,而是让你从“求x”这件事里看到整个线性代数的骨架——向量、矩阵、变换、分解。等你学到后面的特征值和奇异值,回头才发现第1章的每一次消元都是在为它们铺路。

这本书适合两类人:一类是工科生或程序员,需要线代作为机器学习、图形学、控制理论的数学底座,但不需要数学系的证明强度;另一类是自学者,想要一本例题多、应用场景明确、能靠做习题验证进度的教材。它能解决的核心问题是:把线性代数从一个“背公式的符号游戏”变成“看得见几何意义、算得出数值结果、能迁移到真实问题”的工具箱。接下来我会按这本书的内容顺序,拆一遍它到底怎么带你从消元走到奇异值分解。

2. 从解方程组到奇异值分解:这本书按什么顺序带你走完线代

2.1 为什么开篇先讲线性方程组,而不是向量空间

这本书的结构和大部分工程线代教材一样,开篇就是线性方程组和高斯消元。很多第一次接触的人会觉得这是最“无聊”的一章,因为只是反复做行变换。但你往后读就会发现,消元不是目的,是建立“矩阵等于变换”这个直觉的起点。

一个方程组可以写成 (A\mathbf{x}=\mathbf{b}),但同样这个式子还有两个读法:列视角把它看成 (\mathbf{b}) 是 (A) 的各列的线性组合;行视角把它看成每个方程是一条超平面。这本书在开头几章就是用这种“同一个式子换角度读”的方式,让你慢慢建立对矩阵的立体感。到后面学线性变换时,你才意识到原来矩阵的本质不是一张数表,而是一个把向量从一个空间映射到另一个空间的规则。

顺带说一下全书的内容编排逻辑。这本书大致可以分成三段:前几章解决“线性方程组和矩阵是什么”,中间章节进入向量空间、线性变换、特征值和内积空间,最后收在数值方法与应用上。它不是纯理论教材,但也不是纯刷题册,它是让你在每一个新概念出现时,都有一个可计算的例子托底。

2.2 核心概念地图:向量空间、线性变换、分解贯穿三张网

如果让我给这本书画一张概念地图,我会画三张互相缠绕的网。第一张是解方程网:从高斯消元到行列式再到克拉默法则,但这张网不是核心,它只是引出矩阵秩、逆、零空间的入口。第二张是空间网:向量空间、子空间、基、维数、零空间与列空间,这张网解决的是“这个矩阵到底把空间压成了什么形状”的问题。第三张是分解网:LU分解、特征值分解、奇异值分解,这张网解决的是“怎么把一个复杂矩阵拆成几个简单变换的乘积”。

这三张网不是顺序读完就完了,它们是交叉的。比如你在分解网里学的秩,是空间网里列空间维数的直接答案;你在空间网里学的零空间,又是解方程网里“无穷多解到底有多少个自由度”的答案。这本书的高明之处在于:每一章的习题都会用到前面章节的概念,但你没读到后面时根本察觉不到。

2.3 第10版强化的数值实验这条线,值不值得跟

Linear Algebra with Applications 10th相比更早版本有一个明显特点:应用和数值实验的内容比重更大。每个核心章节后面通常跟着一小节应用,比如用马尔可夫链建模人口迁移、用最小二乘拟合实验数据、用特征值分析振动系统。很多应用会直接给一个小的可计算例子,而不是只写一段文字描述。

这条线值得跟,但要有心理准备:它不是为了考你,而是为了让你把前面的抽象概念落到一个具体的矩阵上。比如马尔可夫链那一类应用,本质上就是反复验证“特征值为1对应的特征向量是什么”。如果你能动手把这个例子在代码里复现一遍,比做十道手算题都有用。后面第3章我会给出一套配合这本书的Python复现方案,直接用可运行的代码把这些数值实验跑起来。

提示:这本书的很多习题设计是“先手算、再思考、最后尝试数值验证”的三段式。如果你直接跳到数值验证而没做手算,会丢失掉很多对数字敏感度的训练。

3. 用NumPy跟着课本做一遍:从高斯消元到SVD的落地代码

3.1 用SymPy做符号消元,验证课本的手算步骤

课本里的手算步骤用的是分数和符号,但numpy默认的浮点数算高斯消元会有舍入误差,导致你得到0.3333333而课本写1/3。这时候用sympy做符号计算最合适,它能精确还原每一步消元过程。

import sympy as sp A = sp.Matrix([[1, 2, 1], [2, 1, 3], [1, 1, 1]]) b = sp.Matrix([7, 8, 3]) # 构造增广矩阵并化为简化行阶梯形 aug = A.row_join(b) rref_matrix, pivot_columns = aug.rref() print("简化行阶梯形:") print(rref_matrix) print("主元列:", pivot_columns)

这里有几个要点说明。row_join是把向量 (b) 拼到矩阵 (A) 右侧形成增广矩阵,rref()返回两个结果:第一个是化简后的矩阵,第二个是主元所在的列索引。主元列的含义是“哪些未知量是主变量、哪些是自由变量”,当主元列数小于未知量数时,说明方程组有自由变量,也就是无穷多解。

如果你不想看完整行阶梯形,只想知道方程组的解集,可以直接用sp.linsolve,但那就跳过了消元过程。我建议你至少前五道题用rref()去看主元列,因为这本书后续讨论秩、列空间和零空间的维度时,用的正是主元列这个概念。把这一步做熟了,后面几章会顺很多。

3.2 把特征值章节变成一次Matplotlib可视化

特征值和特征向量是这本书前后半程的分水岭。课本里会教你解特征多项式 (|A-\lambda I|=0),然后代回求特征向量。问题是手算出来的特征向量你根本不知道它长什么样。这时候就该让matplotlib上场了,把矩阵对单位圆的变换画出来,你一眼就能看出特征向量的方向。

import numpy as np import matplotlib.pyplot as plt A = np.array([[2.0, 1.0], [1.0, 2.0]]) theta = np.linspace(0, 2*np.pi, 200) circle = np.column_stack([np.cos(theta), np.sin(theta)]) # 矩阵左乘圆上的每个点,观察圆的变形 transformed = circle @ A.T eigvals, eigvecs = np.linalg.eig(A) print("特征值:", eigvals) print("特征向量(列向量):") print(eigvecs) plt.figure(figsize=(6, 6)) plt.plot(circle[:, 0], circle[:, 1], label="原始单位圆") plt.plot(transformed[:, 0], transformed[:, 1], label="变换后的圆") for i in range(2): v = eigvecs[:, i] * eigvals[i] plt.arrow(0, 0, v[0], v[1], head_width=0.1, color="red", alpha=0.7) plt.axis("equal") plt.legend() plt.show()

这个例子的关键是circle @ A.T。因为circle是 (200 \times 2) 的坐标点矩阵,要计算 (A \mathbf{x}),列向量视角下应该把每个点当列向量,但这里按行存储了,所以右乘A.T才等于对每个行向量做变换。这个转置是新手最容易写错的地方。np.linalg.eig返回的特征向量是按列排列的,eigvecs[:, i]取第 (i) 个特征向量,乘上对应的特征值后,画出的箭头正好落在变换后圆的极值方向上。

你运行一次就会看到:特征向量方向上的点在变换后只被拉伸或压缩,方向不变。这个几何画面,是手算十道题都换不来的直觉。这本书后面讲对角化和二次型时,反复用到的就是“沿着特征向量的方向看,变换只是缩放”。

3.3 最小二乘与SVD:把书末的数值方法跑通一遍

很多读者发现这本书越往后越“数值化”:最小二乘、QR分解、奇异值分解、伪逆。这些内容学起来容易迷失在公式里,但其实代码只有几行。一个比较典型的落地方式是拿一组带噪声的实验数据,用最小二乘拟合一条直线,然后用SVD看看这个欠定/超定系统的秩。

import numpy as np # 模拟实验数据:y = 2.5x + 1 加上噪声 rng = np.random.default_rng(42) x = np.linspace(0, 10, 20) y = 2.5 * x + 1 + rng.normal(0, 0.8, size=x.shape) # 构造设计矩阵,带截距项 X = np.column_stack([x, np.ones_like(x)]) # 线性代数里的标准最小二乘解:A^T A c = A^T b c, _, _, _ = np.linalg.lstsq(X, y, rcond=None) print("拟合系数:斜率=%.3f, 截距=%.3f" % (c[0], c[1])) # 再来一遍SVD,看奇异值分布 U, s, Vt = np.linalg.svd(X, full_matrices=False) print("奇异值:", s) print("条件数:", s[0] / s[-1])

这里要解释lstsq和rcond的作用。lstsq返回四个值:解、残差、矩阵的秩、奇异值。rcond=None表示让numpy根据机器精度自动决定哪些小奇异值被当作零处理,在列不满秩时这个参数直接决定解的行为。我算出的斜率约2.5、截距约1,说明即使加了噪声,最小二乘也能还原出真实参数。

用SVD看设计矩阵 (X) 的奇异值,你会发现两个奇异值都远大于零,条件数(最大奇异值除以最小奇异值)接近几十。条件数这个概念,正是这本书后半部分反复强调的“数值稳定性”的量化指标:条件数越大,(A^T A) 对 (y) 的微小变化越敏感。你可以在代码里把x改成np.linspace(0, 1, 20),截距项和斜率列的相关性变高,条件数立刻变大,你会发现拟合结果开始抖动。这就是数值线代不只在书里,更在数据里。

4. 自学这5个坑,我踩了其中3个:问题与排查

4.1 用数值浮点结果去核对符号习题,结果对不上

这是一个极其常见的问题。课本习题的答案经常是 (1/3) 或 (\sqrt{2}/2),你用numpy算出来是0.33333333或0.70710678。如果你直接拿==比较,永远对不上;更麻烦的是你可能会误以为是自己算错了,浪费大量时间排查。

原因:计算机浮点数是二进制近似表示,能精确表示 0.5 但不能精确表示 0.1 和 (1/3)。这是所有数值计算的基本约束,不是bug。

解决:判断数值结果是否和符号答案一致时,用误差容忍判断,不要用相等判断。代码里写np.isclose(x, 1/3, atol=1e-6),或者在核对分数答案时直接用sympy的符号计算。我的习惯是:手算推导用sympy,大规模数值计算用numpy,两者混用前先把数制心里过一遍。

4.2 特征向量方向判反:特征值对了但向量对不上

用np.linalg.eig解出的特征向量,可能和课本答案相差一个负号。比如课本写特征向量是 ((1, 1)^T),你的代码输出是 ((-1, -1)^T)。你会怀疑是不是矩阵输错了,但特征值明明是对的。

原因:特征向量允许任意非零缩放,若 (v) 是特征向量,则 (-v) 同样是特征向量。数值求解器返回的方向取决于内部的归一化策略,没有義務和课本保持一致。

解决:核对结果时不要直接比较向量分量,而是比较“方向”:把两个向量的点积取绝对值并归一化,如果约等于1,说明是同一个方向;或者干脆让第一个非零元素统一变正号,做一次规范化对齐。附录里也要提醒自己:让你的解和课本答案不同,并不等于做错。

4.3 跳过几何解释,第三遍回来补课

很多人学这本书时觉得“代数推导已经懂了,几何图不重要”,于是看到向量空间部分直接跳图、只背定义。结果学到内积空间和正交投影时,完全想不通“为什么投影向量要这么算”。这时候再回头补几何直觉,等于多学了一遍。

原因:这本书的应用章节大量依赖几何直觉,比如最小二乘的几何意义是“把 (b) 投影到列空间上”,奇异值分解的几何意义是“旋转-缩放-再旋转”。跳过几何图,你记住的是公式而不是机制。

解决:每学完一章,至少把该章的示意图在草稿纸上自己画一遍。尤其是“列空间与零空间正交补”的概念,画一个三维空间里的平面和法向量,比读十遍定理都管用。如果你懒得画,就用第3章的matplotlib方式把变换画出来,效果一样。

4.4 MATLAB实验题没有环境,整章习题卡住

这本书的不少章节末尾配有MATLAB实验题,很多自学者卡在“没装MATLAB”这一步,连带放弃整章的数值实验题。其实这些题目的核心思想是把本章概念用代码验证,而MATLAB只是载体之一。

原因:MATLAB是商业软件,个人安装需要许可证,很多人因此不愿意再用它做题。

解决:对绝大多数实验题,可以用numpy或scipy完成替代。MATLAB的rref对应numpy.linalg.matrix_rank加sympy.Matrix.rref,eig对应numpy.linalg.eig,svd对应numpy.linalg.svd,你需要的时候几乎都能找到对应函数。如果题目指定要用MATLAB,也可以安装Octave,它的语法兼容大部分MATLAB脚本,命令行跑一遍就能出结果。

4.5 同时在读多本教材,记号混乱

不少朋友习惯“一本不懂就换另一本”,比如同时打开Strang的网课和这本书。前期确实是互补,但到了特征值部分就出问题:Strang用 (A\mathbf{x} = \lambda \mathbf{x}) 并强调特征向量空间,这本书则会引入不变子空间和广义特征向量的记号。两套记号来回切换,很快你就搞不清哪个是对角化的充要条件了。

原因:不同教材对同一个概念的引入顺序和记号约定不同,有的用 (\lambda) 表示特征值,有的用 (\sigma) 表示奇异值,到了复数域写法更不一样。这不是理解力问题,是切换成本问题。

解决:确定一本作为主线教材,另一本只作参考,不要同步推进。我的做法是:主线学这本书,遇到模糊的概念再去查Strang对应的章节,查完立刻回到主线做习题。如果两本书对同一概念说法不一致,以主线教材为准,并在书边标注出另一本的叫法。

5. 和Strang、Axler、Lay相比怎么选:不同目标配不同教材

5.1 四本经典教材的定位差异

经常有人问:Linear Algebra with Applications 10th、Gilbert Strang的《Introduction to Linear Algebra》、Sheldon Axler的《Linear Algebra Done Right》、David Lay的《Linear Algebra and Its Applications》有什么区别?要说清楚这个问题,得先看每本书是怎么引入“线性代数核心”的。核心其实就一个:研究向量空间和线性映射,但四本书的进入角度完全不同。

Strang走的是“直觉先行”路线,开篇就从几何向量和线性组合讲起,强调四个基本子空间,强调“线性代数是认识世界的一种视角”。读起来非常舒服,但有些定理证明略过,适合建立宏观图景。

Axler走的是“抛开行列式”路线,它反直觉地宣称行列式这个传统工具被过度强调了,从头用线性映射和算子的角度重新构建理论,证明严密且优美,但对应用场景着墨极少,适合数学系学生。

Lay走的是“教学法优先”路线,例子丰富、习题梯度合理,大量图解和渐变引入,适合工科生按部就班自学。

这本书(Leon 第10版)则显得更“工程化”:大量篇幅给到线性方程组的数值解法、特征值的计算算法、实际应用建模,而且每一处理论都配有可落地的应用场景。它不像Strang那样强调俯视全貌,但让你学完就能动手解决问题。

5.2 按目标选书:考研、机器学习、工程应用怎么配

如果你的目标是考研数学线代部分,我个人建议以这本书为主干,配一本习题集做刷题。考研题目偏向计算熟练度和对秩、特征值、二次型的掌握,这本书对这三块都有足够的例题和练习量,不会出现“概念都会但题不会做”的断裂感。

如果你的目标是入门机器学习和数据科学,那更推荐以Strang为主,搭配这本书的SVD和最小二乘章节重点阅读。机器学习的理论推导大量依赖向量投影和奇异值分解,Strang的直觉能帮你理解“为什么这么做”,再用这本书把数值算法落到代码上。

如果你的目标偏向工程应用,比如信号处理、控制理论、计算力学,那直接把它当主教材完全够用。应用章节覆盖了电路、经济、机械振动、马尔可夫链等经典工程场景,跟着做一遍基本就能把线代和实际系统对接起来。

目标场景主线教材建议配套
考研/系统学基础Leon第10版一本真题或习题集
ML/DL理论入门StrangLeon的第6、7、9章
数学系/理论深造AxlerLeon的数值方法章节作应用补充
工程应用快速上手Leon第10版numpy+matplotlib做课后实验

5.3 推荐的混合阅读方案:先画地图再深入

如果你时间有限,我不建议四本书从头到尾都读。更实际的做法是:用这本书的目录当“地图”,先通读前3章建立矩阵和线性方程组的基础,然后跳到Strang的第4章看四个子空间的宏观视角,再回到这本书学特征值和SVD。这样做的逻辑是:这本教材的章节顺序偏向应用和算法,而Strang提供的图形化视角能帮你把每个算法的位置安放好。

选定主线之后,每一章只做三件事:读概念、做例题、用代码验证定理。不要一开始就追求把所有证明逐行推完,只把结论记住并在代码里验证一次,等第二轮再回头补证明。这个策略对自学最友好,因为第一轮的目标是建立“会算、会用、知道什么情况选什么工具”,证明的细节留到有需要时再补。

6. 把一个动作养成习惯:每章学完,把习题数据换掉重算一遍

最后一件事是我自己交了不少学费换来的教训:不要只做书上原样的题目。书上的数据是精心设计的,算出来往往正好是整数或简单分数,这给了你一种虚假的掌控感。真正检验你有没有学会,是换一组不好看的数据,比如把课本例题里的矩阵改成随机生成的矩阵,再用手算或代码做一遍。

具体做法是:每学完一章,从该章的课后习题里选3道题,然后把题目里的所有数字换成随机数。比如课本解一个 (3\times 3) 线性方程组,你就用rng.integers生成一个随机矩阵和随机右端向量,重新做一遍消元。你会发现很多在整数数据里被隐藏的问题——主元特别小导致消元不稳定、矩阵接近奇异导致解对舍入误差极度敏感——全都会暴露出来。这就是数值线代对你第一轮学习的最好检验:能用代码算出结果不算懂,能预判“这个结果可不可信”才算懂。

我会在每一章的页边写一行小字:“如果我把这里的3换成0.01,结果会怎样?”然后把答案验证一遍。这个习惯帮我提前踩掉了无数坑:最小二乘设计矩阵的条件数变差、特征值对扰动敏感、高斯消元遇到接近零的主元。当你养成这个习惯后再回头看这本Linear Algebra with Applications 10th,你会在书里发现很多以前没注意到的细节——比如那些应用章节的案例,本质上都在提醒你同一个道理:数据一变,算法和理论之间那条缝隙就露出来了。希望帮到你。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询