向量化属于组的求和值

时间:2015-04-13 17:03:26

标签: matlab vectorization

是否可以对通过不同索引映射的循环进行矢量化?例如:

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循环的情况下完成吗?

1 个答案:

答案 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中共享相同键的所有值的相关总和。