1

我需要帮助优化这个循环。matrix_1是一个 ( nx 2) int 矩阵并且matrix_2是一个 ( mx 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

我需要M2_Index_Dist提供一个 ( (n*m)x 2) 矩阵,matrix_2其中第一列中的索引和第二列中的距离。

输出示例:

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]
4

2 回答 2

1

如果我理解正确,这就是你想要的:

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

如您所见,此代码调用pdist2计算矩阵的每对行之间的距离。默认情况下,此函数使用欧几里得距离。

如果您没有pdist2(这是统计工具箱的一部分),您可以将上面的第 2 行替换为bsxfun

d = squeeze(sqrt(sum(bsxfun(@minus,Matrix_2,permute(Matrix_1, [3 2 1])).^2,2)));
于 2014-03-21T22:18:23.013 回答
1

以下是如何应用bsxfun您的公式 ( ||A-B|| = 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.')))).';

如果您更改对矩阵的解释,则可以避免最终转置。

注意:不应该有任何复杂的值需要处理,real但它存在于非常小的差异可能导致微小的负数的情况下。


编辑:没有它可能会更快dot

d = sqrt(bsxfun(@plus, sum(Matrix_1.*Matrix_1,2), ...
    bsxfun(@minus, sum(Matrix_2.*Matrix_2,2)', 2 * Matrix_1*Matrix_2.'))).';

或者只需一个电话bsxfun

d = sqrt(bsxfun(@plus, sum(Matrix_1.*Matrix_1,2), sum(Matrix_2.*Matrix_2,2)') ...
    - 2 * Matrix_1*Matrix_2.').';

注意:这最后的操作顺序为您提供了相同的结果,而不是错误~1e-14


编辑2:复制M2_Index_Dist

II = ndgrid(1:size(Matrix_2,1),1:size(Matrix_2,1));
M2_Index_Dist = [II(:) d(:)];
于 2014-03-21T23:36:03.103 回答