Vectorizing 'for' loops

流过昼夜 提交于 2020-01-07 02:19:25

问题


This piece of code works as I want it to, but in the spirit of good MATLAB code, is there a way to vectorize this (previous is a k x 1 vector):

start = zeros(k,1);
for i = 2:length(previous)
    if (previous(i-1) == -1)
        start(previous(i))= start(previous(i))+1;
    end    
end

What, in general, is the intuitive way to go about vectorizing code in MATLAB?


回答1:


You can do this without find, for maximum performance:

I = [false; previous(1:end-1) == -1];
idx = previous(I);
start(idx) = start(idx) + 1;

This also avoids the risk that previous(end) == -1, which would cause an index out-of-range error in the alternative.

Note that this doesn't work the same as your original if idx contains duplicated indices.




回答2:


Use the find command in MATLAB, which returns the index (i) for which a vector is TRUE. So:

% precache indices i where previous(i-1) == 1
idx = find(previous==-1)+1;
start(previous(idx)) = start(previous(idx))+1;

The reason I precache idx is in case that previous is a big vector and doing the find takes a while. Otherwise you could just do

start( find(previous==-1)+1 ) = start( find(previous==-1) ) + 1;



回答3:


I would do something like:

prev_is_minus1 = [false; previous(1:end-1)==-1]
start = accumarray(previous(prev_is_minus1), 1, k)

I believe this has the same effect as the code loop you posted.



来源:https://stackoverflow.com/questions/8462330/vectorizing-for-loops

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!