[英]optimization of pairwise L2 distance computations
I need help optimizing this loop. 我需要帮助优化此循环。
matrix_1
is a ( n
x 2) int matrix and matrix_2
is a ( m
x 2), m
& n
very. matrix_1
是一个( n
x 2)int矩阵, matrix_2
是一个( m
x 2), m
& n
非常。
index_j = 1;
for index_k = 1:size(Matrix_1,1)
for index_l = 1:size(Matrix_2,1)
M2_Index_Dist(index_j,:) = [index_l, sqrt(bsxfun(@plus,sum(Matrix_1(index_k,:).^2,2),sum(Matrix_2(index_l,:).^2,2)')-2*(Matrix_1(index_k,:)*Matrix_2(index_l,:)'))];
index_j = index_j + 1;
end
end
I need M2_Index_Dist
to provide a ( (n*m)
x 2) matrix with the index of matrix_2
in the first column and the distance in the second column. 我需要
M2_Index_Dist
以提供( (n*m)
×2)与索引矩阵matrix_2
在第一列和第二列之间的距离。
Output example: 输出示例:
M2_Index_Dist = [ 1, 5.465
2, 56.52
3, 6.21
1, 35.3
2, 56.52
3, 0
1, 43.5
2, 9.3
3, 236.1
1, 8.2
2, 56.52
3, 5.582]
If I understand correctly, this does what you want: 如果我理解正确,这可以满足您的要求:
ind = repmat((1:size(Matrix_2,1)).',size(Matrix_1,1),1); %'// first column: index
d = pdist2(Matrix_2,Matrix_1); %// compute distance between each pair of rows
d = d(:); %// second column: distance
result = [ind d]; %// build result from first column and second column
As you see, this code calls pdist2
to compute the distance between every pair of rows of your matrices. 如您所见,此代码调用
pdist2
来计算矩阵的每一对行之间的距离。 By default this function uses Euclidean distance. 默认情况下,此函数使用欧几里得距离。
If you don't have pdist2
(which is part of the the Statistics Toolbox), you can replace line 2 above with bsxfun
: 如果没有
pdist2
(这是“统计信息工具箱”的一部分),则可以将上面的第2行替换为bsxfun
:
d = squeeze(sqrt(sum(bsxfun(@minus,Matrix_2,permute(Matrix_1, [3 2 1])).^2,2)));
Here's how to apply bsxfun
with your formula ( ||AB|| = sqrt(||A||^2 + ||B||^2 - 2*A*B)
): 这是在您的公式中应用
bsxfun
的方法( ||AB|| = sqrt(||A||^2 + ||B||^2 - 2*A*B)
bsxfun
||AB|| = sqrt(||A||^2 + ||B||^2 - 2*A*B)
):
d = real(sqrt(bsxfun(@plus, dot(Matrix_1,Matrix_1,2), ...
bsxfun(@minus, dot(Matrix_2,Matrix_2,2).', 2 * Matrix_1*Matrix_2.')))).';
You can avoid the final transpose if you change your interpretation of the matrix. 如果更改矩阵的解释,则可以避免最终的转置。
Note: There shouldn't be any complex values to handle with real
but it's there in case of very small differences that may lead to tiny negative numbers. 注意:不应该有处理任何复杂的价值
real
,但它的存在在非常小的差异,可能会导致微小的负数的情况。
Edit: It may be faster without dot
: 编辑:可能没有
dot
更快:
d = sqrt(bsxfun(@plus, sum(Matrix_1.*Matrix_1,2), ...
bsxfun(@minus, sum(Matrix_2.*Matrix_2,2)', 2 * Matrix_1*Matrix_2.'))).';
Or with just one call to bsxfun
: 或者只调用
bsxfun
:
d = sqrt(bsxfun(@plus, sum(Matrix_1.*Matrix_1,2), sum(Matrix_2.*Matrix_2,2)') ...
- 2 * Matrix_1*Matrix_2.').';
Note: This last order of operations gives identical results to you, rather than with an error ~1e-14
. 注意:这最后一个操作顺序将为您提供相同的结果,而不是出现
~1e-14
错误。
Edit 2: To replicate M2_Index_Dist
: 编辑2:复制
M2_Index_Dist
:
II = ndgrid(1:size(Matrix_2,1),1:size(Matrix_2,1));
M2_Index_Dist = [II(:) d(:)];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.