英文:
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<N, 3> A;
Eigen::Matrix<3, N> B;
Where N is a large number.
And I would like a one line which does the equivalent of:
Eigen::Matrix<N, 1> D;
for (size_t i=0; i< 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
编译选项。第二种在低维度(从MatrixX2d
到MatrixX4d
)情况下效果更好,第一种在大尺寸情况下效果更好。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论