2013-10-26 3 views
0

Я перепробовал вопрос, который я задал на этой неделе, и что из-за отсутствующего тега не осталось незамеченным (в основном это рассматривалось только мной).Matlab - группы сумм элементов вектора, основанные на данных индексов

У меня есть два больших вектора, значения и индексы. Мне нужно суммировать элементы значений с использованием индексов, как в этом грубом примере силы:

% The two vectors, which are given, look like this: 
N = 3e7; 
values = (rand(N, 1) > 0.3); 
indices = cumsum(ceil(4*rand(N, 1))); 
indices = [0; indices(find(indices > 1, 1, 'first'):find(indices < N, 1, 'last')); N]; 
HH = numel(indices) - 1; 

% This is the brute force solution 
tic 
out1 = zeros(HH, 1); 
for hh = 1:HH 
    out1(hh) = sum(values((indices(hh)+1):indices(hh+1))); 
end 
toc 

Более эффективный способ сделать это состоит в следующем:

tic 
indices2 = diff(indices); 
new_inds = (1:HH+1)'; 
tmp = zeros(N, 1); 
tmp(cumsum(indices2)-indices2+1)=1; 
new_inds_long = new_inds(cumsum(tmp)); 
out2 = accumarray(new_inds_long, values); 
toc 

Лучшее решения:

tic 
out3 = cumsum(values); 
out3 = out3(indices(2:end)); 
out3 = [out3(1); diff(out3)]; 
toc 

три раствора эквивалентны

all(out1 == out2) 
all(out1 == out3) 

Вопрос: так как это действительно основная функция, есть ли более быстрый, уже известный подход/функция, который делает то же самое и что я могу игнорировать или что я просто не знаю?

ответ

0

Если вы создаете свои индексы, это не просто манекен для другого, это может быть улучшено. В настоящее время вы тратите 3/4 от сгенерированных номеров. 1) Определите количество индексов, которые вы хотите (биномиальное распределение) 2) генерируете только используемые индексы.

+0

Я не понимаю: значения и индексы являются моими входными переменными, и они даны ... Конечно, я могу ими манипулировать (как во втором предложенном решении, использующем накопитель). –

Смежные вопросы