问题描述
在Matlab中,D = pdist(X,Y)
函数计算两组观测值X和Y之间的成对距离。给定X = randu(3,2),Y = randu(3,2)
,其中每行存储一个观测值(x,y)。然后pdist
返回一个[3 x 3] D矩阵,其中(i,j)项表示X中第i个观测值与Y中第j个观测值之间的距离。
我想使用Eigen和C ++来模仿这种行为。
我天真地使用for循环迭代X中的每个观测值,并计算X中当前的观测值与Y中每个观测值之间的成对距离。结果是[1 x Y.rows]行向量,然后将其填充进入D矩阵的第i行。
我认为这种实现速度有些慢,因为for循环的两次迭代是独立的,矢量化技术可能会有所帮助。
有人可以给我一些信息以加快实施速度吗?
我尝试使用Eigen的binaryExpr,但未预期结果。
解决方法
我已经根据您的解释实现了此功能(我假设您希望观察的数量是动态的,并且对任何数量的观察N1,N2都适用):
#include <Eigen/Dense>
#include <iostream>
const int oDims = 2;
typedef Eigen::Matrix<double,Eigen::Dynamic,oDims,Eigen::RowMajor> ObservationMatrix;
auto pdist(const ObservationMatrix& X,const ObservationMatrix& Y)
{
return (X.replicate(1,Y.rows()) - Y.reshaped<Eigen::RowMajor>(1,Y.rows() * oDims).replicate(X.rows(),1))
.reshaped<Eigen::RowMajor>(X.rows() * Y.rows(),oDims)
.rowwise().norm()
.reshaped<Eigen::RowMajor>(X.rows(),Y.rows());
}
int main() {
ObservationMatrix X(3,oDims),Y(4,oDims);
X << 3,2,4,1,5;
Y << 10,14,12,17,16,11,13,18;
Eigen::Matrix<double,Eigen::RowMajor> result = pdist(X,Y);
std::cout << result << std::endl;
return 0;
}
我不确定此实现是否更快,但是如果您可以使用for循环共享实现,我们可以检查时间。我试图用MATLAB的pdist函数来验证它的功能。但是,我找不到像您所描述的(https://www.mathworks.com/help/stats/pdist.html)那样接受两个矩阵X,Y的pdist模板。我想念什么吗?