2013-10-26 6 views
0

나는 이번 주에 질문 한 질문을 재발행했으며, 누락 된 태그로 인해 주목받지 못했습니다 (기본적으로 그것은 나만 볼 수있었습니다).Matlab - 주어진 인덱스를 기반으로하는 벡터의 요소 그룹 합계

두 개의 큰 벡터, 값 및 색인이 있습니다.

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 

더 나은 솔루션이다 :

% 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 
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 항 분배). 2) 사용 된 인덱스 만 생성하십시오.

+0

값 및 인덱스가 입력 변수이며 주어진 값입니다 ... 물론 두 번째 솔루션에서 제안 된 것처럼 accumarray를 사용하여 조작 할 수 있습니다. –