Row sums by vector indices without for loop?
Afficher commentaires plus anciens
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'
Réponse acceptée
Plus de réponses (1)
Bruno Luong
le 7 Fév 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 commentaires
Jan
le 7 Fév 2011
Did you compare the speed with the OP's FOR loop method with adding a pre-allocation?
Bruno Luong
le 8 Fév 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);
Catégories
En savoir plus sur Programming dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!