使用Eigen进行vector3d乘积的循环矢量化

huangapple go评论74阅读模式
英文:

Loop vectorising of vector3d products using Eigen

问题

Hi,我正在使用Eigen来在粒子滤波器中对一系列循环操作进行矢量化处理。

实质上,我有两个矩阵:

Eigen::Matrix<N, 3> A;
Eigen::Matrix<3, N> B;

其中N是一个大的数。

我想要一行代码来执行以下操作的等效版本:

Eigen::Matrix<N, 1> D;
for (size_t i=0; i< N; i++)
{
   D.row(i) = A.row(i)*B.col(i);
}

我曾尝试使用D =A.rowwise()*B.colwise(),但这些广播方法之间没有定义operator*()

英文:

Hi I'm using Eigen to roll or vectorise a number of loop operations in a particle filter.

In essence I have two matricies

Eigen::Matrix&lt;N, 3&gt; A;
Eigen::Matrix&lt;3, N&gt; B;

Where N is a large number.

And I would like a one line which does the equivalent of:

Eigen::Matrix&lt;N, 1&gt; D;
for (size_t i=0; i&lt; N; i++)
{
   D.row(i) = A.row(i)*B.col(i);
}

I had been trying to use D =A.rowwise()*B.colwise() but these broadcasting methods do not define an operator*() between them.

答案1

得分: 1

这是一个在小向量情况下几乎是最优的版本。

Eigen::MatrixX3d A;
Eigen::Matrix3Xd B;
Eigen::VectorXd D = (A.array() * B.array().transpose()).rowwise().sum();

为了更好地适应较大的向量大小,例如如果这些是方阵,微调这个表达式有点挑战,但对于3行/列来说,它工作得很好。

如果你可以选择你的矩阵形状,考虑改成这个:

Eigen::Matrix3Xd A, B;
Eigen::VectorXd D = (A.array() * B.array()).colwise().sum();

或者这个:

Eigen::MatrixX3d A, B;
Eigen::VectorXd D = (A.array() * B.array()).rowwise().sum();

这两种方法都会生成非常好的汇编代码,并充分利用了向量指令。在Eigen-3.4.0、GCC-11.3下经过测试,使用-O3 -DNDEBUG编译选项。第二种在低维度(从MatrixX2dMatrixX4d)情况下效果更好,第一种在大尺寸情况下效果更好。

英文:

Here is a version that is pretty much optimal for small vectors like these.

Eigen::MatrixX3d A;
Eigen::Matrix3Xd B;
Eigen::VectorXd D = (A.array() * B.array().transpose()).rowwise().sum();

Fine-tuning this expression for larger vector size, e.g. if these were square matrices, is a bit of a challenge but for 3 rows/columns it works fine.

If you can chose the shape of your matrices, consider changing to this:

Eigen::Matrix3Xd A, B;
Eigen::VectorXd D = (A.array() * B.array()).colwise().sum();

or this:

Eigen::MatrixX3d A, B;
Eigen::VectorXd D = (A.array() * B.array()).rowwise().sum();

Both produce assembly that looks very good and makes full use of vector instructions. Tested with Eigen-3.4.0, GCC-11.3 -O3 -DNDEBUG. The second one is better with low dimensions (MatrixX2d up to MatrixX4d). The first will scale better to large sizes.

huangapple
  • 本文由 发表于 2023年1月9日 13:42:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75053557.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定