2013-03-22 3 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

Я предлагаю вам использовать двумерное ядро ​​свертки вдоль каждого из трех измерений, чтобы получить ОБЩЕЕ расстояние между каждой точкой и ВСЕ его соседей одновременно, а затем квадратное. Я не уверен, что это то, что вы хотите, хотя, потому что в вашем коде вы делаете квадрат на каждом шаге перед добавлением вычисленного расстояния. Тем не менее, вы можете сделать несколько сверток на вашей матрице B, например. с ядром [1 -1; 0 -1], чтобы получить, например, все B (i, j, :) - B (i - 1, j + 1, :) за один раз. (Кто-то, пожалуйста, поправьте меня, если я ошибаюсь). Не уверен, что все будет быстрее. – wakjah

+0

Спасибо за быстрый ответ. Я бы сказал, что это каким-либо образом улучшит читаемость кода. Я посмотрю это в документации Matlab. –

ответ

2

Вы можете вычислить (квадрат) расстояние каждой точки к ее neigbor вправо на:

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

Аналогично, вы вычислить расстояние каждой точки до точки ниже и на обеих диагоналях. У вас нет всех этих значений для точек на границах, чтобы вы их заполняли нулями. Затем вы добавляете расстояния и делите их на количество соседей, точка должна получить среднее расстояние до всех соседей.

Вот мой код:

%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

Приятно, спасибо, это очень помогло во временной сложности! –

Смежные вопросы