2013-03-22 4 views
1

클러스터 색상 값에 대한 자체 구성지도를 학습 중입니다. 이제 노드와 직접 이웃 사이의 유클리드 거리를 표시하기 위해 일종의 U-matrix을 만들고 싶습니다. 내 문제는 지금 내 알고리즘이 상당히 불충분하다는 것이다! 이것을보다 효율적으로 계산하는 방법은 분명히 있을까요?여러 유클리드 거리를 효율적으로 계산하는 방법 Matlab

function displayUmatrix(dims,weights) %#dims is [30 30], size(weights) = [900 3], 
             %#consisting of values between 1 and 0 

hold on; 
axis off; 
A = zeros(dims(1), dims(2), 3); 
B = reshape(weights',[dims(1) dims(2) size(weights,1)]); 
if size(weights,1)==3 
    for i=1:dims(1) 
     for j=1:dims(2) 
      if i~=1 
       if j~=1 
        A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i-1,j-1,:)).^2; 
       end 
       A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i-1,j,:)).^2; 
       if j~=dims(2) 
        A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i-1,j+1,:)).^2; 
       end 
      end 
      if i~=dims(1) 
       if j~=1 
        A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i+1,j-1,:)).^2; 
       end 
       A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i+1,j,:)).^2; 
       if j~=dims(2) 
        A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i+1,j+1,:)).^2; 
       end 
      end 
      if j~=1 
       A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i,j-1,:)).^2; 
      end 
      if j~=dims(2) 
       A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i,j+1,:)).^2; 
      end 
      C(i,j)=sum(A(i,j,:)); 
     end 
    end 
    D = flipud(C); 
    maximum = max(max(D)); 
    D = D./maximum; 
    imagesc(D) 
else 
    error('display function does only work on 3D input'); 
end 
hold off; 
drawnow; 

감사, 최대

+0

각 3 차원을 따라 2D 컨볼 루션 커널을 사용하여 모든 이웃과 모든 점 사이의 TOTAL 거리를 한 번에 얻은 다음이를 정사각형으로 만드는 것이 좋습니다. 하지만, 코드에서 계산 된 거리를 더하기 전에 각 단계마다이를 정사각형으로 표시하기 때문에 원하는 결과인지는 확실하지 않습니다. 그래도 B 행렬에서 여러 가지 컨볼 루션을 수행 할 수 있습니다. 커널 [1 -1; 예를 들어, 모든 B (i, j, :) - B (i-1, j + 1, :)를 한번에 얻을 수있다. (누군가 내가 잘못했으면 바로 잡으십시오.) 그것은 비록 더 빨리 될거라 확신하지 않습니다. – wakjah

+0

빠른 답변 주셔서 감사합니다. 나는 이것이 어떤 식 으로든 코드의 가독성을 향상시킬 것이라고 말합니다. Matlab 설명서에서 살펴 보겠습니다. –

답변

2
당신은만큼 오른쪽으로의 neigbor 각 지점의 (제곱) 거리를 계산할 수 있습니다

: 마찬가지로

sum((B(:,1:end-1,:) - B(:,2:end,:)).^2, 3) 

, 당신이 계산하려면 각 점과 아래 점 및 두 대각선상의 거리. 테두리에있는 모든 값을 가질 필요는 없으므로 0으로 채 웁니다. 그런 다음 거리를 더하고 이웃 수로 나눕니다. 모든 이웃에 평균 거리를 가져야합니다. 그것은 당신의 버전보다 빠르게 처리 될 수 있도록,

%calculate distances to neighbors 
right = sum((B(:,1:end-1,:)- B(:,2:end,:)).^2, 3); 
bottom = sum((B(1:end-1,:,:)- B(2:end,:,:)).^2, 3); zeros(); 
diag1 = sum((B(1:end-1,1:end-1,:)- B(2:end,2:end,:)).^2, 3); 
diag2 = sum((B(2:end,2:end,:)- B(1:end-1,1:end-1,:)).^2, 3); 

%pad them with zeros to the correct size 
rightPadded = [right zeros(dim(1) , 1)]; 
leftPadded = [zeros(dim(1) , 1) right]; 

botomPadded = [bottom; zeros(1,dim(2))]; 
upPadded = [zeros(1,dim(2));bottom]; 

bottomRight = zeros(dim(1), dim(2)); 
bottomRight(1:end-1,1:end-1) = diag1; 
upLeft = zeros(dim(1), dim(2)); 
upLeft(2:end,2:end) = diag1; 

bottomLeft = zeros(dim(1), dim(2)); 
bottomLeft(1:end-1,2:end) = diag2; 
upRight = zeros(dim(1), dim(2)); 
upRight(2:end,1:end-1) = diag2; 

%add distances to all neighbors 
sumDist = rightPadded + leftPadded + bottomRight + upLeft + bottomLeft + upRight; 

%number of neighbors a point has 
neighborNum = zeros(dim(1), dim(2)) + 8; 
neighborNum([1 end],:) = 5; 
neighborNum(:,[1 end]) = 5; 
neighborNum([1 end],[1 end]) = 3; 

%divide summed distance by number of neighbors 
avgDist = sumDist./neighborNum; 

그것은 모든 벡터화 :

여기 내 코드입니다. 정확한 U- 행렬을 원할 경우 평균 거리를 인접 거리로 인터리브 할 수 있습니다.

+0

멋지게 완료되었습니다. 덕분에 시간 복잡성에 많은 도움이되었습니다. –