Clever solution sought: Summing values from an array into a vector component given in a second array
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
Matthew Masarik
el 22 de Ag. de 2014
Editada: per isakson
el 22 de Ag. de 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 comentarios
Respuesta aceptada
Más respuestas (2)
Roger Stafford
el 22 de Ag. de 2014
You might try using accumarray:
A = accumarray(indArray(:),valArray(:),[M,1]);
0 comentarios
per isakson
el 22 de Ag. de 2014
Editada: per isakson
el 22 de Ag. de 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 comentarios
Ver también
Categorías
Más información sobre Logical en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!