Row sums by vector indices without for loop?
Show older comments
Best illustrated by example
M=rand(5,10);
s=[1 3; 5 8; 9 10];
for i=1:size(s,1)
sm(:,i)=sum(M(:,s(i,1):s(i,2)),2);
end
Is there a one-liner or short-cut for the for loop? I do not know how large M or s is ahead of time, or their values. Above code shown only for illustration of problem trying to solve.
Thanks!
edit: Corrected typo of 'm' in for-loop to 'M'
Accepted Answer
More Answers (1)
Bruno Luong
on 7 Feb 2011
Yes, to be more specific my mcolon on FEX
can be used like this:
% Data
M = ceil(10*rand(5,10))
s = [1 3; 5 8; 9 10];
% Engine
[a i] = mcolon(s(:,1),s(:,2));
[r c] = ndgrid(1:size(M,1),i);
Ma = M(:,a);
sm = accumarray([r(:) c(:)], Ma(:))
Bruno
2 Comments
Jan
on 7 Feb 2011
Did you compare the speed with the OP's FOR loop method with adding a pre-allocation?
Bruno Luong
on 8 Feb 2011
Following Jan's question: I make the following test and I get the 25% acceleration by using MCOLON
Time relative for-loop/mcol = 1.26013/1
% Code
ntest = 10;
t = zeros(2,ntest);
for n=1:ntest
s = ceil(10*rand(1,2*10000));
s = cumsum(s);
s = reshape(s, 2, [])';
M=rand(5,s(end));
% for loop Engine
tic
sm = zeros(size(M,1),size(s,1));
for i=1:size(s,1)
sm(:,i)=sum(M(:,s(i,1):s(i,2)),2);
end
t(1,n) = toc;
% mcolon Engine
tic
[a c] = mcolon(s(:,1),s(:,2));
[r c] = ndgrid(1:size(M,1),c);
Ma = M(:,a);
sm = accumarray([r(:) c(:)], Ma(:));
t(2,n) = toc;
end
t = min(t,[],2);
t = t/min(t);
fprintf('Time relative for-loop/mcol = %g/%g\n', t);
Categories
Find more on Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!