
学MATLAB这事儿我一直觉得向量是第一个真正意义上的“坎”。如果你之前写过C或者Python脑子里很容易把它当成普通数组结果第一天就被行向量、列向量、维度不一致这些报错教育了一顿。这篇笔记是《MATLAB基础学习笔记》的第3篇专门聊MATLAB里的向量怎么创建、怎么索引、怎么运算以及那些在文档里翻不到、只有自己踩过坑才懂的经验。适合刚接触MATLAB的本科生、研究生也适合工程岗上需要快速上手数值计算的朋友我尽量把“为什么这样做”也讲清楚。1. 先搞懂底层逻辑MATLAB里的向量到底是什么1.1 行向量还是列向量这真不是小事很多教材开篇就写a [1 2 3]告诉你这是个向量然后就没下文了。但实际用起来行向量和列向量在MATLAB里是完全不同的两个东西连内存布局都不一样。MATLAB的存储顺序是列优先column-major意思是内存里先存第1列的所有行再存第2列。所以一个1×3的行向量[1 2 3]和一个3×1的列向量[1;2;3]在内存里的实际排列方式是不同的。更重要的是矩阵乘法、dot、cross这些函数对维度的敏感程度远超你的想象。比如你要算两个向量的点积dot(a, b)确实对行列不敏感但如果手写a * b行列搞反就直接报维度错误。我做数值实验的时候最常犯的错误就是把某个中间变量存成了行向量结果后面矩阵运算全部维度爆炸调试一晚上。后来养成一个习惯凡是代表某个物理量的向量代码里统一用列向量只有坐标序列这类纯粹数据的才允许用行向量。1.2 命名规范和预分配从第一天就养成好习惯向量变量名我建议遵循几条不成文的规定小写字母开头比如v、x、time不要用V、X这种大写因为MATLAB区分大小写而且很多内置函数和特殊变量都是大写或大写开头。别用i和j做循环变量或向量名。这两个是内置虚数单位一旦你给i赋值后面复数运算全乱。这个坑我见过太多次了很多新手写for i 1:10然后某天代码里需要算复数的实部虚部结果早忘了i已经被改写了查半天。向量名别和函数名冲突。比如sum、mean、max都是函数你建个变量叫sum后面想用sum(x)求和MATLAB会告诉你不支持。动态增长是另一个大坑。很多人这么写x []; for k 1:10000 x(k) k^2; end这代码能跑但慢得离谱。每次x(k) ...都要重新分配内存10000次还好10万次以上就明显卡顿。正确做法是预分配x zeros(1, 10000); for k 1:10000 x(k) k^2; end向量化还能更快但那是第5节的内容。预分配是任何时候都该做的底线操作。2. 创建向量的所有姿势写法越多踩坑机会越多2.1 冒号运算符你确定真的懂它吗冒号运算符是创建向量最常用的手段1:5得到[1 2 3 4 5]1:2:9得到[1 3 5 7 9]。看起来简单但有几个细节需要清楚。步长默认是1如果你写5:1得到的是空矩阵因为MATLAB的冒号规则是“从起点到终点按步长递增直到不超过终点”逆序必须给负步长。这个细节我见过不少人栽过。步长不一定是整数。0:0.1:1看起来生成了11个点但浮点数精度问题可能导致最后一个点不是刚好1。准确说是0,0.1,...,0.9然后1有没有取决于浮点比较。在临界点计算时这可能导致数组长度和预期不符。更严谨的做法是用linspace(0, 1, 11)它保证生成恰好11个点首尾都包括。2.2 linspace与logspace当你需要精确个数的点时linspace(a, b, n) logspace(a, b, n)linspace(0, 1, 5)生成[0, 0.25, 0.5, 0.75, 1]n可以省略默认是100。logspace则是对数等距分布比如logspace(0, 3, 4)得到[1, 10, 100, 1000]。频率响应的横轴、滤波器设计里经常用这个。选哪种需要精确控制点数、首尾值确定的时候用linspace。需要均匀覆盖数量级范围的时候用logspace。需要指定步长、点数无关紧要的时候用冒号运算符。2.3 转置那个看似无害的单引号MATLAB里是共轭转置.是非共轭转置。对实数向量两者结果一样对复数向量区别就出来了z [12i, 3-4i]; z % 结果是列向量且每个元素取共轭 z. % 结果是列向量但不取共轭很多人不知道这个区别导致复数域计算里莫名其妙多出个负号。如果你只是想转置不管数据是不是复数我都建议用.养成习惯。这一行代码的区别可能给你省下一个通宵的排错时间。2.4 一些冷门但实用的创建函数zeros(1,n)和zeros(n,1)全零向量最常用的预分配手段。ones(1,n)全1向量。eye(n)n×n单位阵但取eye(n)(:,k)就是第k个单位向量。想建单位向量可以用这个。rand(1,n)、randn(1,n)均匀分布和正态分布的随机向量蒙特卡洛模拟里天天见。repmat、meshgrid严格说不止向量但生成规则网格时会用到。随机试验我推荐先用rand因为它结果可复现性更好控制。具体做法是把随机种子固定下来不然每次跑结果都不一样调试阶段会很痛苦。3. 索引与切片MATLAB向量最考验基本功的地方3.1 基本索引和end关键字x(3)取第三个元素x(1:3)取前三个x(end)取最后一个x(end-2:end)取最后三个。这里的end是MATLAB的一个特殊关键字不是变量它表示当前维度的末尾索引。这个end语法在循环里尤其好用。我之前写一个滑动窗口均值窗口长度是某个变量w想取最后w个数用x(end-w1:end)代码干净又有可读性。3.2 逻辑索引比find优雅十倍x randn(1, 100); y x(x 0); % 只保留正数逻辑索引直接用一个逻辑向量去“过滤”原向量不满足条件的元素直接丢掉。这个操作在数据处理里太重要了。常见写法还包括mask x 0 x 1; y x(mask); % 只保留0到1之间的元素有人说用find比如pos find(x 0); y x(pos);功能一样但逻辑索引把筛选逻辑表达得更清晰而且不需要额外的下标变量。唯一的建议是别在循环里反复计算逻辑掩码能提到循环外就提出来。3.3 你可能会遇到的越界和空索引索引越界报错是家常便饭。x(101)当x只有100个元素时直接报“索引超出数组边界”。另一种情况是索引结果为空的逻辑掩码比如x(x 100)如果没有任何元素满足返回的是空矩阵[]。这两个情况性质不同一个是错误一个是合法结果。合法结果也要注意对空向量取mean会得到NaN或者某些函数直接报错。处理方式是先判断isempty或者在画图前检查数据范围。4. 向量运算点积、叉乘、范数一次讲透4.1 点积夹角、投影与相似度都靠它点积公式是两个向量对应元素相乘再求和。MATLAB提供dot(a, b)也可以直接写a * b。点积的几何意义是投影的长度乘以另一向量的模长所以当两个向量方向一致时取最大垂直时为0。在数据科学里点积常被用来计算相似度。比如你有一个查询向量和一个数据库里的向量内积越大代表它们越相似。这个概念延伸出去就是“向量数据库”的核心思想之一。很多推荐系统、语义搜索系统后台都在算大规模向量的点积只是在工程实现上会做索引和近似计算不会真去逐条算。这跟你今天在MATLAB里写dot(x, y)学到的数学思想是一脉相承的。4.2 叉乘结果是向量方向由右手定则决定叉乘只能用于三维向量以及二维向量的三维扩展公式稍有记错就出负号。在网上搜“空间法向量的交叉填负号”很多人说的就是叉乘算的时候容易弄反符号。MATLAB里直接cross(a, b)它会自动按行列向量判断输出方向。我建议你干脆统一用列向量然后cross(a, b)和cross(b, a)方向反过来。工程中叉乘最典型的应用是计算法向量比如三角面片的法向量就是两条边向量的叉乘。我在处理三维点云的时候经常要用叉乘估计曲面法向用cross一步到位比手写公式稳得多。4.3 范数衡量向量长度的通用标准norm(x)默认计算2-范数即向量各元素平方和的开方几何上就是向量的“长度”。norm(x, 1)是1-范数各元素绝对值之和norm(x, Inf)是无穷范数取绝对值最大元素。在深度学习和优化问题里范数的作用远不止算长度。正则项、梯度裁剪、误差度量都涉及范数的概念。做机器学习时你会看到大量“L1范数”“L2范数”的术语本质就是这里的norm(x, p)。所以别小看这个函数它是你未来理解很多算法的基础工具。4.4 向量化运算点乘、点除、点幂MATLAB特别强调向量化也就是用. *,./,.^来对每个元素做操作而不是写循环。x 1:10; y x.^2; % 每个元素平方 z sin(x) .* cos(x); % 对应元素相乘这里必须注意*和.*的区别。A * B是矩阵乘法A .* B是逐元素乘法。矩阵乘法要求维度匹配A的列数等于B的行数而逐元素乘法要求形状一致。写代码时第一年我肯定打过无数遍这两者的报错。记住一条判断规则如果你不确定这个操作该用哪个就把维度写出来套一次矩阵乘法的规则就能知道自己该选哪个了。5. 向量化编程让代码告别for循环的性能关键5.1 为什么MATLAB里的循环“这么慢”不只是心理作用。MATLAB是解释型语言for循环每迭代一次都有解释开销而内置函数全是编译好的C代码。向量化之所以快是因为它把循环放到了底层编译代码里不再受解释开销拖累。举个我实测过的例子对1e6个随机数求每段的滑动均值如果写成双层for循环耗时是线性的代码越长越慢改用movmean或者conv快到几乎感觉不到。这差距不是几倍是几十倍到上百倍。5.2 经典循环改写成向量这是最常用的几个改写模式累加求和s 0; for k 1:n s s x(k); end % 改为 s sum(x);元素平方和s 0; for k 1:n s s x(k)^2; end % 改为 s sum(x.^2);条件计数cnt 0; for k 1:n if x(k) 0 cnt cnt 1; end end % 改为 cnt sum(x 0);每一行改写背后都是一个原则先把数据放进向量再用向量作为整体参与运算最后归结为一个聚合函数sum、mean、max、min。5.3 向量化的边界不是所有循环都能无脑改向量化虽然好但边界情况也不少。比如迭代过程依赖上一步结果的最简单的递归关系x(k1) f(x(k))这类本质上必须串行不能直接向量化。再比如需要动态调整索引的算法强行向量化反而写出糟糕的可读性。我现在的原则是两句话能向量化就向量化不能向量化就预分配加循环。MATLAB新版里的JIT即时编译已经让循环快了不少在一些简单场景下循环和向量化的差距没那么大了。但作为学习资料还是建议把向量化思维练熟。同时我记得网上有人把vector向量练习作为一个关键词其实说的就是这类练习本质上是在锻炼你“把问题映射成数组运算”的能力这个能力练好了后面学矩阵运算、学图像处理都会顺利很多。6. 向量的可视化会画图才算真正会向量6.1 最常用的绘图命令t linspace(0, 2*pi, 100); y sin(t); plot(t, y, LineWidth, 1.5); xlabel(时间 t); ylabel(sin(t)); title(正弦曲线); grid on;这里t和y都是长度100的向量plot要求横纵坐标维度一致。如果长度不匹配报错信息会直接告诉你“向量长度必须相同”。plot画的是折线如果想看点就用scatter或者plot(t, y, o)。数据量大的时候scatter有自己的优势还能按颜色映射数值大小。操作上我建议先figure新建图形窗口再画图命名的时候就用有意义的变量名比如figure_original这种方便多图对比。6.2 三维向量和箭头画三维向量quiver3是标配。比如画原点发出的一条向量[1;2;3]quiver3(0, 0, 0, 1, 2, 3, LineWidth, 2); axis equal;这里axis equal很关键不然三个坐标轴的缩放比例不一致视觉上向量方向会失真歪得不像样。我做三维法向可视化的时候一定要加axis equal不然面片法向看起来斜得很离谱。6.3 画图时的常见错误最典型的是画多条曲线时忘了hold onplot(t, sin(t)); hold on; plot(t, cos(t));没有hold on第二条曲线会覆盖第一条。另一个常见问题是横纵轴数据类型不匹配比如横轴是字符串数组、纵轴是数值向量画出来是离散的散点。这类问题排查时先检查数据维度再检查数据类型。7. 常见报错和调试技巧我踩过的坑都整理给你7.1 矩阵维度不一致这是最经典的报错没有之一。出现这个报错直接检查两个东西参与运算的向量是行还是列长度分别是多少。用size(x)确认维度不要用length(x)因为length不区分行列只返回最大值很容易掩盖行列混用的问题。7.2 混用行向量和列向量比如一个1×5的行向量加上一个5×1的列向量MATLAB新版会触发隐式扩展得到一个5×5矩阵而不是报错。这个“不报错的结果”有时比报错更危险。因为你的预期是向量操作结果得到矩阵然后后面所有步骤全错位排查起来非常费劲。建议在关键运算前用assert(size(a,1) size(b,1))这类断言主动检查维度给未来留个后门。7.3 隐式扩展新版MATLAB的隐形炸弹R2016b开始MATLAB引入了隐式扩展也就是维度兼容的向量会自动“扩”成矩阵。比如(1:3) 1:3得到的是3×3矩阵。这个特性在某些场景下很方便但新手很容易踩进去。如果你的代码里出现了莫名其妙的大矩阵先检查是不是两个“看起来都是向量”的东西搞出了笛卡尔积式的扩展。调试技巧是选一小段数据用size和whos把每个变量的维度都打出来看一遍往往第一个维度不对劲的地方就是问题源头。8. 从向量延伸出去它远不止一门课程里的基础概念8.1 向量在工程计算里的实际应用学向量的最终目的不是为了做练习册而是为了后面这些真刀真枪的工程问题信号处理一个时间序列、一段语音、一帧图像灰度值本质都是向量或矩阵。滤波、去噪、FFT全是向量运算。物理仿真位置、速度、加速度、力全用向量表示比如无人机姿态控制里搞四元数、向量旋转。机器学习样本特征是向量模型参数是向量损失函数对参数的梯度也是向量。支持向量机名字就带着“向量”。SVM的核心是把样本看作特征空间里的点用一个超平面去分割而超平面由法向量和偏置决定。这个“点”和“法向量”就来自今天的向量基础。所以学到这里你其实已经把机器学习、信号处理、数值仿真这三个领域的公共地基打下一块了。8.2 向量数据库一个完全不同的方向热搜词里多次出现“向量数据库”这跟MATLAB里的向量确实是同源的数学概念但工程形态完全不同。向量数据库的核心工作是把文本、图像、音频这些非结构化数据通过嵌入模型转成高维向量然后建索引以便做近邻搜索。做推荐系统、语义检索、大模型RAG检索增强生成的人都在跟这个东西打交道。在MATLAB里我们处理的是内存中的一维数组规模可能是几千到几百万在向量数据库里处理的是分布式存储下的海量高维向量动辄上亿条需要用专门的近似最近邻算法比如HNSW、IVF去加速查询。虽然基础设施不同但数学上还是距离、点积、余弦相似度这些老朋友。你会发现在MATLAB里把dot、norm这些概念吃透了后面理解向量数据库的相似度计算逻辑会非常轻松。8.3 向量的意义是建立直觉最后说一点学习体会。MATLAB向量这部分内容难度其实不大但它建立的是一个很重要的直觉把连续问题离散化、把离散数据组织成向量、用向量运算替代循环。这三个思维一旦建立后续的矩阵、线性代数、数值计算、数据分析、深度学习都会自然衔接上因为你看到的都是“数组运算”这一种统一的语言。我自己用MATLAB这几年向量是最基础但最常被低估的一块。很多人急着学矩阵、学Simulink、学工具箱结果连一个向量的行列都没理顺后面每走一步都在补前面的债。建议你多花点时间做“vector向量练习”把索引、逻辑掩码、点积、范数这些练到条件反射的程度。真正的效率提升不是学会某个酷炫函数而是把这些底层操作变成你脑子里的默认语言。