Is it possible to vectorize a loop that goes through different index mappings? For example:
a = zeros(1, 5);
m = [4 3 5; 5 1 3];
f = [1 2 3; 4 5 6];
for ii = 1:size(m,1)
a(m(ii,:)) = a(m(ii,:)) + f(ii,:);
end
Gives output:
a = [5 0 2+6 1 3+4] = [5 0 8 1 7]
Can this be done without the for
loop?
This is a classic case of
accumarray
.accumarray
works by providing a set of keys and a set of values associated with each key.accumarray
groups all values that belong to the same key and does something to all of the values. The default behaviour is to sum all of the values that belong to the same key together, which is what you're after.In your case,
m
are the keys andf
are the values you want to add up that belong to the same key. Therefore:In general, you may have keys that are missing. Therefore, you may opt to specify the output dimensions of the output array where it should be the maximum key value seen in
m
:This is of course assuming that
f
consists of strictly positive values.In general, if you have floating point numbers in
f
, thenaccumarray
out of the box won't work because the keys are assumed to be strictly positive and integer. However, a common trick is to assign a unique ID to each value off
and use this as the input intoaccumarray
. The third output ofunique
should do this for you. You'll also need the first output ofunique
to help you figure out which sum belongs to what key:out
will contain a 2 column matrix where each row gives you a unique value inm
and the associated sum for all values that shared the same key inm
.