【问题标题】:Using vector instead of Loop使用向量而不是循环
【发布时间】:2018-05-19 01:32:21
【问题描述】:

我有一个巨大的矩阵。我刚刚给出了一个大小为(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))

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

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

【问题讨论】:

标签: matlab loops matrix


【解决方案1】:

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

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 计时的性能:

Orig_Post = 14.3219
Orig_Post_with_Preallocation = 1.7764
Vectorised = 5.3292

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

【讨论】:

  • 我没有你那么耐心,所以我尝试使用1e6 来确定数组大小(R2017a)。我看到 0.055 没有预分配,0.0087 有,0.018 有矢量化代码。与您的结果相似。我期望矢量化代码的成本相似或略好于循环,而不是更差。这可能是我迄今为止看到的第三个例子,其中循环比相应的矢量化代码更快。我认为在这种情况下,这是因为矢量化代码需要更多的数据副本和中间结果。我敢肯定,这完全与内存使用和缓存未命中有关。
  • 另外,分离索引以避免这样做两次:a3 = a(3:end); a2 = a(2:end-1); a1 = a(1:end-2); k = [0 abs(a3-2*a2+a1) ./ (a3+2*a2+a1)];。这给了我 0.011,更接近循环时间。我尝试做a2 = 2*...,不乘两次,也尝试a0=a3+a1,不做两次加法,但两次时间都增加了。莫名其妙!
猜你喜欢
  • 2014-09-20
  • 2018-12-05
  • 1970-01-01
  • 2016-02-20
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
  • 1970-01-01
相关资源
最近更新 更多