关于matlab:用向量代替循环

Using vector instead of Loop

我有一个巨大的矩阵。我刚刚给出了一个大小为 (1*1000000).

的矩阵示例

我正在使用简单的 Loop(我不喜欢使用 Loop)来查找 k

k= k(ii)=(abs(a(ii+1)-2*a(ii)+a(ii-1)))/(a(ii+1)+2*a(ii)+a(ii-1))

但是,这对于小矩阵来说很好。如果我有大量数据需要很长时间。有什么方法可以使用向量而不是 Loop 来查找 k

1
2
3
4
5
6
7
clear;
clc;
a=rand(1,1000000);

for ii=2:size(a,2)-1
    k(ii)=(abs(a(ii+1)-2*a(ii)+a(ii-1)))/(a(ii+1)+2*a(ii)+a(ii-1));
end


如果你想对它进行矢量化,你需要知道在每次迭代中你将使用 a 的哪些索引。例如,术语 a(ii+1)ii2 迭代到 999999 意味着您正在使用从索引 3 到 last 的 a 元素,并且类似地找出其他术语。然后只需按元素进行除法 ./0 是在开始时手动附加的,因为在您的代码中,您没有在第一个索引处显式存储任何内容,并且当您跳过索引时自动存储的内容为零。

1
k = [0 abs(a(3:end)-2*a(2:end-1)+a(1:end-2)) ./ (a(3:end)+2*a(2:end-1)+a(1:end-2))];

使用 R2017a 和 a=rand(1,1e8); 在我的系统上使用 timeit 计时的性能:

1
2
3
Orig_Post = 14.3219
Orig_Post_with_Preallocation = 1.7764
Vectorised = 5.3292

因此可以看出循环在较新的版本中得到了显着改进。事实证明,具有为 k 正确预分配内存的循环的解决方案比向量化的解决方案快得多。您遇到的性能下降是由于没有预分配(正如 Cris Luengo 已经建议的那样)。要预分配,请编写 k = zeros(1, size(a,2)-1);
在循环之前。