有效计算单元阵列之间的欧几里得距离

Posted

技术标签:

【中文标题】有效计算单元阵列之间的欧几里得距离【英文标题】:Efficient computation of Euclidean distance between cell arrays 【发布时间】:2014-09-24 18:38:18 【问题描述】:

我有一个a-by-b 元胞数组C。在每个元素中,都有一个浮点数组。

我现在想创建一个新的对称矩阵MM 中的每个元素 (i, j) 将被设置为 C 中所有相应浮点数组的欧几里德距离之和。

例如,要查找M(i,j),我将沿行C 获取b 浮点数组集i,并沿行C 获取b 浮点数组集@987654334 @,求两个集合中每个数组之间的欧式距离,然后将b x b的值相加。 Ci,j 是一个列向量。所有列的长度相同。

以下是我对此的“蛮力”实现:

for i=1:a
    for j=1:a
        dist_sum = 0;
        for k=1:b
            for l=1:b
                dist = sqrt(sum((Ci, k - Cj, l) .^ 2));
                dist_sum = dist_sum + dist;
            end
        end
        M(j, i) = dist_sum;
        M(i, j) = dist_sum;
    end
end

我的问题:有没有一种更有效的方法可以使用矩阵运算来执行此操作,而不必依次显式计算每个欧几里得距离?

【问题讨论】:

Ci,j的具体内容是什么?行向量?所有ij 的长度相同? Ci,j 是一个列向量。所有列的长度相同。 如果你有一个 3D 数组 C(i,j,k),我会更容易,其中k 是每个向量分量。这对你来说可能吗? 您可以使用cell2mat 将您的元胞数组转换为矩阵吗?这样可以更轻松地使用 pdist 等函数。 如果您的单元格数组 C 中的所有元素都属于同一类型,则您应该使用普通数组/矩阵。这将改善您的内存消耗,正如@2cents 所说,将更容易在其他函数中使用该数组/矩阵。 【参考方案1】:

最好使用 3D 数组,而不是等长列向量的 2D 元胞数组。

如果你有一个元胞数组:首先转换成一个 3D 数组(在我的代码中是D);然后很容易用bsxfun计算距离;最后申请sum:

D = permute(C, [3 1 2]);
D = reshape(cat(2, D:), [], size(C,1), size(C,2)); %// 3D array
dist = sqrt(sum(bsxfun(@minus, D, permute(D, [1 4 5 2 3])).^2)); %// distances
M = squeeze(sum(sum(dist, 3), 5)); %// sum of distances

例子:用

>> C = [1; 2], [30; 40], [0; 1]; [5; 7] [19; 17] [4; 5]; %// a is 2, b is 3

你和我的代码的结果都是

M =
  196.8391  182.8791
  182.8791   77.3002

【讨论】:

等等,“如果你真的需要一个元胞数组,首先转换成一个3D矩阵”?我很困惑。 @2cents 我的意思是:OP 应该使用 3D 矩阵(正如我们在 cmets 中都同意的那样)。如果他/她有一个单元阵列,它可以做到,但第一步是转换为 3D 矩阵。我会在我的回答中更清楚地说明这一点 我不确定将其转换为 3D 数组。如果我在C 上使用 cell2mat,那么它会给我一个大小为(a x b) x f 的二维数组,其中f 是浮点数组的长度,而不是一个 3D 矩阵。 @Karnivaurus 按照我的代码进行转换——前两行:D 是 3D 数组【参考方案2】:

在计算欧几里得距离之前:

可以使用cell2mat将单元格数组转换为矩阵...然后您可以使用以下方法..

方法一:

G  = rand(1, 72);
G2 = rand(1, 72);
D  = sqrt(sum((G - G2) .^ 2));

方法二:

V = G - G2;
D = sqrt(V * V');

方法三:

D = norm(G - G2);

方法四:

D = pdist2(G,G2);

【讨论】:

这些方法中的任何一种都可以解决元胞数组吗? 可以使用cell2mat将单元格数组转换为矩阵...然后你可以使用这些方法.. 我会将其添加到您帖子的开头,以帮助更直接地解决 OP 问题。 小心方法2中的'!我不认为复共轭转置是这里的意思。【参考方案3】:

我建议使用 (:) 将矩阵元素转换为向量,然后使用来自 Matlab File Exchange 的 distance2curve.m 函数文件来查找两个数组之间的最小/欧几里得距离。

假设这两个元胞数组是 AB,其中矩阵包含每个元胞数组的行和列索引,分别表示为“indA”和“indB”,其中“indA”和“indB”中的每一行分别包含“A”和“B”的行元素和列元素。现在将上述函数用作:

[M, distance, t] = distance2curve(indA(:, :), indB(:, :))

输出变量M 应包含您要查找的两个数组之间的最小/欧几里得距离。

【讨论】:

以上是关于有效计算单元阵列之间的欧几里得距离的主要内容,如果未能解决你的问题,请参考以下文章

knn算法中计算距离而不是欧几里得距离的替代有效方法

如何有效地找到我的测试行和训练集之间的欧几里得距离?

使用构造函数计算两点之间的欧几里得距离

计算两个python数组之间的欧几里得距离

计算多维火炬张量中向量之间的欧几里得距离

计算数组中向量之间的最大距离