Eigen3:将 MatrixXd 映射到 Matrix4d 的乘法

问题描述 投票:0回答:1

使用 eigen3 将多个连续布置的 Vector3d 乘以 Matrix4d。

显然,我对矩阵的不同大小有疑问。

为了解决这个问题,我在磁盘上添加了 w 部分以在 Vector4d 上进行操作,但我想避免它以节省每个向量的双精度大小。

代码:

#include <array>
#include <eigen3/Eigen/Geometry>
#include <iostream>

using namespace std;
#define M 4
int main (){


        
                #if M == 4

                auto arr = std::to_array( {1., 2., 3., 1., 4., 5., 6., 1.} );
                Eigen::Map <Eigen::MatrixXd> v( arr.data(), 4, 2 );

                #elif M == 3

                auto arr = std::to_array( {1., 2., 3., 4., 5., 6.} );
                Eigen::Map <Eigen::MatrixXd> v( arr.data(), 3, 2 );

                #endif
                
                // This is just an example matrix
                // I get a different one by parameter
                // in the real code.
                Eigen::Matrix4d w;
                w.setIdentity();

                w( 0, 3 ) = 10;
                w( 1, 3 ) = 20;

                cout << v.matrix() << "\n\n";
                cout << w.matrix() << "\n\n";

                auto res = w * v;

                std::cout << res.matrix() << std::endl;
        

}

关联神箭

有没有办法让 Eigen 为我的 v 矩阵添加 w 部分,或者当 M == 3 时我应该将 w 部分存储在磁盘上,浪费空间?

c++ matrix-multiplication eigen3
1个回答
0
投票

我想谈谈以下几个方面:

Vector4 与 Vector3

从性能角度来看,使用

Vector4d
更好。对于 AVX2,这直接映射到单个 YMM 寄存器。使用 SSE 或其他矢量化硬件,它也可以很好地工作,例如作为两个 128 位向量。一般来说,二或四的倍数会以牺牲一些内存为代价获得更好的性能。

如果您仍然想使用

Vector3d
或相应的矩阵,Eigen 专门为此提供了
homogeneous
方法。所以这应该对你有用:

res = w * v.colwise().homogeneous();

使用
MatrixXd

对于这样的应用程序,您应该使用固定在一维的矩阵类型定义。这告诉 Eigen 使用最适合小型、固定大小的向量/矩阵的专用代码。当你这样写时,你会得到更好的性能:

Eigen::Map<Eigen::Matrix4Xd> v( arr.data(), 4, 2 );

或者因为你似乎更喜欢

auto
,你可以使用这个:

auto v = Eigen::Matrix4Xd::Map(arr.data(), 4, 2);

第二个选项是首选,因为您可以给它一个

const
指针,并且返回类型将为
Eigen::Map<const Eigen::Matrix...>
而无需编写更长的类型。

使用
auto

请阅读本手册的常见陷阱部分。您的行

auto res = w * v
不计算矩阵。它存储一个 expression 对象,该对象将按需计算为矩阵乘法。至关重要的是,它包含指向输入数据的指针,当内存被释放或重用时,这可能会导致内存安全问题。它还可能导致重复评估,而不仅仅是一次评估。

要么像这样专门分配给一个新矩阵:

Eigen::Matrix4Xd res = w * v;

或者像这样:

auto res = (w * v).eval();

matrix()
方法

更多的旁注,但像

cout << res.matrix()
这样的东西是不必要的。
matrix()
及其对应物
array()
的存在是为了在
Eigen::Array
Eigen::Matrix
类型之间进行转换,以便您可以对同一对象使用两种操作风格。特别是对于
cout
来说应该没有区别。

© www.soinside.com 2019 - 2024. All rights reserved.