【问题标题】:Vectorizing column wise logical indexing of a matrix向量化矩阵的按列逻辑索引
【发布时间】:2018-11-01 03:16:42
【问题描述】:

我正在 MATLAB 中对矩阵进行逐列逻辑索引。一个例子是:

tic

N = 5*10^6;
input = randi(100,N,12);
output = zeros(N,1);

d_sn2 = randi(25,N,12);
d_sd2 = randi(25,N,12);

LL1 = randi(8,N,12);
UL1 = randi([12,20],N,12);

LL2 = randi(8,N,12);
UL2 = randi([12,20],N,12);

for p = 1:N
    temp = zeros(12,12);
    for i = 1:12
        I2 = (d_sn2(:,i)>LL1(p,i) & d_sn2(:,i)<UL1(p,i)) & (d_sd2(:,i)>LL2(p,i) & d_sd2(:,i)<UL2(p,i));
        temp(i,:) = mean(input(I2,:));
    end
    output(p) = max(temp(:));
end

toc               

我想知道我是否可以将此操作矢量化或加快速度?

【问题讨论】:

  • 抱歉,这是个错误。计算后我确实使用了 I2。由于它的大小和涉及的数据,我没有在这里显示确切的代码。但这是问题的症结
  • @CrisLuengo:抱歉,我相应地编辑了代码。
  • 我已经调整了您的代码,以便实际使用内部循环中计算的所有数据。我不确定这是否符合您的要求,但它给了我一些可以在答案中讨论的内容。

标签: arrays matlab matrix indexing


【解决方案1】:

内部循环中I2 的计算可以很容易地向量化。这个:

temp = zeros(12,12);
for i = 1:12
   I2 = (d_sn2(:,i)>LL1(p,i) & d_sn2(:,i)<UL1(p,i)) & (d_sd2(:,i)>LL2(p,i) & d_sd2(:,i)<UL2(p,i));
   temp(i,:) = mean(input(I2,:));
end

和这个是一样的:

I2 = d_sn2>LL1(p,:) & d_sn2<UL1(p,:) & d_sd2>LL2(p,:) & d_sd2<UL2(p,:);
temp = zeros(12,12);
for i = 1:12
   temp(i,:) = mean(input(I2(:,i),:));
end

此代码使用隐式单例扩展,如果您有 R2016b 之前的 MATLAB 版本,则需要使用 bsxfun 编写每个 &gt; (gt) 和 &lt; (lt) 调用: bsxfun(@gt,d_sn2,LL1(p,:))

不幸的是,input 的索引很难矢量化。因为i 的每次迭代都会访问不同数量的input 元素,所以没有简单的方法可以在没有循环的情况下创建矩阵temp。我尝试的几种方法都比循环代码慢得多。

如果您使用的是相当新版本的 MATLAB,那么您的代码将会非常高效。 MATLAB 的解释器使用 JIT(即时编译器)使循环不像以前那么慢。例如,将矩阵的所有元素相加的普通循环的差异仅比使用函数 sum 慢 2-3 倍。回到过去,这曾经可能慢 100 倍。所以矢量化的好处和以前不一样了。再加上您使用的数组非常大,这意味着向量化将成为一种悲观化,因为向量化通常意味着创建更大的中间矩阵。

【讨论】:

    猜你喜欢
    • 2014-11-05
    • 1970-01-01
    • 2015-07-30
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多