是否可以对通过不同索引映射的循环进行矢量化?例如:
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
提供输出:
a = [5 0 2+6 1 3+4] = [5 0 8 1 7]
这可以在没有for
循环的情况下完成吗?
答案 0 :(得分:2)
这是accumarray
的经典案例。 accumarray
通过提供一组键和与每个键相关联的一组值来工作。 accumarray
对属于同一个键的所有值进行分组,并对所有值执行某些操作。默认行为是将属于同一个键的所有值相加,这就是您所追求的。
在您的情况下,m
是键,f
是您要添加的属于同一个键的值。因此:
>> a = accumarray(m(:), f(:))
a =
5
0
8
1
7
通常,您可能缺少密钥。因此,您可以选择指定输出数组的输出维度,它应该是m
中显示的最大键值:
a = accumarray(m(:), f(:), [max(f(:)), 1]);
这当然假设f
由严格正值组成。
通常,如果您在f
中有浮点数,那么开箱即用的accumarray
将无效,因为假设键是严格正整数。但是,常见的诀窍是为f
的每个值分配唯一ID,并将其用作accumarray
的输入。 unique
的第三个输出应该为您执行此操作。您还需要unique
的第一个输出来帮助您确定哪个总和属于哪个键:
[msorted,~,id] = unique(m);
a = accumarray(id, f(:));
out = [msorted a];
out
将包含一个2列矩阵,其中每一行都为m
提供了一个唯一值,以及m
中共享相同键的所有值的相关总和。