c++ 使用std::vector初始化特征::vector

7d7tgy0s  于 2022-12-05  发布在  其他
关注(0)|答案(5)|浏览(268)

我以前见过这样的操作,但我不记得如何有效地用一个已知长度的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.

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

hsvhsicv

hsvhsicv1#

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

Matrix (const Scalar *data)

构造一个固定大小的矩阵,该矩阵使用从数据开始的系数进行初始化。
vector referencestd::vector::data定义为:

std::vector::data

T* data();
const T* data() const;

返回指向用作元素存储的基础数组的指针。该指针使[data(); data() + size())范围始终为有效范围,即使容器为空。
因此,您可以将向量的数据作为Vector3d构造函数参数传递:

Eigen::Vector3d v2(v1.data());

此外,从Eigen 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所示。

klsxnrf1

klsxnrf12#

只是为了延长@ggael的回答以防别人没有注意到它:
来自快速参考指南:Map外部阵列:

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
ltqd579y

ltqd579y3#

下面的一行程序应该更正确:

#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());
ymzxtsji

ymzxtsji4#

我通过这个链接找到了一个更好的答案:
https://forum.kde.org/viewtopic.php?f=74&t=94839
基本上,首先创建一个指向std向量的指针,然后使用Map将指针和长度传递给构造函数。
这个方法可以在Eigen中使用动态Vector对象。当我尝试使用std vector中的.data()函数作为第一个答案时,它给了我一个错误:静态Assert失败:您调用了动态大小矩阵或向量上的固定大小方法
但使用这种方法它的工作!
我只是从链接中复制并粘贴相关代码到这里:

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

vuktfyat5#

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

Eigen::Map<Eigen::VectorXd> b(v1.data(), v1.size());

否则(制作深层副本),使用

Eigen::VectorXd a = Eigen::Map<Eigen::VectorXd>(v1.data(), v1.size());

相关问题