Clever solution sought: Summing values from an array into a vector component given in a second array
3 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Matthew Masarik
am 22 Aug. 2014
Bearbeitet: per isakson
am 22 Aug. 2014
I have two arrays -- an array of indices and an array of values, both are K x M. The index array has values between 1:M. Now I want to obtain the vector whose jth component is sum( valArray( indArray == j ) ).
Can you think of way to do this that beats the simple for loop solution? I have a couple of bsxfun solutions to do the ( indArray == j ) in one shot, but those don't beat the for loop. I also have a way to do this using a sparse array, but that doesn't beat the for loop either.
Here's code to set up the problem and find the answer using a for loop:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%NOTE: set M and K to be much larger for the real problem
M = 10;
K = 5;
indArray = randi(M,[K M]);
valArray = rand([K M]);
result = zeros(M,1);
for ii = 1 : M * K
temp = indArray(ii);
result(temp) = result(temp) + valArray(ii);
end
Thanks for taking a look.
0 Kommentare
Akzeptierte Antwort
Weitere Antworten (2)
Roger Stafford
am 22 Aug. 2014
You might try using accumarray:
A = accumarray(indArray(:),valArray(:),[M,1]);
0 Kommentare
per isakson
am 22 Aug. 2014
Bearbeitet: per isakson
am 22 Aug. 2014
Yes, accumarray beats the loop for large arrays (R2013a)
M = 2e3;
K = 5e3;
ix = randi(M,[K,M]);
val = rand([K,M]);
tic
out = zeros(M,1);
for ii = 1 : M * K
out(ix(ii)) = out(ix(ii)) + val(ii);
end
toc
tic
acc = accumarray( ix(:), val(:), [], @sum );
toc
assert( all( abs(out-acc)<1e-6 ), 'A:B:C', 'Results differ' )
returns
Elapsed time is 0.330848 seconds.
Elapsed time is 0.179041 seconds.
 
However
M = 100;
K = 40;
returns
Elapsed time is 0.000125 seconds.
Elapsed time is 0.000258 seconds.
0 Kommentare
Siehe auch
Kategorien
Mehr zu Loops and Conditional Statements finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!