【问题标题】:Simplifying for-loop简化 for 循环
【发布时间】:2014-04-17 06:56:34
【问题描述】:

我有一个数据:

    minval =  NaN   7   8   9   9   9   10  10  10  10
              NaN   NaN 10  10  10  10  10  10  10  10
              NaN   NaN NaN 10  10  9   10  10  10  9
              NaN   NaN NaN NaN 9   9   10  9   10  10
              NaN   NaN NaN NaN NaN 9   10  10  10  10
              NaN   NaN NaN NaN NaN NaN 10  11  10  10
              NaN   NaN NaN NaN NaN NaN NaN 10  10  10
              NaN   NaN NaN NaN NaN NaN NaN NaN 10  10
              NaN   NaN NaN NaN NaN NaN NaN NaN NaN 10
              NaN   NaN NaN NaN NaN NaN NaN NaN NaN NaN

我会这样做:

C=size(minval,2);
for e=2:C
    D1(1,e)=minval(1,e);
end
D1(D1 == 0) = nan;
for e=3:C
    for b=2:e-1
    D2(b,e)= minval(b,e)+D1(1,b-1);
    D2(D2 == 0) = nan;
    [D1(2,e), idx_bt(1,e)]=min(nonzeros(D2(:,e)));
    end
end
D1(D1 == 0) = nan;
for e=4:C
    for b=3:e-1
    D3(b,e)= minval(b,e)+D1(2,b-1);
    D3(D3 == 0) = nan;
    [D1(3,e), idx_bt(2,e)]=min(nonzeros(D3(:,e)));
    end
end
D1(D1 == 0) = nan;

效果很好,它给了我这样的正确答案:

D1 = NaN    7   8   9   9   9   10  10  10  10
     NaN    NaN NaN 17  17  16  17  17  17  16
     NaN    NaN NaN NaN NaN 26  27  26  26  26

idx_bt = 0  2   3   4   5   6   7   8   9   10
         0  0   1   3   3   3   3   3   3   3

我想有一个技巧可以让这段代码更简单、更快速。有什么帮助吗?谢谢。

【问题讨论】:

  • 您能否发布minval 的“小”版本 - 可能是 10x10 以及您在此示例中获得的输出。通常,简化代码比重新考虑给定输入和输出的所有内容更难。
  • 我已经编辑了我的问题,谢谢你的建议。
  • @sintyar 你能确认idx_bt 的值吗?运行代码让我们 idx_bt 仅作为显示结果的最后两行。

标签: arrays performance matlab for-loop vectorization


【解决方案1】:

以下代码的症结围绕bsxfun,这应该是向量化代码的方法之一。

代码

%%// Get C
C=size(minval,2);

%%// Declare variables to store required outputs 
D1 = NaN(3,C);
idx_bt = zeros(2,C);

%%// --------- STAGE 0 -------------------------
D1(1,2:end) = minval(1,2:C);

%%// --------- STAGE 1 -------------------------
ft1 = bsxfun(@plus,minval(2:C-1,3:C),D1(1,1:C-2)');%%//'
ft1 = [zeros(1,size(ft1,2)) ;ft1];
ft1(ft1==0) = NaN;
D2 = ft1;
[D1(2,3:end) ,idx_bt(1,3:end)] = nanmin(D2);

%%// Probably do not need this given your data, but if you have zeros 
%%// alongwith the NaNs and if you are looking to replace 
%%// those zeros with NaNs you might. So, it all depends on your data.
%%// This could be looked after later on in the code as well.%%//' 
D1(D1 == 0) = NaN;

%%// --------- STAGE 2 -------------------------
ft11 = bsxfun(@plus,minval(3:C-1,4:C),D1(2,2:C-2)');%%//'
ft11 = [zeros(2,size(ft11,2)) ;ft11];
ft11(ft11==0) = NaN;
D3 = ft11;
[D1(3,4:end) ,idx_bt(2,4:end)] = nanmin(D3);

D1(D1 == 0) = NaN; 

输出

D1 =

   NaN     7     8     9     9     9    10    10    10    10
   NaN   NaN   NaN    17    17    16    17    17    17    16
   NaN   NaN   NaN   NaN   NaN    26    27    26    26    26


idx_bt =

     0     0     1     3     3     3     3     3     3     3
     0     0     0     1     1     5     5     7     7     7

【讨论】:

  • 更多关于bsxfun的信息可以在它的标签wiki中找到:bsxfun
  • @Shai 谢谢你的链接!让我们宣传bsxfun
  • 非常感谢,这个bsxfun对我帮助很大。
  • @sintyar 您能否使用idx_bt 的正确值编辑您的问题,因为我不确定?
猜你喜欢
  • 1970-01-01
  • 2018-04-11
  • 2016-03-06
  • 1970-01-01
  • 2016-11-20
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多