如何在C ++中使用特征值实现Matlab的pdist?

问题描述

在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模板。我想念什么吗?

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...