0

我有一个矩阵a,我想计算从一个点到所有其他点的距离。所以实际上结果矩阵应该有一个零(在我选择的点)并且应该显示为围绕该特定点的某种数字圆圈。

这是我已经拥有的,但我似乎无法得到正确的结果。

a = [1 2 3 4 5 6 7 8 9 10]

for i = 2:20
    a(i,:) = a(i-1,:) + 1;
end

N = 10

for I = 1:N
    for J = 1:N
        dx = a(I,1)-a(J,1);
        dy = a(I,2)-a(J,2);
        distance(I,J) = sqrt(dx^2 + dy^2)
    end
end
4

3 回答 3

12

您的a矩阵是一维向量,与嵌套循环不兼容,嵌套循环计算二维空间中从每个点到另一个点的距离。因此,以下答案适用于在N-by-D矩阵中查找所有成对距离的问题,就像您的循环对D=2.

选项 1 - pdist

我认为您正在寻找pdist距离'euclidean'选项。

a = randn(10, 2); %// 2D, 10 samples
D = pdist(a,'euclidean');  %// euclidean distance

跟着它squareform得到你想要的对角线上为零的方阵:

distances = squareform(D);

选项 2 - bsxfun

如果您没有pdist统计工具箱中的 ,您可以使用以下方法轻松完成此操作bsxfun

da = bsxfun(@minus,a,permute(a,[3 2 1]));
distances = squeeze(sqrt(sum(da.^2,2)));

选项 3 - 重新制定的方程

您还可以使用欧几里得(2-范数)距离的另一种形式,

||A-B|| = sqrt ( ||A||^2 + ||B||^2 - 2*A.B )

u在 MATLAB中为两个v大小为 的数据数组编写此代码NxD

dot(u-v,u-v,2) == dot(u,u,2) + dot(v,v,2) - 2*dot(u,v,2) % useful identity
%// there are actually small differences from floating point precision, but...
abs(dot(u-v,u-v,2) - (dot(u,u,2) + dot(v,v,2) - 2*dot(u,v,2))) < 1e-15

使用重新制定的方程,解决方案变为:

aa = a*a';
a2 = sum(a.*a,2); % diag(aa)
a2 = bsxfun(@plus,a2,a2');
distances = sqrt(a2 - 2*aa);

如果选项 2 占用太多内存,您可能会使用此方法。

计时

对于大小为 1e3×3(N×D)的随机数据矩阵,这里是 100 次运行的时序(Core 2 Quad,4GB DDR2,R2013a)。

  • 选项 1 ( pdist):1.561150 秒(0.560947 秒pdist
  • 选项 2 ( bsxfun):2.695059 秒
  • 选项 3(bsxfun替代):1.334880 秒

结果: (i) 用 计算bsxfun,使用替代公式。(ii) pdist+squareform选项具有可比的性能。(iii) 之所以squareform花费两倍的时间,pdist可能是因为pdist距离矩阵是对称的,所以只计算三角矩阵。如果您可以不使用方阵,那么您可以避免squareform并在大约 40% 的时间内使用bsxfun(0.5609/1.3348) 手动进行计算。

于 2013-10-18T18:17:58.393 回答
-2

这是我一直在寻找的,但感谢所有建议。

A = rand(5, 5);
select_cell = [3 3];
distance = zeros(size(A, 1), size(A, 2));
for i = 1:size(A, 1)
    for j = 1:size(A, 2)
        distance(i, j) = sqrt((i - select_cell(1))^2 + (j - select_cell(2))^2);
    end
end
disp(distance)

您也可以通过使用矢量化来改进它:

distances = sqrt((x-xCenter).^2+(y-yCenter).^2
于 2013-10-28T15:14:27.777 回答
-3

重要提示:data_matrix 是 DXN,其中 D 是维数,N 是数据点数!

final_dist_pairs=data_matrix'*data_matrix;

规范=诊断(final_dist_pairs);

final_dist_pairs = bsxfun(@plus, norms, norms') - 2 * final_dist_pairs; 希望能帮助到你!

% 另一个重要的事情, 永远不要使用 MATLAB 的 pdist 函数。这是一个顺序评估,类似于 for 循环并且需要很多时间,可能在 O(N^2)

于 2013-10-18T18:14:17.617 回答