[英]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
的情况下所做的那样。
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);
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)));
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
两个数据数组u
和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
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 占用太多内存,您可能会使用此方法。
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)。
pdist
): 1.561150 sec (0.560947 sec in pdist
)选项1( pdist
):1.561150秒(在0.560947秒pdist
)bsxfun
): 2.695059 sec选项 2 ( bsxfun
):2.695059 秒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.