2014-04-29 2 views
0

동일한 행 수의 2 행렬을 취하여 스칼라 값을 구하는 함수가 f입니다. 이제는 두 개의 행렬 목록을 취하고 모든 쌍에 f을 호출하는 새 함수를 만들 가능성을 찾고 있습니다.모든 쌍의 행렬을 계산하십시오.

나는이 루프의 무어 효율적인 구현이 필요합니다

% X = cell of matrices 
% Y = cell of matrices 
for k=1:length(X) 
    for l=1:length(Y) 
     M(k,l) = f(X{k},Y{l}); 
    end 
end 

제곱 거리

을의 평균 수 예를 f를 들어

(그것은 X와 Y는 세포 인 요구 사항은 아닙니다)

f = @(X,Y) mean(mean(bsxfun(@plus,dot(X,X,1)',dot(Y,Y,1))-2*(X'*Y))); 

그러나 질문이 없습니다 f, 그것은 훨씬 더 복잡한 문제의 예일뿐입니다.

+1

'f'에 대한 질문은 아마도 효율성을 향상시키는 가장 중요한 방법 일 것입니다. 'f'가 두 개의 n-by-m 행렬을 취하여 하나의 스칼라를 생성하지만, 두 개의 nx mx2 행렬을 취하여 두 개의 요소 벡터를 생성 할 수 있도록 작성 될 수 있습니다. 아마도 최선의 선택입니다. – Dan

+0

@ Dan의 질문에 더 많은 것들을 추가하는 것은 순수한 내 견해입니다. 아마도 당신이 사용하고있는 기능 중 하나를 공유 할 수있을 것입니다. 복잡하다고 했으므로 새로운 질문을 할 수도 있습니다. – Divakar

+0

Thx. 불행히도 함수 f (많은 함수가 있습니다)가 내 통제하에 있지 않습니다. 위에서 설명한대로 새로운 함수로 래핑 할 수 있습니다. –

답변

5

먼저 M을 사전 할당해야합니다. 그럼 당신은 X와 Y의 모든 요소 쌍의 목록 생성 meshgrid를 사용하여 아주 쉽게 하나 개의 루프를 잘라 수 있습니다 : 당신이 그렇게 제대로 벡터화되어 f을 구현할 수있는 경우에, 그러나

[K, L] = meshgrid(1:length(X), 1:length(Y)); 

M = zeros(size(K)); %//This preallocation alone should give you a significant speed up 
for ii = 1:numel(K) 
    M(ii) = f(X{K(ii)},Y{L(ii)}); 
end 

을, 당신은 수 있습니다 두 개의 3D 행렬, 즉 X와 Y 쌍의 전체 목록을 전달할 수 있고 전혀 루프없이 수행 할 수 있습니다. 그러나 이것은 당신의 f이하는 일에 전적으로 의존합니다. 내가 이것을 할 수있는 더 좋은 방법이 생각하지만 cellfun에게

fy = @(x,Y) cellfun(@(y) f(x,y), Y); 
fx = @(X,Y) cellfun(@(x) fy(x,Y), X, 'UniformOutput', false); 
newF = @(X,Y) cell2mat(fx(X,Y)')'; 

을 사용하고 작동 가능한 솔루션에

+0

2 개의 for (큰) 행렬을 생성하는 비용으로 두 개의 for 루프를 하나로 변환하면 속도가 빨라 집니까? –

+0

아니요. 앞서 언급했듯이 (다른 답변에 대한 의견에 있음에도 불구하고) 방법이 Matlab의 속도면에서 효율적인지를 판단 할 수있는 유일한 방법은'timeit' 또는'tic'과'toc'를 사용하여 테스트하는 것입니다. 또한 OP는 Matlab이 행렬을 할당하는 방식 인 것처럼 두 개의 루프를 전환하여 속도를 높일 수도 있습니다. 그러나 나는 메모리를 미리 할당하는 것이 비용을 전혀 들이지 않고 가장 큰 차이를 만들 것이라고 생각한다. – Dan

+0

왜 downvote ??? – Dan

0

.

+0

이 방법을 두 루프 방법과 비교하고 내 사전 할당 + 루프 방법과 비교해 본 적이 있습니까? 나는 당신이'timeit' 함수 (2013b가 없다면 파일 교환에서 사용 가능)를 사용하거나 단순히 루프와'tic'과'tic'을 사용하여 그것을 할 것을 제안한다. 이것이 가장 효과적인 방법을 알 수있는 유일한 방법입니다. – Dan

관련 문제