特征 - 计算 2 组向量之间的距离矩阵



我需要创建一个特征数组,其中包含每个源和记录器位置之间的所有距离。

我有三个特征::数组 sx、sy 和 sz 表示源位置,三个特征::数组 rx、ry 和 rz 表示记录器位置。源和记录位置阵列的长度不必相同。

使用 for 循环,我可以按如下方式计算距离矩阵

Eigen::ArrayXf  sx, sy, sz;
Eigen::ArrayXf  rx, ry, rz;
Eigen::ArrayXXf dist;
for (int s=0; s<nrSources; s++ ) {
   for (int r=0; r<nrReceivers; r++) {
      dist(h,g) = sqrt(pow(rx(h)-sx(g),2.)+
                       pow(ry(h)-sy(g),2.)+
                       pow(sz(h)-sz(g),2.));
   }
}

我需要为实验计算 dist 数组,例如 500 x 1000 次。使用 for 循环显然有效,但它可能不是最有效的方法,因为它没有使用矢量化。

将 sx

、sx、sz 和 hx、hy 和 hz 重写为 sxyz 和 hxyz 数组应该是可能的。

是否有可能更有效地编写方程!?

您可能希望放弃内部循环以支持表达式。通过这样做,我们允许将计算混为一谈,并希望实现矢量化。假设rs变量被声明为 Eigen::ArrayX3f sxyz(nrSources,3), rxyz(nrReceivers,3); ,则可以将外部循环编写为:

for (int s = 0; s < nrSources; s++)
{
    dist.col(s) =
        (rxyz.rowwise() - sxyz.row(s)).matrix().rowwise().norm();
}       

在这里,我们使用rxyz.rowwise() - sxyz.row(s)从所有 r s 中减去第 s s。需要matrix()才能访问norm()

对您的

实施进行基准测试和比较。

你可以看看我的项目计算距离矩阵。
我实现了各种方法来计算 2 个任意向量集之间的距离矩阵。

实际上,Eigen 这样做的速度非常快(比使用 MSVC 的原版 C 实现慢得多)。

无论如何,另一个要做上述事情的是:

void CalcDistanceMatrixEigen(float* mD, float* mA, float* mB, int vecDim, int numRowsA, int numRowsB)
{
    EigenMatExt meA(mA, vecDim, numRowsA);
    EigenMatExt meB(mB, vecDim, numRowsB);
    EigenMatExt meD(mD, numRowsA, numRowsB);
    // meD = meA.colwise().squaredNorm().transpose() - (2 * meA.transpose() * meB) + meB.colwise().squaredNorm();
    // Not even close to be as fast as MATLAB (Intel MKL???)
    meD = ((-2 * meA.transpose() * meB).colwise() + meA.colwise().squaredNorm().transpose()).rowwise() + meB.colwise().squaredNorm();

}

只需查看文件即可。
你可以看到我在@AviGinsburg和上述方法中都比较了特征,似乎我的更快(尽管再次,使用该 Vanilla C 比该操作的特征快得多)。

相关内容

  • 没有找到相关文章

最新更新