MATLAB:vectorize for-loop包含circshift

时间:2016-09-20 15:34:59

标签: performance matlab vectorization

我有以下for循环,我想要矢量化。但是,在for-loop里面我使用了circshift。有没有办法使用矢量化执行for循环,或至少优化它?它运行得很慢,因为strt,stop和M会增加它们的大小。

indx = 0;

M = magic(16);
v = M(:,1);

strt=-5;
stop=+5;

result = zeros(4, length(strt:stop), 4);
for ii=strt:stop
    tmp = circshift(M, [0 ii])*v;
    tmp = tmp/norm(tmp);

    indx = indx+1;
    result(:, indx, :) = reshape( tmp(:,1), 4,4);
end

3 个答案:

答案 0 :(得分:2)

2D数组Mcircshift一起转移肯定会很昂贵。因此,一个技巧可能是转移到1D数组v而不是另一个方向,并保持M不变。因此,我们只需要一个编辑来替换:

circshift(M, [0 ii])*vM*circshift(v,-ii)

M作为(2500 x 2500)大小的数组的运行时间与我原来的和建议的方法一样 -

----------------------- With Original approach
Elapsed time is 0.803823 seconds.
----------------------- With Proposed approach
Elapsed time is 0.137444 seconds.

答案 1 :(得分:2)

当您增加M的大小时,函数circshift将成为代码中最耗时的部分。这个时间随着规模的增加而增加。

一个有用的步骤是将circshift(M, [0 ii])*v更改为M*circshift(v,-ii)。请注意,它们会生成相同的tmp,但第二个会处理v,这只是M的一列。

答案 2 :(得分:1)

这可以表示为2D卷积,因此此代码在Octave中进行了测试,对于Matlab,需要进行一些更改,这些更改需要在评论中解释:

%temp created however order of column reversed relative to  your 'tmp'
temp=conv2([M M(:,1:10)] , circshift(flipud(v).', [0 , 5]),'valid');
%only availabe in Octave. Norm of columns computed . In Matlab use for loop to compute norm of each column
nrm=norm(temp,'cols');
%divide temp by norm
temp = bsxfun(@rdivide,temp,nrm);
% The result. Order of slices reversed
result = reshape(temp,[4,4,size(temp,2)])