2014-10-14 2 views
4

내가matlab에 : 행렬과 Arrayfun

A = ones(3,3,3) 
for i = 1:3 
    B(i) = trace(A(:,:,i)); 
end 

arrayfun 내가 희망

f = @(x) trace(x) 
B = arrayfun(f, A); 

을 시도하여 다음과 같은 코드를 다시 작성하려고하지만 이것은 단지 (당신이 기대하는 것처럼) 각각의 A(i,j,k)하지 이상 추적 A(:,:,i) 내가 원하는대로. 그런 다음 A{i}=ones(3,3)을 셀로 지정하고 arrayfun으로 전달하려고 시도했지만이 방법도 작동하지 않았습니다.

Matlab의 행렬에 함수를 벡터화하려면 어떻게해야합니까?

+0

여기 제공된 솔루션 중 하나가 유용하면 궁금하십니까? – Divakar

+0

안녕하세요, Divikar, 솔루션은 작동하지만 어느 누구도 제가 테스트 할 수있는 GPU에서 행렬의 함수를 벡터화하는 일반적인 방법을 제공하지 않습니다. 불행히도 내가 액세스 할 수있는 서버는'pagefun'없이 Matlab 버전을 실행하고 있지만 목요일에 업그레이드 될 예정입니다. – rwolst

답변

5

bsxfun AB (사용)을 정의하는 방법을 trace 기반 벡터화 솔루션 - sum of diagonal elements -

%// Get size of A 
[m,n,r] = size(A) 

%// Get indices of the diagonal elements for each 3D "slice" as columns of idx 
idx = bsxfun(@plus,[1:m+1:m*n]',[0:r-1]*m*n) %//' 

%// Thus, for your 3 x 3 x 3 case, idx would be - 
%//idx = 
%//  1 10 19 
%//  5 14 23 
%//  9 18 27 
%// and these are the linear indices to the diagonal elements to each `3D` slide. 

%//Index into A with idx and sum along columns to get each element of desired output 
B = sum(A(idx),1) 

당신이 추가 그다지 필요하지와의 혼란을 작업 공간에 저장하려는 경우 변수, 피하기 idx with -

B = sum(A(bsxfun(@plus,[1:m+1:m*n]',[0:r-1]*m*n)),1) 

GPU를

당신이 GPUs 작업을해야하는 경우

작업을 위해

, 당신은 다음 A을 포함하는 후속 작업을 GPU에서 수행 될 것이다, gpuArray(A)와 gpuArrays로를 선언 할 수 있습니다 그리고 당신은 gpuArray으로 출력을 얻을 것입니다, 다시 gather(..)으로 CPU 변수로 되돌릴 수 있습니다.

따라서, 전체 코드는 다음과 같이 보일 것이다 -

[m,n,r] = size(A); %// Get size 
gpu_A = gpuArray(A); %// copy data from CPU to GPU 

%// Perform calculations on GPU 
gpu_B = sum(gpu_A(bsxfun(@plus,[1:m+1:m*n]',[0:r-1]*m*n)),1); %//' 

B = gather(gpu_B); %// get back output onto CPU 

빠른 검사 :를 GTX 750 티 (나는에 액세스 할 수 있는지), 이것은 당신의 정신이 이상한 코드를 통해 나에게 3 배의 속도 향상을 제공하기 위해 나타납니다 .

5

당신이 정말로이 같은 트릭을 시도 할 수 arrayfun을 사용하려면 :

arrayfun(@(i)trace(A(:,:,i)), 1:size(A,3)) 

을하지만 arrayfun하지 벡터 라이! 떨어져 있음을 알아, 그것은 루프 단지 래퍼의 자주보다 느리다 추가 된 오버 헤드로 인한 루프.

벡터화는 아니지만 두 번째 방법은 cellfun으로 변경해야합니다. 즉 A{i} = ones(3,3) 경우

cellfun(@(x)trace(x), A) 
+1

GPU에서 코드를 실행하면서'arrayfun'을 사용하고 싶었습니다. 'arrayfun' 래퍼가이 경우에 계산 속도를 빠르게한다고 생각하는 것이 맞습니까? – rwolst

+0

@rwolst'pagefun'은 GPU의'araryfun'과 같습니다. 그래도 그 공식 문서를보고 그 사실을 확인하십시오. – Divakar

+2

@Divakar : 아니요,'arrayfun'은 루프를 GPU에 푸시 (push)하는 좋은 방법입니다. 물론, 병렬화 오버 헤드에 관한 일반적인주의 사항이 적용됩니다. – Jonas