2014-10-08 2 views
2

그래서 오늘벡터화 블록 (어떤 의미)이 실패

A_TEST(dest,:)=A_TEST(source,:)+A_TEST(dest,:); 
A_TEST(:,dest)=A_TEST(:,source)+A_TEST(:,dest); 

이명 령이 고유하지 않은 경우이 버그에 달렸다 값. 그래서 내 빠른 수정은 끝났어 for 루프를 수행하는 것입니다

for (k=1:numel(dest)) 
    A(dest(k),:)=A(source(k),:)+A(dest(k),:); 
    A(:,dest(k))=A(:,source(k))+A(:,dest(k)); 
end 

그리고 matlab은 루프에 좋지 않습니다. 이 호출을 어떻게 벡터화할까요?

+0

죄송합니다. 다중성을 원하니? – Sheljohn

+1

나는 다양성을 원해. 출처는 고유하지만 도착지는 아닙니다. – IdeaHat

+1

Matlab은 루프에서 나쁘지 않으며 JIT 컴파일을 사용합니다. 특히 단순 루프에서는 벡터화 된 코드만큼 효율적입니다. – David

답변

3

다음은 행을 처리하는 방법을 보여줍니다. 열을 사용하여이 작업을 수행하는 방법은 비슷하지만 코드는 다르므로 그 이유를 설명하겠습니다.

요약하면 n 행과 p 열이있는 행렬 A가 있습니다. [1,n], srcdst의 idem 범위의 정수 목록이 있습니다. 둘 다 같은 크기를 가지고 있고 n 개 이상의 요소가 포함될 수 있으므로 (둘 다 잠재적으로 반복 될 수 있도록)

dst으로 그룹화하면 이야기하는 작업이 행의 선형 재조합과 동일하다는 것은 분명합니다. 이것은 n x n 행렬에 의한 사전 곱셈에 해당하며, 요소 (i,j) = k은 "대상 행 i에 해당하는 재조합에 다중도 k가있는 행 j가 들어 있음"을 의미합니다.

function A = madScience(A, src, dst) 

    n = size(A,1); 
    M = eye(n); 

    ix = sub2ind([n,n], dst, src); 

    [ux,~,mlt] = unique(ix); 
    nux = length(ux); 
    mlt = accumarray(mlt(:), 1, [nux,1]); 

    M(ux) = M(ux) + mlt'; 
    A  = M*A; 

end 

주 1 :

다음 코드가 무엇을 당신이 게시물에 제공 두 코드 하지 동일을, 2 개의 별도의 for 루프가 필요합니다.

주 2 열에 동일한 조작 소자 (i,j) = k 의미하는 행렬 승산 후 동등 '항목 J에 대응하는 다수의 재조합과 K I 열 포함 ".

참고 3 : A가 정사각형 인 경우 두 작업은 동일한 행렬 M ((M*A) * M')으로 수행 할 수 있습니다 (괄호가 중요 함).

+0

꽤 똑똑한 접근! +1 – Divakar

+0

좋은 ... 나는 그것이 일종의 축적 광기 일 것이라고 생각했다. – IdeaHat

+1

원래 게시물에서 언급하지 않은 점은 매트릭스가 실제로 대각선으로 반원 모양 (가중치가있는 인접 매트릭스)이라는 점이었습니다. 행 조합만으로이 모든 작업을 수행 할 수 있습니다 ... nice! – IdeaHat