おそらくワンライナーほどエレガントではありませんcellfun
が、桁違いに速く実行されます。
sums = cumsum(M([index{:}]));
sums = diff([0, sums(cumsum(cellfun('length', index)))]);
大規模な入力の場合、JIT で高速化されたループよりも約 4 倍または 5 倍速く実行されます。の各セルにindex
~2000 を超える要素を持つベクトルが含まれている場合、このアプローチのパフォーマンスはループ (およびcellfun
) と比較して低下し始めることに注意してください。
基準
M = rand(2103, 2030);
I = ceil(numel(M) * rand(2032, 10));
index = mat2cell(I, ones(size(I, 1), 1), size(I, 2));
N = 100;
tic
for k = 1:N
sums = zeros(1, numel(index));
for n = 1:numel(sums)
sums(n) = sum(M(index{n}));
end
end
toc
tic
for k = 1:N
sums = cellfun(@(idx) sum(M(idx)), index);
end
toc
tic
for k = 1:N
sums = cumsum(M([index{:}]));
sums2 = diff([0, sums(cumsum(cellfun('length', index)))]);
end
toc
これを MATLAB 2012a (2.27 GHz 16 コア Intel Xeon プロセッサで実行されている Windows Server 2008 R2) で実行すると、次の結果が得られました。
Elapsed time is 0.579783 seconds.
Elapsed time is 1.789809 seconds.
Elapsed time is 0.111455 seconds.