简化for循环

时间:2014-04-17 06:56:35

标签: arrays performance matlab for-loop vectorization

我有一个数据:

    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

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

1 个答案:

答案 0 :(得分: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