我知道matlab有一个内置的pdist函数,可以计算成对距离然而,我的矩阵太大了,它的6000x300和matlab的内存都用完了。
这个问题是Matlab euclidean pairwise square distance function的后续问题。
有没有办法解决这种计算效率低下的问题我试着手动编写成对距离的计算代码,通常需要一整天的时间(有时需要6到7个小时)。
非常感谢您的帮助!

最佳答案

我忍不住到处玩我创建了一个名为mex C file的Matlabpdistc,它实现了单精度和双精度的成对欧氏距离在我使用matlabr2012和R2015a的机器上,对于大输入(例如60000×300),它比pdist快20–25%(以及底层的pdistmex辅助函数)。
正如已经指出的,这个问题从根本上来说是由内存限制的,你需要很多内存我的mex C代码使用的内存比输出所需的内存少将其内存使用量与pdist的内存使用量进行比较时,似乎两者实际上是相同的换句话说,pdist没有使用大量的额外内存您的内存问题可能是在调用pdist之前耗尽的内存中(您可以使用clear删除任何大数组吗?)或者仅仅是因为你想在小硬件上解决一个大的计算问题。
因此,我的pdistc函数可能无法节省您的内存,但您可以使用我内置的另一个功能可以计算整体成对距离向量的块像这样的:

m = 6e3;
n = 3e2;
X = rand(m,n);
sz = m*(m-1)/2;

for i = 1:m:sz-m
    D = pdistc(X', i, i+m); % mex C function, X is transposed relative to pdist
    ...                     % Process chunk of pairwise distances
end

这要慢得多(大约10倍),而且我的C代码的这部分没有得到很好的优化,但是它允许更少的内存使用——假设您不需要一次使用整个数组请注意,使用pdist(或pdistc)可以更有效地执行相同的操作,方法是创建一个循环,在其中直接传入X的子集,而不是全部。
如果你有一个64位的Intel Mac,你不需要编译,因为我已经包含了.mexmaci64二进制文件,但否则你需要知道如何为你的机器编译代码我帮不了你您可能无法编译它,或者需要通过自己编辑代码来解决兼容性问题也有可能存在错误,代码会使Matlab崩溃另外,请注意,相对于pdist,您可能会得到稍微不同的输出,两者在机器epsilon(eps)范围内存在差异pdist可能会或可能不会做一些花哨的事情来避免大输入和其他数字问题的溢出,但请注意,我的代码不会。
另外,我创建了一个简单的pure Matlab implementation它比mex代码慢得多,但仍然比一个简单的实现或pdist中的代码快。
所有文件can be found hereZIP存档包含所有文件是BSD授权的可以随意优化(我在C代码中尝试了BLAS调用和OpenMP,但没有效果——也许一些指针魔术或GPU/OpenCL可以进一步加快速度)我希望它能对你或其他人有帮助。

08-24 22:58