很多学线性代数的人都有过这种经历:课上老师推导黑板上密密麻麻的符号,作业里手算三阶矩阵的逆,考试前背特征多项式和克拉默法则。考试能过,但当手里真的有一批数据、一个方程组、一个需要判断“矩阵是否病态”的工程问题时,突然发现自己不知道怎么把纸上的数学变成能跑起来的结果。
这个问题的本质不是“线性代数没有用”,而是我们太习惯用“手工计算”的方式去理解线性代数,却很少用“程序语言”的方式去看它。实际上,线性代数是一套描述数据关系、空间变换和系统状态的语言,而这种语言最好的落地载体之一,就是 MATLAB。
这篇文章是“大谦MATLAB:线性代数”系列里的基础篇,目标是把线性代数最核心的概念和 MATLAB 命令一一对应起来。读完以后,你能完成四件事:创建矩阵并做基本运算;用矩阵求解线性方程组;计算特征值和特征向量;把向量和线性变换画成图。更重要的是,我会把那些新手最容易踩的坑一起讲清楚,比如什么时候不该用inv、为什么det很小不代表矩阵一定不可用。
如果你正在学线性代数,准备数学建模,或者在自动控制、图像处理、数据分析这类方向刚起步,这篇文章会给你一份可以直接照着敲的 MATLAB 线性代数速通手册。
1. 这篇文章真正要解决的问题
先做一个直接的判断:MATLAB 是目前学习线性代数概念时“反馈感”最强的工具之一。
原因是 MATLAB 这门语言的设计起点就是矩阵。它不像 C 语言那样要先写双重循环才能做矩阵乘法,也不像 Python 里需要先import numpy才能把“数组”当成“向量”来用。在 MATLAB 里,矩阵是第一等公民,打开软件输入一行代码就能看到结果,这个“即时反馈”对建立空间直觉非常重要。
这篇文章要解决的问题,是三个非常具体的痛点:
第一个痛点是“数学符号不知道对应什么操作”。你看到A^T、|x|、det(A)、λ这些符号时,知道它们代表转置、范数、行列式和特征值,但不太确定在 MATLAB 里用什么函数、什么语法去表达。
第二个痛点是“能手动算但不会用代码解”。三阶以下矩阵你还能手算,但一旦到了五阶、十阶,或者矩阵里是浮点数,手算根本不现实。你需要知道 MATLAB 里x = A \ b和x = inv(A) * b的区别,以及什么场景应该用哪一行。
第三个痛点是“计算结果没有直觉判断力”。代码运行后得到一个特征值列表,但这组数字到底在说什么?矩阵变换之后图形变成什么样?这些问题需要可视化来帮助理解,而不是只看一个数字。
所以这篇文章不只是给你一堆命令,还会告诉你这些命令背后的数学含义、适用边界和常见陷阱。学完之后你再遇到“解一个线性系统”“判断矩阵是否可逆”“找出数据变化的主方向”这类问题,会有一个清晰的操作路径。
2. 为什么用 MATLAB 学线性代数:三种方式对比
在进入代码之前,先花点时间回答一个很多人纠结的问题:学线性代数,用手算、用 Python、还是用 MATLAB?
我的观点是:要建立几何直觉和快速验证,MATLAB 是目前最省事的工具。这不是说 Python 不行,而是说 MATLAB 的交互方式更贴合“边算边看”的学习过程。
先说手算。手算的好处是能理解运算过程,比如按行展开计算行列式、高斯消元解方程组。但它的缺点也很明显:只能处理低阶矩阵,容易出错,而且完全无法建立“矩阵是变换”这种几何直觉。你算完一个四阶行列式,得到的只是一个数,但你不知道这个数在空间中代表什么。
再说 Python 配合 NumPy。NumPy 的性能很强,生态也很丰富,但学习线性代数时,你需要先处理“数组维度”“广播机制”“np.dot和np.matmul的区别”这类额外的语言概念。如果你本来就在学 Python,那用 NumPy 完全合理;但对于只想快速验证线性代数概念、或者数学建模刚入门的同学,MATLAB 的语法更接近数学语言的书写习惯。
最后说 MATLAB。它有几个对线性代数学习特别友好的特性:
- 所有变量本质都是矩阵,
[1 2 3]和[1; 2; 3]直接就有行列语义,不需要区分“数组”和“矩阵”。 - 内置了大量线性代数函数:
transpose、det、rank、inv、eig、svd,不需要额外安装包。 - 自带强大的可视化函数,
plot、quiver、plot3可以快速把向量和变换画出来。 - 命令窗口交互式执行,输入一行命令立刻看到结果,特别适合“如果我把矩阵改一下,特征值会怎么变”这种探索式学习。
下面用一张表总结它们的差异:
| 对比维度 | 手算 | Python + NumPy | MATLAB |
|---|---|---|---|
| 矩阵乘法表达 | 逐项手算 | np.dot(A, B) | A * B |
| 解线性方程组 | 高斯消元 | np.linalg.solve(A, b) | A \ b |
| 特征值计算 | 特征多项式 | np.linalg.eig(A) | eig(A) |
| 可视化 | 无 | matplotlib需额外配置 | quiver、plot直接用 |
| 学习曲线 | 低,但只适合低阶 | 中等,需先学语言 | 较低,语法贴近数学 |
| 适合场景 | 理解运算过程 | 工业级数据处理 | 概念验证和数学建模 |
这里要强调一下,我说“MATLAB 适合学线性代数”,不等于“只在 MATLAB 里学数学”。你在 MATLAB 里看到的特征值、奇异值、矩阵分解这些概念,和数学教材里是完全一致的,换到 Python 或者 Julia 里只是换个函数名,思想没有变。所以放心用 MATLAB 做验证,之后再去接触其他工具,概念是通用的。
3. 环境准备与前置条件
接下来进入实操。第一步是准备好 MATLAB 环境。
先说版本。本文所有代码都使用 MATLAB 的基础语法,不依赖任何特定工具箱,所以在常见版本中都可以直接运行。如果你用的是学生版、教育版或者学校的机房版本,也没有关系,下面这些命令都内置在 MATLAB 核心环境里。由于不同大版本的界面布局略有差异,本文重点演示通用操作思路,版本细节请以你自己机器上的实际版本为准。
安装完成后,建议做两件事:
- 在主界面的“命令行窗口”里输入
ver,确认 MATLAB 能正常启动,并看到版本信息。 - 输入
doc,打开帮助文档界面,后续查找函数用法时可以快速查证。
如果你刚接触 MATLAB,还需要先理解两个最基本的操作:
第一个是“分号抑制输出”。在命令行里输入a = 1并按回车,MATLAB 会立刻显示a = 1。如果输入a = 1;,就不会显示任何输出。写脚本时,如果不加分号,程序运行后窗口会被大量中间结果刷屏。所以一个非常通用的习惯是:在语句结尾加英文分号,想查看某个变量的值时就单独输入变量名。
第二个是“行内注释”。注释用百分号%开头,它后面的内容不会被 MATLAB 执行。示例代码中出现的%注释,你自己动手时可以直接复制,也可以改成自己的说明文字。
另外,我建议不要只在命令窗口里敲命令。更好的做法是新建一个脚本文件:
% 文件路径:demo_basic.m A = [1 2; 3 4]; % 创建一个 2x2 矩阵 disp(A); % 在命令窗口显示矩阵 A新建脚本的方式是:点击主页选项卡里的“新建脚本”,或者直接按快捷键Ctrl+N,然后把代码粘贴进去,保存为.m文件,最后点击“运行”按钮。用脚本文件的好处是你随时可以修改参数重新运行,不会因为命令窗口里的历史记录太多而找不到之前的操作。
4. 核心概念与 MATLAB 对应命令
这一节把线性代数的核心概念和 MATLAB 命令做一个对应表。这些概念是后面所有代码的基础,所以我会先简单解释数学含义,再给出命令和一个小例子。
4.1 矩阵与向量
线性代数中的“矩阵”就是一个按矩形排列的数表。向量可以看成只有一列或一行的特殊矩阵。MATLAB 里创建矩阵非常直接:
A = [1 2 3; 4 5 6; 7 8 9]; % 3 行 3 列矩阵 v = [1; 2; 3]; % 列向量 w = [1, 2, 3]; % 行向量这里的规则是:同一行元素用空格或逗号分隔,不同行用分号分隔。注意分号一定是英文输入法下的分号,而不是中文全角分号。
4.2 转置、内积与范数
转置就是矩阵行列互换,数学符号是A^T。在 MATLAB 里用单引号A'表示。
列向量和行向量的内积(也叫点积)可以用dot(v, w)计算。范数表示向量长度,用norm(v)计算,默认是二范数,也就是向量各分量平方和的平方根。
A = [1 2; 3 4]; disp(A'); % 转置结果 v = [1; 2]; w = [3; 4]; disp(dot(v, w)); % 内积 = 1*3 + 2*4 = 11 disp(norm(v)); % 长度 = sqrt(1^2 + 2^2) = 2.23614.3 线性方程组
线性代数里最经典的题目就是解线性方程组,写成一式就是:
A * x = b
其中A是系数矩阵,b是常数向量,x是未知数向量。MATLAB 解这类方程组最标准的写法是:
x = A \ b;这里用到的运算符是“左除”\。它的数学含义是“从左边解A乘以x等于b”。对应的,还有“右除”/,但实际使用频率低很多,主要在求解x * A = b这种形式时才用。
左除A \ b和inv(A) * b在数学上等价,但实际结果可能差别很大。原因我放在后面的最佳实践章节详细说,这里先记住结论:解线性方程组优先用\,不要用inv。
4.4 行列式、秩与条件数
行列式det(A)是一个标量,常用于判断矩阵是否可逆,或者计算体积变化比例。但对计算机来说,det并不适合直接用来判断数值上的“是否可逆”,因为浮点计算下det非常接近 0 并不能严格说明矩阵奇异。
矩阵的秩rank(A)表示矩阵线性无关的行或列的数量。满秩的方阵才是可逆的。
条件数cond(A)衡量矩阵对误差的敏感程度。条件数越大,说明方程组越“病态”,小扰动会带来大误差。
A = [1 2; 2 4]; disp(det(A)); % 结果很接近 0,矩阵秩为 1 disp(rank(A)); % 1 disp(cond(A)); % Inf 或极大值,说明矩阵接近奇异这个例子里的矩阵两行成比例,是一个不可逆矩阵。从rank和cond上看非常明显,但从det的数字上反而不直观。
4.5 特征值与特征向量
特征值和特征向量是线性代数里最容易被考试“考糊”但实际应用最广的概念之一。
定义是这样:对于矩阵A,如果存在一个非零向量v和一个实数(或复数)λ,满足:
A * v = λ * v
那么λ是矩阵A的特征值,v是对应于λ的特征向量。
在 MATLAB 里用eig函数:
A = [2 1; 1 2]; [V, D] = eig(A);结果中V的每一列是一个特征向量,D是一个对角矩阵,对角线上的元素就是特征值。
关于特征向量的一个重要直觉是:当矩阵作用于特征向量时,结果向量的方向不变,只是长度按特征值的比例缩放。如果特征值是 2,向量会被拉长一倍;如果特征值是 -1,方向会反向。这个直觉用可视化最容易理解,我会在第 6 节里给出完整代码。
4.6 矩阵运算的注意事项
MATLAB 中矩阵乘法A * B是标准的线性代数乘法,要求A的列数等于B的行数。如果你想做“对应元素相乘”,需要用点乘操作符.*,这也是新手最容易搞混的地方。
A = [1 2; 3 4]; B = [1 1; 1 1]; C1 = A * B; % 矩阵乘法 C2 = A .* B; % 对应元素相乘这两者结果完全不同。矩阵乘法关心行列之间的组合关系,对应元素相乘只是普通投影运算。后面的代码示例中,如果看到*和.*,一定要分清它们的使用场景。
5. 完整示例:从矩阵运算到线性方程组求解
下面用两个实际场景把前面讲的概念串起来。第一个场景是“创建矩阵并做基本运算”,第二个场景是“解一个真实的线性方程组”。
5.1 示例一:矩阵创建与基本运算
新建一个脚本文件demo_matrix_ops.m,输入以下代码:
% 文件路径:demo_matrix_ops.m A = [1 2; 3 4]; B = [5 6; 7 8]; fprintf('A + B:\n'); disp(A + B); fprintf('矩阵乘法 A * B:\n'); disp(A * B); fprintf('A 的转置 A'':\n'); disp(A'); v = [1; 2]; fprintf('向量 v 的二范数: %.4f\n', norm(v)); fprintf('向量 v 所有分量的平方和: %.4f\n', v' * v);运行脚本后,你会看到类似这样的输出(不同版本小数位数可能有差异):
A + B: 6 8 10 12 矩阵乘法 A * B: 19 22 43 50 A 的转置 A': 1 3 2 4 向量 v 的二范数: 2.2361 向量 v 所有分量的平方和: 2.2361这里要注意一个容易看错的地方:代码里A'表示矩阵转置,但因为转置符号在字符串中间出现了,所以写成了A''来打印一个带单引号的字符串。这段代码的核心逻辑是比较norm(v)和v' * v,它们数值相等,说明向量二范数的定义恰好是向量与自身内积的平方根。通过这样一个最小示例,你就把“矩阵运算”“转置”“内积”“范数”这几个概念全部跑通了。
5.2 示例二:解线性方程组
第二个场景是解一个线性方程组。假设有一个系统满足:
2*x1 + x2 = 5 x1 + 3*x2 = 6把它写成矩阵形式就是:
A = [2 1; 1 3];b = [5; 6];
新建脚本demo_linear_system.m:
% 文件路径:demo_linear_system.m A = [2 1; 1 3]; b = [5; 6]; % 方法一:左除(推荐) x1 = A \ b; % 方法二:inv 矩阵求逆(不推荐) x2 = inv(A) * b; fprintf('左除结果 x1:\n'); disp(x1); fprintf('inv 结果 x2:\n'); disp(x2); fprintf('残差范数 norm(A*x1 - b): %.6e\n', norm(A * x1 - b)); fprintf('残差范数 norm(A*x2 - b): %.6e\n', norm(A * x2 - b));预期输出是:
左除结果 x1: 1.8000 1.4000 inv 结果 x2: 1.8000 1.4000 残差范数 norm(A*x1 - b): 0.000000e+00 残差范数 norm(A*x2 - b): 0.000000e+00解释一下:
x1 = A \ b是 MATLAB 推荐的方式,它会根据矩阵的数值性质自动选择合适算法。x2 = inv(A) * b理论上结果一样,但多算了A的逆矩阵,计算量更大,数值稳定性也更差。在大型矩阵中,这种差异会非常明显。- 残差
norm(A*x - b)用来衡量求解精度。理想情况下它应该是 0,由于浮点运算的限制,它会是一个很小的数,比如1e-16量级。如果残差很大,说明代码里矩阵或向量写错了。
这里的判断技巧是:只要残差在1e-10以下,就可以放心认为求解成功。如果残差达到0.1或者更大,优先回头检查A和b的输入是否有维度或符号错误。
6. 完整示例:特征值与特征向量的计算与验证
特征值和特征向量是 MATLAB 线性代数应用的高频区域,很多实际问题最后都会落脚到“求一个矩阵的特征向量”。下面通过一个对称矩阵例子演示完整流程。
6.1 用 eig 计算特征值和特征向量
新建脚本demo_eig.m:
% 文件路径:demo_eig.m A = [2 1; 1 2]; % 方式一:只返回特征值向量 lambda = eig(A); fprintf('特征值:\n'); disp(lambda); % 方式二:同时返回特征向量矩阵 V 和特征值对角矩阵 D [V, D] = eig(A); fprintf('特征向量矩阵 V(每列是一个特征向量):\n'); disp(V); fprintf('特征值对角矩阵 D:\n'); disp(D); % 验证第一个特征向量的性质 lambda1 = D(1, 1); v1 = V(:, 1); lhs = A * v1; rhs = lambda1 * v1; fprintf('第一个特征值: %.4f\n', lambda1); fprintf('A*v1 与 lambda1*v1 的最大误差: %.6e\n', max(abs(lhs - rhs)));运行结果会类似:
特征值: 1 3 特征向量矩阵 V(每列是一个特征向量): -0.7071 0.7071 0.7071 0.7071 特征值对角矩阵 D: 1 0 0 3 第一个特征值: 1.0000 A*v1 与 lambda1*v1 的最大误差: 2.220446e-16这段代码有几个重要细节:
[V, D] = eig(A)中D的对角线是特征值,V的列是对应的特征向量。特征向量矩阵的每一列需要和特征值一一对应,不要看错行列。- 验证
A*v1 = λ1*v1时,误差在1e-16量级,这是浮点运算的正常表现,完全可以认为等式成立。 - 如果
A是不对称矩阵,特征值可能是复数,eig也能返回复数结果,此时特征向量的元素也会出现虚部,这是正常的。
6.2 用图像理解特征向量的“方向不变性”
只看数字还不够“线性代数”。下面这段代码会把特征向量的方向画出来,可以直观看到当矩阵作用到特征向量上时,结果向量的方向保持不变。
% 文件路径:demo_eig_visual.m A = [2 1; 1 2]; [V, D] = eig(A); v1 = V(:, 1); v2 = V(:, 2); % 计算变换后的向量 Av1 = A * v1; Av2 = A * v2; figure; hold on; % 原始特征向量(实线) quiver(0, 0, v1(1), v1(2), 0, 'b', 'LineWidth', 2); quiver(0, 0, v2(1), v2(2), 0, 'r', 'LineWidth', 2); % 变换后的向量(虚线) quiver(0, 0, Av1(1), Av1(2), 0, 'b--', 'LineWidth', 2); quiver(0, 0, Av2(1), Av2(2), 0, 'r--', 'LineWidth', 2); grid on; axis equal; xlim([-2 2]); ylim([-2 2]); legend('特征向量 v1', '特征向量 v2', 'A*v1', 'A*v2', 'Location', 'best'); title('特征向量的方向在矩阵变换后保持不变');运行这段代码后,你会看到两个特征向量的实线箭头和它们变换后的虚线箭头分别重叠在两条直线上。蓝色和红色虚线只是把实线等比拉长了,方向没有改变。这就是特征向量“方向不变”的几何意义。
这里用到了quiver函数,它的基本语法是:
quiver(x, y, u, v);其中(x, y)是箭头起点,(u, v)是箭头方向向量。第 5 个参数0表示禁止 MATLAB 自动缩放箭头,这样代码中给出的长度就是真实长度。如果你不做这个设置,quiver 默认会把所有箭头缩放到差不多的长度,就看不出“拉长”效果了。
7. 完整示例:用向量可视化理解线性变换
特征值只是一个方面,线性代数的另一个核心思想是“矩阵是一个线性变换”。一个矩阵可以把平面里的点拉伸、旋转、剪切或压缩。理解这个思想,比死记硬背矩阵乘法规则有用得多。
下面这段代码演示一个最简单的剪切变换。矩阵A = [1 0.5; 0 1]的作用是:保持y坐标不变,但把x坐标加上0.5 * y的偏移。
% 文件路径:demo_transform_visual.m v = [2; 1]; A = [1 0.5; 0 1]; w = A * v; figure; hold on; quiver(0, 0, v(1), v(2), 0, 'b', 'LineWidth', 2); quiver(0, 0, w(1), w(2), 0, 'r', 'LineWidth', 2); grid on; axis equal; xlim([0 3]); ylim([0 3]); legend('原始向量 v', '变换后向量 A*v', 'Location', 'best'); title('矩阵 A 对向量 v 的线性变换');运行后你能直观看到,蓝色的原始向量方向在y方向没有变化,但到了红色的变换后向量,x方向被“推”了一下。这个可视化过程,就是线性变换的几何意义。
顺着这个思路继续走一步。如果你想看整个平面如何被矩阵变换,可以画一个单位正方形的变换效果:
% 文件路径:demo_transform_square.m sq = [0 0 1 1 0; 0 1 1 0 0]; A = [1 0.5; 0 1]; sqA = A * sq; figure; hold on; plot(sq(1, :), sq(2, :), 'b-o', 'LineWidth', 2); plot(sqA(1, :), sqA(2, :), 'r-o', 'LineWidth', 2); grid on; axis equal; xlim([-0.5 2]); ylim([-0.5 2]); legend('原始正方形', '变换后图形', 'Location', 'best'); title('矩阵 A 对单位正方形的线性变换');这里把正方形的四个顶点拼成一个2×5矩阵sq,每一列是一个顶点的坐标。用矩阵A去乘sq,等于同时对四个顶点做变换。结果显示出来的红色图形是一个被剪切的平行四边形,这就是“矩阵是线性变换”的直观证据。
这两个可视化示例并不复杂,但非常值得自己动手跑一遍。它们能帮你在脑子里建立一种“看到矩阵就去想空间变换”的本能,这种本能对后续学习主成分分析、控制系统状态空间、图像仿射变换等应用非常有帮助。
8. 常见问题与排查思路
在实际学习和使用中,最容易卡住你的往往不是数学概念,而是一些看起来很小的问题。下面整理了一张排查表,建议收藏备用。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
运行inv(A)*b报告矩阵必须为方阵 | 矩阵不是方阵或者写错了尺寸 | 用size(A)、size(b)检查维度 | 确认方程组Ax=b是否真的方阵,或改用左除\ |
| 矩阵结果显示太长,窗口刷屏 | 语句末尾没有加分号 | 检查脚本中是否漏掉; | 在语句末尾加英文分号,需要看值就单独输入变量名 |
eig结果顺序和教材不一致 | eig不保证特征值排序 | 查看diag(D)的排序方式 | 按需求用sort或max提取特征值,不要依赖固定顺序 |
det(A)很接近 0 但求解仍有警告 | 矩阵接近奇异,但det判断不可靠 | 查看cond(A)、rank(A) | 优先使用cond和rank判断,对病态矩阵考虑pinv |
A*x和b相差很大 | 左除和右除用反了 | 检查A*x与b的矩阵乘法维数 | 明确Ax=b用左除x = A \ b |
| 变量名和 MATLAB 内置函数冲突 | 用了eig、det等做变量名 | 输入which eig查看解析结果 | 避免用内置函数名作为变量名,例如改用my_eig |
| 输入代码后报错提示中文符号 | 标点符号用了全角 | 查看报错位置附近是否有中文逗号、分号 | 切换英文输入法,检查所有分号和引号 |
| 大型矩阵运算非常慢 | 循环里反复创建变量或使用符号计算 | 用profile分析代码耗时 | 用数值矩阵代替符号矩阵,使用向量化操作,或预分配数组 |
下面针对几个最常见的问题,再展开说一下排查思路。
8.1 关于det(A)判断矩阵是否可逆
很多教材里说“行列式等于 0,矩阵不可逆”。这句话在理论上是对的,但在计算机浮点数环境里要小心。由于浮点误差,一个本来可逆的病态矩阵,它的det可能只是一个非常小的数,比如1e-20。如果你只用det判断,会误以为矩阵不可逆。
更稳妥的做法是看条件数cond(A)。条件数越大,矩阵对误差越敏感。如果cond(A)是Inf,说明矩阵精确奇异;如果cond(A)是一个大于1e15的数,说明矩阵已经非常病态,求解结果可能不可信。
8.2 关于\和inv的选择
解Ax = b时,x = A \ b和x = inv(A) * b在数学上等价,但数值上差别可能很大。原因是inv(A)需要显式求逆矩阵,这一步既增加计算量,也会放大浮点误差。而A \ b会采用高斯消元或其他数值更稳定的算法直接求解。
所以最佳实践非常简单:除非你明确需要A的逆矩阵作为中间结果,否则永远用\解线性方程组。
8.3 关于特征值顺序
eig返回的特征值顺序并不是固定的。对于同一个矩阵,不同版本的 MATLAB,或者同一版本中不同的调用方式,都可能得到不同顺序的特征值。因此,当你需要“最大的特征值”时,不要想当然认为D(1,1)就是最大值,而应该先提取diag(D),再用max或sort处理。
lambda = eig(A); max_lambda = max(real(lambda)); % 取实部最大的特征值9. 最佳实践与工程建议
到这里,你已经掌握了 MATLAB 线性代数的基础操作。但在实际项目里使用这些知识时,还有一些工程层面的建议值得记住。
9.1 解方程优先用左除,避免显式求逆
前面已经多次提到这一点,这里再强调一次。A \ b不仅速度快,数值稳定性也更好。不要把数学教材里的写法x = A^{-1} b直接翻译成x = inv(A) * b,在 MATLAB 里它的正确翻译是x = A \ b。
9.2 判断矩阵病态不要只看det
用cond(A)、rank(A)来辅助判断。特别是当你处理的矩阵来自真实数据(比如工程测量、图像特征)时,矩阵往往接近奇异,此时条件数比行列式更能反映求解风险。
9.3 用向量化代替循环
MATLAB 的for循环性能远不如向量化操作。比如对矩阵每一行求和,与其写循环,不如直接用sum(A, 2)。这不只是语法上的简写,而是 MATLAB 底层引擎针对矩阵运算做过多线程和性能优化,矩阵运算才是它的强项。
% 不推荐:用循环累加 s1 = 0; for k = 1:length(v) s1 = s1 + v(k); end % 推荐:直接用 sum s2 = sum(v);9.4 养成使用脚本文件的好习惯
命令行窗口适合临时验证,但如果你想复现一个结果,或者把计算过程分享给其他人,一定要用.m脚本。脚本里最好加上注释,说明矩阵的含义和求解目标。否则一周之后你打开自己写的脚本,可能完全想不起来当时的思路。
我常用的脚本结构是这样的:
% 文件路径:demo_linear_model.m % 功能:求解线性模型系数 % 作者:你的名字 % 日期:2025-XX-XX clear; clc; % 清空变量和命令窗口 A = [2 1; 1 3]; % 系数矩阵 b = [5; 6]; % 常数向量 x = A \ b; % 求解 disp(x);9.5 分号、注释、变量命名要规范
分号和注释直接关系到代码可读性。变量名尽量使用有意义的英文,比如不要用a、b、c这种没有语义的命名,而是用coeff_matrix、rhs_vector这类名字。这样不仅方便自己阅读,也方便别人接手。
9.6 不要忽略条件数与残差验证
在实际项目中,求解完成后一定要验证残差。这一步看起来多余,但能在早期发现很多隐蔽错误,比如矩阵符号写错、维度不匹配、数据读取顺序错误等。简单一行代码就能完成:
residual = norm(A * x - b);如果residual很大,先不急着分析结果,回头检查数据。
10. 总结与后续学习方向
这一篇文章已经把 MATLAB 线性代数的主线走了一遍:从矩阵创建和基本运算,到用左除求解线性方程组,再到特征值与特征向量的计算和验证,最后用可视化建立了“矩阵是空间变换”的直觉。每一个例子都可以直接复制运行,新手跟着做一遍,就能对 MATLAB 的矩阵思维有一个完整的体感。
接下来如果你想继续深入,有几个方向值得关注:
- 矩阵分解:LU 分解、QR 分解、奇异值分解(SVD)。SVD 在数据降维、图像压缩、推荐系统里出现频率极高。
- 数值线性代数:了解浮点误差、条件数、病态问题产生的原因,这会让你在工程中少踩很多坑。
- 线性代数的应用场景:主成分分析、最小二乘拟合、控制系统里的状态空间、图像处理里的仿射变换。这些方向都会用到今天讲的命令。
- MATLAB 自带工具箱:比如统计、优化、控制系统工具箱,它们底层都依赖矩阵运算。基础打牢以后,再上手工具箱会轻松很多。
建议你收藏这篇文章,把它当成一份可以随时查的速查手册。等真正开始做数学建模、图像处理或数据分析项目时,再回头看这里的示例,你会发现自己对线性代数的理解已经不再是“会考试”,而是“会用”了。这套“大谦MATLAB:线性代数”系列后续还会继续拆解更多专题,下一次遇到难题时,记得回来看看。