Clever solution sought: Summing values from an array into a vector component given in a second array
1 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
更多回答(2 个)
Roger Stafford
2014-8-22
You might try using accumarray:
A = accumarray(indArray(:),valArray(:),[M,1]);
0 个评论
per isakson
2014-8-22
编辑:per isakson
2014-8-22
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 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!