2016-05-31 6 views
4

동일한 크기의 두 개의 (큰) 벡터 a=[0 0 0 0 0]b=[1 2 3 4 5]과 {1, ..., length (a)}의 값을 가진 하나의 인덱스 벡터 ind=[1 5 2 1]이 있다고 가정 해 봅시다. 내가 즉서브 어레이의 벡터화 추가

for k = 1:length(ind) 
    a(ind(k)) = a(ind(k)) + b(ind(k)); 
end 
% a = [2 2 0 0 5] 

계산 싶습니다, 나는 다양성을 포함 aind 선언 b의 해당 항목을 추가 할 수 있습니다.

a(ind)=a(ind)+b(ind); 
% a = [1 2 0 0 5] 

은 물론 더 빠르며 여러 번 나타나는 색인을 무시합니다.

어떻게 위 코드를 빠르게 할 수 있습니까?

+0

여러 번 나타나는 색인에 대해 예상되는 동작은 무엇입니까? 이 색인에 한 번만 추가 하시겠습니까? – drorco

+0

아니요, 자주 나타나는대로 색인을 추가하고 싶습니다. 위의 for 루프와 같습니다. – Julian

+0

왜 나는 (ind) + b (ind)가 여러 번 나타나는 인덱스를 무시하는지 이해하지 못합니다. – GameOfThrows

답변

5

unique을 사용하여 고유 색인 값을 식별하고 세 번째 출력을 사용하여 ind의 어떤 요소가 동일한 색인을 공유하는지 확인할 수 있습니다. 그런 다음 accumarray을 사용하여 동일한 색인을 공유하는 b의 모든 요소를 ​​합계 할 수 있습니다. 이 위치에 원래 값인 a을 추가합니다.

[uniqueinds, ~, inds] = unique(ind); 
a(uniqueinds) = a(uniqueinds) + accumarray(inds, b(ind)).'; 

accumarray 단순히 ind에서 누락 된 항목에 대한 0를 반환하기 때문에 max(inds) == numel(a) 다음이 다음에 간단하게 할 수 있다면. 그 입력으로하여 두 개의 열 벡터로

accumarray 작동 방법

a(:) = a(:) + accumarray(ind(:), b(ind(:)), [numel(a) 1]); 

을 동일한 인덱스에 대응하는 제 2 입력 값을 합산 :

a(:) = a(:) + accumarray(ind(:), b(ind)); 
+0

결과는''[13 12 9]''입니다. – Julian

+0

@Julian 죄송합니다. 업데이트되었습니다. – Suever

+0

이것은 여전히''[15 14 9]''라고 생각합니다. – Julian

3

다른 접근법 accumarray에 기초 먼저. 세 번째 입력은 여기에 사용되어 결과가 a과 동일한 크기가되도록하고 필요에 따라 0으로 채 웁니다.

+1

멋진 점, 나는 항상 세 번째 입력을 잊어 버린다! – Suever