简体   繁体   English

求矩阵中一点到矩阵中所有其他点的距离

[英]Find the distance from one point in a matrix to all other points in a matrix

I have a matrix a and I want to calculate the distance from one point to all other points .我有一个矩阵a ,我想计算从一个点到所有其他点的距离 So really the outcome matrix should have a zero (at the point I have chosen) and should appear as some sort of circle of numbers around that specific point.所以实际上结果矩阵应该有一个零(在我选择的点上)并且应该显示为围绕该特定点的某种数字圆圈。

This is what I have already but I cant seem to get the correct outcome.这是我已经拥有的,但我似乎无法得到正确的结果。

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

Your a matrix is a 1D vector and is incompatible with the nested loop, which computes distance in 2D space from each point to each other point .您的a矩阵是一个一维向量,与嵌套循环不兼容,它计算二维空间中从每个点到彼此点的距离 So the following answer applies to the problem of finding all pairwise distances in a N-by-D matrix, as your loop does for the case of D=2 .因此,以下答案适用于在N-by-D矩阵中查找所有成对距离的问题,就像您的循环在D=2的情况下所做的那样。

Option 1 - pdist选项 1 - pdist

I think you are looking for pdist with the 'euclidean' distance option.我认为您正在寻找带有'euclidean'距离选项的pdist

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

Follow that by squareform to get the square matrix with zero on the diagonal as you want it:按照squareform进行操作,根据需要获得对角线上为零的方阵:

distances = squareform(D);

Option 2 - bsxfun选项 2 - bsxfun

If you don't have pdist , which is in the Statistics Toolbox, you can do this easily with bsxfun :如果您没有统计工具箱中的pdist ,您可以使用bsxfun轻松完成此bsxfun

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

Option 3 - reformulated equation选项 3 - 重新公式化的方程

You can also use an alternate form of Euclidean (2-norm) distance,您还可以使用欧几里得(2-范数)距离的替代形式,

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

Writing this in MATLAB for two data arrays u and v of size NxD ,在 MATLAB 中为大小为NxD两个数据数组uv编写此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

With the reformulated equation, the solution becomes:使用重新公式化的方程,解变成:

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

You might use this method if Option 2 eats up too much memory.如果选项 2 占用太多内存,您可能会使用此方法。

Timings时间安排

For a random data matrix of size 1e3-by-3 (N-by-D), here are timings for 100 runs (Core 2 Quad, 4GB DDR2, R2013a).对于大小为 1e3×3(N×D)的随机数据矩阵,这里是 100 次运行的时序(Core 2 Quad、4GB DDR2、R2013a)。

  • Option 1 ( pdist ): 1.561150 sec (0.560947 sec in pdist )选项1( pdist ):1.561150秒(在0.560947秒pdist
  • Option 2 ( bsxfun ): 2.695059 sec选项 2 ( bsxfun ):2.695059 秒
  • Option 3 ( bsxfun alt): 1.334880 sec选项 3( bsxfun alt):1.334880 秒

Findings: (i) Do computations with bsxfun , use the alternate formula.结果:(i) 使用bsxfun计算,使用替代公式。 (ii) the pdist + squareform option has comparable performance. (ii)所述pdist + squareform选项具有相当的性能。 (iii) The reason why squareform takes twice as much time as pdist is probably because pdist only computes the triangular matrix since the distance matrix is symmetric. (III)的原因所在squareform需要两倍多的时间, pdist可能是因为pdist只计算三角矩阵由于距离矩阵是对称的。 If you can do without the square matrix, then you can avoid squareform and do your computations in about 40% of the time required to do it manually with bsxfun (0.5609/1.3348).如果你可以不方阵做,那么你就可以避免squareform ,做你的计算中的时间大约40%用做手工需要bsxfun (0.5609 / 1.3348)。

This is what i was looking for, but thanks for all the suggestions.这就是我一直在寻找的,但感谢所有建议。

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)

Also you can improve it by using vectorisation:您也可以通过使用矢量化来改进它:

distances = sqrt((x-xCenter).^2+(y-yCenter).^2

IMPORTANT: data_matrix is DXN, where D is number of dimensions and N is number of data points!重要提示:data_matrix 是 DXN,其中 D 是维数,N 是数据点数!

final_dist_pairs=data_matrix'*data_matrix; final_dist_pairs=data_matrix'*data_matrix;

norms = diag(final_dist_pairs);规范 = diag(final_dist_pairs);

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

% Another important thing, Never use pdist function of MATLAB . % 另一个重要的事情,永远不要使用 MATLAB 的 pdist 函数 It is a sequential evaluation, that is something like for loops and takes a lot of time, maybe in O(N^2)这是一个顺序评估,类似于 for 循环,需要很多时间,可能是 O(N^2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM