本节摘要:矩阵的构造、索引、拼接与运算是 Matlab 全部上层能力的地基。本节覆盖常用构造函数、冒号与 end 索引、线性索引规则、矩阵拼接与变形,以及以
size、reshape、inv、\为核心的运算函数,配以可运行示例。
假设有一份实验数据:4 次测量、每次 3 个通道。在 Matlab 里它天然就是一个 4×3 矩阵。构造它、切它、拼它、对它做统计,这四件事覆盖了日常数据操作的大半。
Z = zeros(3,4); % 预分配全零矩阵 I = eye(3); % 单位阵 R = rand(4,3); % 均匀随机数 D = diag([5 3 1]); % 对角阵 rng(42); % 固定随机种子,保证结果可复现 size(R) % 返回 [4 3] length(R) % 最大维度 = 4(建议改用 size,语义更明确) numel(R) % 元素总数 12
预分配不是小事:第 6 章会看到,循环里不断"变长"的数组是性能杀手,zeros 预分配是老一辈 Matlab 程序员的肌肉记忆。
A = magic(4); % 4x4 魔方阵 A(2,3) % 第2行第3列 A(1:2, 2:end) % 前2行、第2列到末列 A([1 4], :) % 第1、4行的全部列 A(:, 2) = [] % 删除第2列(整列赋空) v = A(3, :); % 取出一行变向量
两条隐规则要记牢:赋空即删除(把子块赋成 [] 就删掉它);线性索引按列优先展开,A(6) 等价于沿列数到第 6 个元素。列优先继承自 Fortran 时代,与 C 系语言的行优先相反,做混合编程时最容易在这里出错。
逻辑索引是矩阵语言的点睛之笔:
idx = A > 10; % 同尺寸逻辑矩阵 A(idx) % 抽出所有大于10的元素,得到列向量 A(A < 5) = 0; % 阈值过滤一行搞定
B = [A, A]; % 水平拼接(逗号或空格) C = [A; A]; % 垂直拼接(分号) M = reshape(1:12, 3, 4); % 按列重排成 3x4
reshape 只搬运排列、不复制数据顺序按列走,配合线性索引可以玩出"矩阵变向量再变回来"的把戏,图像分块处理里非常常用。
统计与代数函数默认沿列作用,这是另一个"矩阵优先"的化石:
mean(A) % 每列均值,返回行向量 max(A, [], 2) % 每行最大值(第二维) sum(A(:)) % 全体元素和:先摊平再求和 det(A); rank(A); eig(A) % 行列式、秩、特征值
💡 关键直觉:
mean(A)与mean(A,2)的差别,本质是"沿哪个维压缩"。把"压缩"当心智模型,sum、max、mean一整套函数就统一了。
data = rand(4,3) * 100; data(data < 30) = 30; % 下限截断 data = (data - min(data,[],1)) ... % 按列min-max归一化 ./ (max(data,[],1) - min(data,[],1));
三行完成截断加归一化——用标量语言写要两层循环,这里每个表达式都同时对整个矩阵生效。
把本章主线题目做完。目标:解四元线性方程组,并回答"这个解能信吗"。
A = [ 3 1 0 2 -1 4 2 1 2 0 5 -1 1 3 1 6 ]; b = [6; 4; 7; 12]; x = A\b % 一次性求解 r = A*x - b % 残差,理论上全为零附近 cond(A) % 条件数:衡量解对扰动的敏感度
命令行会给出 x 的四个分量,残差 r 各元素量级在 1e-15 上下——这就是"数值上正确"。cond(A) 若输出在几十的量级,说明矩阵性态良好,解可信;如果条件数冲到 1e10 以上,哪怕残差很小,输入数据末位的一点测量误差也会被放大到解的整体上,此时应当考虑重新建模或改用正则化,而不是抱怨算法不准。\ 算符内部会根据矩阵形态自动在 LU、QR、Cholesky 之间选择,这个"自动挡"日常够用;想看它选了什么,加 sparse 或查看文档中的算法说明即可。
矩阵操作类报错集中在三句话上,逐一给出定位思路。第一句"矩阵维度必须一致",出现在逐元素运算两侧尺寸不同时,先分别打印 size 对一遍,九成是行向量碰上了列向量——用 v(:) 或 v.' 摆正方向。第二句"内部矩阵维度必须一致"(乘法版本),说明矩阵乘法的内维不匹配,回到线性代数定义检查 A 的列数与 B 的行数。第三句"索引超出数组范围",多半是 end 用在了空数组上,或者循环边界写成了 n+1;用断点停在出错行,把被索引变量的实际尺寸看一眼,通常立破。
另一个隐蔽问题是逻辑索引与数值索引混用:A(find(idx)) 与 A(idx) 在 idx 为逻辑向量时等价,但当 idx 是数值向量且含零时,find 版会把零当跳过、直接版则报错。统一用逻辑索引写法,行为最可预期。
三者都在"改变元素排布",但语义完全不同。转置只交换两个维度;reshape 保持列优先的数据顺序不变、只改各维长度;permute 任意重排维度顺序、元素随维度搬家。一张表看清:
| 操作 | 改什么 | 数据顺序 | 典型用途 |
|---|---|---|---|
A.' |
行列互换 | 元素位置随之变 | 向量方向调整 |
reshape(A,m,n) |
外形尺寸 | 列优先序列不变 | 图像分块、摊平 |
permute(A,[2 1 3]) |
维度次序 | 元素跟维度走 | 多通道数组换轴 |
辨析的意义在三维以上才真正显现:处理一批 100 张 64×64 图像时,数据是 64×64×100 的数组,想要"每张图的行"还是"跨所有图像的同位置像素",决定了该用转置还是 permute。想清楚数据的维度语义,比背函数签名重要。
zeros/eye/rand/diag,预分配习惯从此建立;