主要内容

向量化

使用向量化

MATLAB®针对涉及矩阵和向量的操作进行了优化。修改基于循环的、面向标量的代码以使用MATLAB矩阵和矢量操作的过程被称为向量化.向量化你的代码是值得的,原因如下:

  • 外观:向量化的数学代码看起来更像教科书上的数学表达式,使代码更容易理解。

  • 少出错:如果没有循环,向量化的代码通常会更短。代码行数越少,引入编程错误的机会就越少。

  • 性能:向量化代码通常比包含循环的相应代码运行得快得多。

通用计算向量化代码

这段代码计算从0到10的1001个值的正弦值:

I = 0;T = 0:。01:10 I = I + 1;Y (i) = sint;结束

这是同一个代码的向量化版本:

T = 0:.01:10;Y = sint;

第二个代码示例通常比第一个执行得更快,并且更有效地使用了MATLAB。通过创建包含所示代码的脚本来测试系统上的执行速度,然后使用抽搐而且toc函数来度量它们的执行时间。

为特定任务向量化代码

这段代码计算一个向量在每五个元素上的累积和:

X = 1:10000;Ylength = (length(x) - mod(length(x),5))/5;Y (1:ylength) = 0;N = 5:5: y(N /5) = sum(x(1: N));结束

使用向量化,您可以编写一个更简洁的MATLAB过程。这段代码显示了完成任务的一种方法:

X = 1:10000;xsum = cumsum(x);Y = xsum(5:5:长度(x));

数组操作

数组操作符对数据集中的所有元素执行相同的操作。这些类型的运算对于重复的计算很有用。例如,假设您收集卷(V)以记录锥体的直径(D)和高度(H).如果你只收集一个锥体的信息,你可以计算出这个锥体的体积:

V = 1/12*pi*(D^2)*H;

现在,收集10000个球果的信息。向量D而且H每个包含10,000个元素,您希望计算10,000个卷。在大多数编程语言中,您需要设置一个类似于此MATLAB代码的循环:

V(n) = 1/12*pi*(D(n)²)*H(n);结束

使用MATLAB,你可以用类似于标量情况的语法对向量的每个元素执行计算:

%矢量化计算V = 1/12*pi*(d ^2).*H;

请注意

放置句号()/,,将它们转换为数组操作符。

数组运算符还使您能够组合不同维度的矩阵。这种大小为1的维度的自动扩展对于向量化网格创建、矩阵和向量操作等非常有用。

假设这个矩阵一个表示测试分数,其中的行表示不同的类。你想要计算每个班级的平均分和个人分数之间的差值。使用循环,操作看起来像:

A = [97 89 84;95 82 92;64 80 99;76 77 67;...88 59 74;78 66 87;55 93 85];mA = mean(A);B = 0(大小(A));n = 1:size(A,2) B(:,n) = A(:,n) - mA(n);结束

一个更直接的方法是A -均值(A),这样就避免了循环的需要,而且速度要快得多。

devA = A - mean(A)
devA = 18 11 0 16 4 8 -15 2 15 -3 -1 -17 9 -19 -10 -1 -12 3 -24 15

尽管一个7 × 3矩阵和意思是(A)是一个1 × 3的向量,MATLAB隐式展开该向量,就好像它与矩阵具有相同的大小,并且该操作执行为普通的元素减操作。

操作数的大小要求是,对于每个维度,数组的大小必须相同,或者其中一个为1。如果满足此要求,则其中一个数组的大小为1的维度将扩展为与另一个数组中的相应维度相同的大小。有关更多信息,请参见基本操作的兼容数组大小

隐式展开对向量化有用的另一个领域是处理多维数据。假设你想求一个函数的值,F,为两个变量,x而且y

F(x,y) = x*exp(-x2- y2

求这个函数在点的每一个组合上的值x而且y向量,你需要定义一个值的网格。对于这个任务,您应该避免使用循环来遍历点组合。相反,如果其中一个向量是列,另一个是行,那么当向量与数组操作符一起使用时,MATLAB会自动构造网格,例如x + yx - y.在这个例子中,x21 × 1向量和y是一个1 × 16的向量,所以这个运算得到了一个21 × 16的矩阵x的第一个维度y

X = (-2:0.2:2)';% 21-by-1Y = -1.5:0.2:1.5;% 1-by-16F = x.*exp(-x.²-y.²);% 21-by-16

在希望显式创建网格的情况下,可以使用meshgrid而且ndgrid功能。

逻辑阵列操作

数组批量处理的一个逻辑扩展是向量化比较和决策。MATLAB比较运算符接受矢量输入并返回矢量输出。

例如,假设在收集10,000个锥的数据时,您记录了直径的几个负值。方法确定向量中的哪些值是有效的> =接线员:

D = [-0.2 1.0 1.5 3.0 -1.0 4.2 3.14];D >= 0
Ans = 0 1 1 1 0 1 1
您可以直接利用MATLAB的逻辑索引功能来选择有效的圆锥体积,Vgood的对应元素D都是非负的。
Vgood = V(D >= 0);

MATLAB允许您对具有函数的整个向量的元素执行逻辑与或所有而且任何,分别。的所有值都可以抛出警告D都低于零度:

如果所有(D < 0)警告(“所有直径值都是负数。”返回结束

MATLAB还可以比较两个具有兼容大小的向量,允许您施加进一步的限制。这段代码找到所有V为非负的值D大于H

V((V >= 0) & (d > h))
生成的向量与输入的大小相同。

为了便于比较,MATLAB包含特殊值来表示溢出、下溢和未定义的操作符,例如而且.逻辑运算符isinf而且isnan存在是为了帮助对这些特殊值执行逻辑测试。例如,排除法通常很有用计算值:

x = [2 -1 0 3 NaN 2 NaN 11 4 Inf];Xvalid = x(~isnan(x))
xvalid = 2 -1 0 3 2 11 4 Inf

请注意

Inf == Inf返回true;然而,NaN == NaN总是返回false。

矩阵运算

在对代码进行向量化时,通常需要构造具有特定大小或结构的矩阵。存在创建统一矩阵的技术。例如,你可能需要一个相等元素的5 × 5矩阵:

A = ones(5,5)*10;
或者,你可能需要一个重复值的矩阵:
V = 1:5;A = repmat(v,3,1)
A = 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5

这个函数repmat具有从较小的矩阵或向量构建矩阵的灵活性。repmat通过重复输入矩阵创建矩阵:

A = repmat(1:3,5,2) B = repmat([1 2;3, 2, 2)
A = 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 4 1 2 1 2 3 4 3 4

排序、设置和计数操作

在许多应用中,对向量的一个元素进行的计算依赖于同一向量中的其他元素。例如,一个向量,x,可能表示一个集合。如何迭代通过一个集没有循环不明显。当使用向量化代码时,过程变得更加清晰,语法也不那么麻烦。

消除冗余元素

求向量的冗余元素有许多不同的方法。一种方法涉及到函数diff.向量元素排序后,相等的相邻元素在使用diff在这个向量上的函数。因为diff (x)生成元素小于1的向量x,则必须添加一个不等于集合中任何其他元素的元素。总是满足这个条件。最后,你可以使用逻辑索引来选择集合中唯一的元素:

X = [2 1 2 2 3 1 3 2 1 3];X = sort(X);差异= diff([x,NaN]);Y = x(差~=0)
Y = 1 2 3
方法也可以完成相同的操作独特的功能:
y =独特(x);
然而,独特的函数可能会提供超出所需的功能,并降低代码的执行速度。使用抽搐而且toc函数,如果您想度量每个代码段的性能。

计算向量中的元素

的集合或子集,而不仅仅是返回x,您可以计算一个元素在向量中的出现次数。向量排序之后,可以使用找到函数来确定零值的索引diff (x)并显示元素改变值的位置。的后续索引之间的差异找到函数指示特定元素的出现次数:

X = [2 1 2 2 3 1 3 2 1 3];X = sort(X);差异= diff([x,max(x)+1]);Count = diff(find([1,difference])) y = x(find(difference))
计数= 3 4 3 y = 1 2 3
找到函数不返回的索引元素。你可以数一数而且值使用isnan而且isinf功能。

Count_nans = sum(isnan(x(:)));Count_infs = sum(isinf(x(:)));

向量化中常用的函数

函数 描述
所有

确定是否所有数组元素都是非零或为真

任何

判断是否有数组元素非零

cumsum

累计金额

diff

差分与近似导数

找到

查找非零元素的索引和值

ind2sub

线性下标

ipermute

N-D阵列的逆排列维数

逻辑

将数值转换为逻辑值

meshgrid

二维和三维空间中的矩形网格

ndgrid

N-D空间中的矩形网格

交换

重新排列N-D数组的维数

刺激

数组元素的乘积

repmat

数组的重复副本

重塑

重塑数组

shiftdim

改变尺寸

排序

对数组元素排序

挤压

删除单维度

sub2ind

将下标转换为线性下标

总和

数组元素的和

相关的话题

外部网站