Построить трехмерную матрицу расстояний наименьших квадратов без петель? - PullRequest
1 голос
/ 05 февраля 2012

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

Например, для 3d матрицы d,

d(m,n,o)=(vec1(m)-vec2(n))^2+(vec1(m)-vec3(o))^2+(vec2(n)-vec1(o))^2

В настоящее время я делаю это с тройным циклом for:

d=zeros(N,M,O);
for o=1:O
    for n=1:N
        for m=1:M
            d(n,m,o)=(((t(n)-r(m))^2)+((t(n)-z(o))^2)+((r(m)-z(o))^2));
        end
    end
end

У меня вопрос: есть ли более быстрый и умный способ сделать это, например, для 2D-версии, которую я мог бы использовать:

%for n=1:N
%    for m=1:M
%        d(n,m)=(t(n)-r(m))^2;
%    end
%end
d=(repmat(t(:),1,M)-repmat(r(:)',N,1)).^2; %this replaces the nested for loops from       above Thanks Georg Schmitz

Кто бы ни был Георг Шмитц, он придумал способ использовать repmat для замены двойных циклов for в 2d версии. Конечно, я мог бы адаптировать этот метод и заменить мой тройной цикл for одним циклом for, который повторяет метод repmat (o) несколько раз, но я чувствую, что должен быть способ сделать это без циклов.

Есть идеи? Спасибо

Ответы [ 2 ]

1 голос
/ 05 февраля 2012

Вы действительно можете векторизовать расчет:

%# properly reshape the vectors
vec1 = vec1(:); %# n-by-1
vec2 = reshape(vec2,1,[]); %# 1-by-m
vec3 = reshape(vec3,1,1,[]); %# 1-by-1-by-o 

%# use bsxfun to efficiently replicate the arrays
d = bsxfun(@plus,bsxfun(@plus,...
    bsxfun(@minus,vec1,vec2).^2,...
    bsxfun(@minus,vec2,vec3).^2)),...
    bsxfun(@minus,vec3,vec1).^2));
0 голосов
/ 09 мая 2015

Вы должны попробовать pdist или pdist2 в зависимости от ваших потребностей.pdist вычисляет внутренние расстояния, в то время как pdist2 вычисляет матрицу попарных расстояний.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...