矩阵运算与向量化:MATLAB 的核心
基于进阶语言 · 核于 2026-08
速查
- 矩阵运算(无点号):
A * B(矩阵乘法)、A ^ 2(矩阵幂 A*A)、A'(共轭转置)、A \ B(左除,解 AX=B)、inv(A)(求逆)、eig(A)(特征值)——按数学规则作用于整个矩阵。 - 逐元素运算(点号 .):
A .* B(逐元素乘)、A .^ 2(逐元素平方)、A ./ B(逐元素除)——对应位置分别运算。点号是「逐元素」标志。 - 矩阵构造:
[1 2; 3 4](分号换行,空格/逗号分隔同行);zeros(m,n)/ones(m,n)/eye(n)(单位阵)/rand(m,n)快速构造。 - 索引从 1 开始:
A(1)是第一个元素;A(2,3)是第 2 行第 3 列;A(:,1)是第 1 列(:表示全部);A(1:3,:)是前 3 行所有列。 - 矩阵分解:
lu(A)(LU 分解)、qr(A)(QR 分解)、svd(A)(奇异值分解)、chol(A)(Cholesky 分解)——求解线性方程组、最小二乘、降维的基础。 - 线性方程组求解:
x = A \ b(左除,推荐,比inv(A)*b快且数值稳定);超定方程(最小二乘)也用\。 - 向量化替代循环:
sum(A)/mean(A)/max(A)/cumsum(A)/diff(A)等聚合函数直接作用于矩阵;A .* B替代逐元素循环。向量化快(底层 LAPACK/BLAS)且简洁。 - 数组预分配:循环前用
x = zeros(n,1)预分配,避免每次循环扩容数组(否则慢几个数量级)。 - 广播(Broadcasting):维度兼容时自动扩展(如矩阵每行加一个行向量
A + row),无需显式复制。
一、矩阵构造与索引
MATLAB 的矩阵构造用方括号,索引用圆括号(从 1 开始):
matlab
% 构造矩阵
A = [1 2 3; 4 5 6; 7 8 9] % 3×3 矩阵(分号换行)
v = [1 2 3 4 5] % 行向量(空格分隔)
col = [1; 2; 3] % 列向量(分号换行)
% 快速构造
Z = zeros(3, 4) % 3×4 全零矩阵
O = ones(2, 2) % 2×2 全一矩阵
I = eye(3) % 3×3 单位阵
R = rand(2, 3) % 2×3 均匀随机矩阵
n = 1:5 % [1 2 3 4 5](冒号生成序列)
m = 0:0.1:1 % [0 0.1 0.2 ... 1](步长 0.1)
% 索引(从 1 开始!)
A(1, 1) % 第 1 行第 1 列 = 1
A(2, :) % 第 2 行所有列 = [4 5 6]
A(:, 3) % 第 3 列所有行 = [3;6;9]
A(1:2, 2:3) % 子矩阵:前 2 行、2-3 列 = [2 3;5 6]
A(end, end) % 最后一行最后一列(end 表示末尾)- 索引从 1:这是 MATLAB(继承自 Fortran)与 Python/JS(从 0)最大的区别。
A(1)是第一个元素,没有A(0)(会报错)。 :是「全部」:A(:,k)是第 k 列全部行,A(k,:)是第 k 行全部列——切片的核心语法。end关键字:索引中end表示该维度的末尾,A(2:end, :)表示第 2 行到最后一行。
二、矩阵运算 vs 逐元素运算详解
matlab
A = [1 2; 3 4];
B = [5 6; 7 8];
% —— 矩阵运算(无点号)——
A * B % 矩阵乘法:[1*5+2*7, 1*6+2*8; 3*5+4*7, 3*6+4*8] = [19 22; 43 50]
A' % 转置(实数矩阵就是转置,复数是共轭转置):[1 3; 2 4]
A.^2 % 注意:A^2(无点)是 A*A 矩阵幂;A.^2 是逐元素平方
inv(A) % 求逆:[-2 1; 1.5 -0.5]
A \ B % 左除 = inv(A)*B,解 AX=B
eig(A) % 特征值
det(A) % 行列式
% —— 逐元素运算(点号)——
A .* B % 逐元素乘:[5 12; 21 32]
A ./ B % 逐元素除:[0.2 0.333; 0.429 0.5]
A .^ B % 逐元素幂:[1^5 2^6; 3^7 4^8]- 最容易犯的错:想逐元素相乘写成
A * B(矩阵乘法)。如果 A、B 维度不匹配矩阵乘法规则(A 列数 ≠ B 行数),会报错;如果恰好匹配但你要的是逐元素,会得到错误结果且不报错(隐蔽 bug)。 - 记忆:点号 = 逐元素。看到
.就想「对应位置分别算」。 - 标量与矩阵:标量运算无需点号(
2 * A是标量乘矩阵,每元素乘 2);A + 1每元素加 1。
三、矩阵分解与线性方程组求解
矩阵分解是数值计算的基石——求解线性方程组、最小二乘、特征值问题都靠它:
matlab
A = [4 3; 6 3];
b = [10; 12];
% 解线性方程组 Ax = b(推荐用左除 \)
x = A \ b % [2; 0.667],比 inv(A)*b 快且稳定
% LU 分解(A = L*U,L 下三角 U 上三角)
[L, U, P] = lu(A)
% QR 分解(A = Q*R,Q 正交 R 上三角,用于最小二乘)
[Q, R] = qr(A)
% 奇异值分解(A = U*S*V',用于降维/伪逆/PCA)
[U, S, V] = svd(A)
% Cholesky 分解(对称正定 A = R'*R,比 LU 快)
R = chol(A)
% 特征值与特征向量
[V, D] = eig(A) % A*V = V*D,D 对角线是特征值,V 列是特征向量- 为什么用
\而非inv(A)*b:\内部根据矩阵特性自动选最合适的分解(LU/QR/Cholesky),更快(不真正求逆)且数值更稳定(求逆会放大舍入误差)。数值计算的金科玉律:「能解方程就别求逆」。 - 超定方程(方程数 > 未知数):
A \ b自动做最小二乘求解(用 QR 分解)。 - SVD 的威力:
svd(A)是最稳健的分解,用于伪逆(病态方程求解)、PCA(主成分分析)、数据压缩。
四、向量化编程实战
向量化是 MATLAB 性能的核心——把循环改成矩阵/向量运算:
matlab
n = 1000000;
% ❌ 反面:循环逐元素(慢,且未预分配)
x = [];
for i = 1:n
x(i) = sin(2*pi*i/n);
end
% ✅ 正面:向量化(快几十倍)
i = 1:n;
x = sin(2*pi*i/n); % sin 作用于整个向量
% 矩阵聚合(默认按列)
A = [1 2 3; 4 5 6];
sum(A) % [5 7 9](每列求和)
sum(A, 'all') % 21(全部求和)
sum(A, 2) % [6; 15](每行求和,维度 2 = 沿列)
mean(A) % 每列均值
max(A, [], 1) % 每列最大值
% 逻辑索引(向量化筛选)
v = [1 -2 3 -4 5];
pos = v(v > 0) % [1 3 5](用逻辑向量索引)
v(v < 0) = 0 % 把负数置零(向量化赋值)- 聚合函数的方向:
sum(A)默认沿第一个非单一维度(通常是列,对矩阵得到每列的和)。sum(A,2)沿第 2 维(每行的和)。 - 逻辑索引:
v(v > 0)用逻辑表达式直接筛选元素——等价于 Python 的v[v > 0],比循环 if 高效。 - 广播:
A + row_vec(矩阵每行加对应列的值)自动广播,无需显式扩展。
五、数组预分配:循环的性能前提
如果非要用循环(无法向量化),必须预分配数组:
matlab
n = 100000;
% ❌ 未预分配:每次循环都重新分配+拷贝,O(n²) 复杂度
x = [];
for i = 1:n
x(i) = i^2; % 每次都扩容 x
end
% ✅ 预分配:一次性分配,O(n) 复杂度
x = zeros(n, 1); % 预分配 n×1 数组
for i = 1:n
x(i) = i^2;
end- 为什么未预分配慢:MATLAB 数组每次扩容要「申请新内存 + 拷贝旧数据」,n 次循环导致 O(n²) 次拷贝。预分配后只需赋值,是 O(n)。
- JIT 缓解:现代 MATLAB 的 JIT 能优化部分未预分配的循环,但仍不如显式预分配 + 向量化。
下一步
掌握矩阵运算与向量化后,下一步进入工具箱、绘图与对比——Signal/Control 工具箱的典型用法、plot/surf 绘图、以及 MATLAB 与 Python/NumPy 的深度对照。