向量化子数组的加法
Vectorizing addition of subarray
假设我有两个大小相同的(大)向量 a=[0 0 0 0 0]
和 b=[1 2 3 4 5]
以及一个索引向量 ind=[1 5 2 1]
,其值在 {1,...,length(一种)}。我想计算
for k = 1:length(ind)
a(ind(k)) = a(ind(k)) + b(ind(k));
end
% a = [2 2 0 0 5]
也就是说,我想将ind
中声明的b
的条目添加到a
中,包括多重性。
a(ind)=a(ind)+b(ind);
% a = [1 2 0 0 5]
当然要快得多,但会忽略出现多次的索引。
我怎样才能加快上面的代码?
我们可以使用 unique
来识别唯一索引值,并使用第三个输出来确定 ind
的哪些元素共享相同的索引。然后我们可以使用 accumarray
对共享相同索引的 b
的所有元素求和。然后我们将这些添加到这些位置的 a
的原始值。
[uniqueinds, ~, inds] = unique(ind);
a(uniqueinds) = a(uniqueinds) + accumarray(inds, b(ind)).';
如果 max(inds) == numel(a)
那么这可以简化为以下内容,因为 accumarray
将简单地 return 0
对于 ind
中的任何缺失条目。
a(:) = a(:) + accumarray(ind(:), b(ind));
基于accumarray
的另一种方法:
a(:) = a(:) + accumarray(ind(:), b(ind(:)), [numel(a) 1]);
工作原理
accumarray
以两个列向量作为输入聚合对应于第一个相同索引的第二个输入的值。第三个输入在这里用于强制结果与 a
大小相同,如果需要用零填充。
假设我有两个大小相同的(大)向量 a=[0 0 0 0 0]
和 b=[1 2 3 4 5]
以及一个索引向量 ind=[1 5 2 1]
,其值在 {1,...,length(一种)}。我想计算
for k = 1:length(ind)
a(ind(k)) = a(ind(k)) + b(ind(k));
end
% a = [2 2 0 0 5]
也就是说,我想将ind
中声明的b
的条目添加到a
中,包括多重性。
a(ind)=a(ind)+b(ind);
% a = [1 2 0 0 5]
当然要快得多,但会忽略出现多次的索引。
我怎样才能加快上面的代码?
我们可以使用 unique
来识别唯一索引值,并使用第三个输出来确定 ind
的哪些元素共享相同的索引。然后我们可以使用 accumarray
对共享相同索引的 b
的所有元素求和。然后我们将这些添加到这些位置的 a
的原始值。
[uniqueinds, ~, inds] = unique(ind);
a(uniqueinds) = a(uniqueinds) + accumarray(inds, b(ind)).';
如果 max(inds) == numel(a)
那么这可以简化为以下内容,因为 accumarray
将简单地 return 0
对于 ind
中的任何缺失条目。
a(:) = a(:) + accumarray(ind(:), b(ind));
基于accumarray
的另一种方法:
a(:) = a(:) + accumarray(ind(:), b(ind(:)), [numel(a) 1]);
工作原理
accumarray
以两个列向量作为输入聚合对应于第一个相同索引的第二个输入的值。第三个输入在这里用于强制结果与 a
大小相同,如果需要用零填充。