MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn moreOpportunities for recent engineering grads.

Apply Today
Asked by Maximilian on 11 Dec 2012

Hi guys,

does anybody have an idea how I could speed up the following loop:

Havg = zeros(1, length(Gsum)); for k=1:K Havg = Havg + circshift(Gsum, [0 numBlocks*M*(k-1)]); end

Here, length(Gsum)=280000 and K=1200. NumBlocks equals 10 and M=14. This loop is very slow. However, I did not find a way to use the MATLAB-specific vector processing to speed it up.

How can I speed up the loop, e.g. with MATLABs powerful vector processing?

Regards, Max

*No products are associated with this question.*

Answer by Matt J on 11 Dec 2012

Accepted answer

If Gsum is sparse, there may be better ways than the following fft-based method:

numBlocks=10; M=14; N=length(Gsum); K=1200;

f=@(t) mod(t-1,N)+1; shifts = f(1:numBlocks*M:numBlocks*M*(K-1)+1); comb=accumarray(shifts.',1,[N,1]).'; Havg=ifft(fft(Gsum).*fft(comb),'symmetric');

Maximilian on 12 Dec 2012

Thank you for this fft-based idea. The code works well and much faster than the original version.

Answer by Roger Stafford on 11 Dec 2012

As your code is now, you are performing 280,000 X 1,200 = 336,000,000 additions. You can cut down the number of flops by a factor of about 1/333 with the use of matlab's 'cumsum' function.

p = 140; q = 2000; r = 1200; Havg = reshape(Gsum,p,q); Havg = cumsum([zeros(p,1),Havg,Havg(:,1:r-1)],2); Havg = reshape(Havg(:,r+1:r+q)-Havg(:,1:q),1,[]);

It should be noted, however, that the above reduction in the number of flops comes at the cost of increased round-off error accumulated by 'cumsum' over q+r = 3200 steps in each of the 140 rows in the next-to-last line.

Roger Stafford

## 2 Comments

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/56286#comment_116564

How slow is very slow? I assume Gsum is a row vector?

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/56286#comment_116577

Is Gsum sparse?