您的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) 手动进行计算。