向量化
使用向量化
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 + y
或x - y
.在这个例子中,x
21 × 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
逻辑阵列操作
数组批量处理的一个逻辑扩展是向量化比较和决策。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
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(:)));