用std::vector初始化Eigen::vector

Initialise Eigen::vector with std::vector

本文关键字:vector Eigen 初始化 std      更新时间:2023-10-16

我以前见过这样做,但我不记得如何有效地用相同长度的std::vector初始化已知长度的Eigen::Vector。下面是一个很好的例子:

std::vector<double> v1 = {1.0, 2.0, 3.0};
Eigen::Vector3d v2; // Do I put it like this in here: v2(v1) ?
v2 << v1[0], v1[1], v1[2]; // I know you can do it like this but 
                           // I am sure i have seen a one liner.

我已经仔细阅读了这个关于高级矩阵初始化的页面,但是没有明确的解释执行此操作的方法。

根据Eigen Doc, Vector是Matrix的类型定义,而Matrix有一个具有以下签名的构造函数:

Matrix (const Scalar *data)

构造一个固定大小的矩阵,初始化系数从data开始。

和向量引用将std::vector::data定义为:

std::vector::data
T* data();
const T* data() const;

返回指向作为元素存储的底层数组的指针。指针是这样的,范围[data(); data() + size())总是a有效范围,即使容器为空。

因此,您可以将vector的数据作为Vector3d构造函数参数传递:

Eigen::Vector3d v2(v1.data());
同样,从特征3.2.8开始,上面提到的构造函数定义为:
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>
  ::Matrix(const Scalar *data)
{
  this->_set_noalias(Eigen::Map<const Matrix>(data));
}

如您所见,它也使用Eigen::Map,如@ggael和@gongzhitaao所示。

只是为了扩展@ggael的答案,以防其他人没有注意到:

来自快速参考指南:映射外部数组:

float data[] = {1,2,3,4};
Map<Vector3f> v1(data);       // uses v1 as a Vector3f object
Map<ArrayXf>  v2(data,3);     // uses v2 as a ArrayXf object
Map<Array22f> m1(data);       // uses m1 as a Array22f object
Map<MatrixXf> m2(data,2,2);   // uses m2 as a MatrixXf object

下面的一行应该更正确:

#include <Eigen/Dense>
#include <Eigen/Core>
std::vector<double> a = {1, 2, 3, 4};
Eigen::VectorXd b = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(a.data(), a.size());

我找到了一个更好的答案:

https://forum.kde.org/viewtopic.php?f=74& t = 94839

基本上首先创建一个指向std vector的指针,然后使用Map将指针和长度传递给构造函数。

此方法适用于Eigen中的动态Vector对象。当我尝试使用.data()函数从std矢量作为第一个答案建议,它给了我一个错误:静态断言失败:you_called_a_fixed_size_method_on_dynamic_size_matrix_or_vector

但是使用这个方法它是有效的!

我只是从这里的链接复制并粘贴相关代码:

std::vector<double> v(4, 100.0);
double* ptr = &v[0];
Eigen::Map<Eigen::VectorXd> my_vect(ptr, 4);

有两种选择。如果您希望Eigen::VectorXdstd::vector共享内存,请使用

Eigen::Map<Eigen::VectorXd> b(v1.data(), v1.size());
否则(做一个深拷贝),使用
Eigen::VectorXd a = Eigen::Map<Eigen::VectorXd>(v1.data(), v1.size());