有效计算单元阵列之间的欧几里得距离
Posted
技术标签:
【中文标题】有效计算单元阵列之间的欧几里得距离【英文标题】:Efficient computation of Euclidean distance between cell arrays 【发布时间】:2014-09-24 18:38:18 【问题描述】:我有一个a
-by-b
元胞数组C
。在每个元素中,都有一个浮点数组。
我现在想创建一个新的对称矩阵M
。 M
中的每个元素 (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
的具体内容是什么?行向量?所有i
和j
的长度相同?
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
函数文件来查找两个数组之间的最小/欧几里得距离。
假设这两个元胞数组是 A
和 B
,其中矩阵包含每个元胞数组的行和列索引,分别表示为“indA”和“indB”,其中“indA”和“indB”中的每一行分别包含“A”和“B”的行元素和列元素。现在将上述函数用作:
[M, distance, t] = distance2curve(indA(:, :), indB(:, :))
输出变量M
应包含您要查找的两个数组之间的最小/欧几里得距离。
【讨论】:
以上是关于有效计算单元阵列之间的欧几里得距离的主要内容,如果未能解决你的问题,请参考以下文章