简体   繁体   English

我应该如何从特征3中的张量切片中获得向量?

[英]How should I get a Vector from a Tensor slice in Eigen 3?

I'm tearing my hair out trying to access a column of data in an Eigen::Tensor<double, 3> as a Eigen::VectorXd . 我正在努力尝试以Eigen::VectorXd身份访问Eigen::Tensor<double, 3>的数据列。

Slicing, as according to this answer , works fine to get me the column I want. 按照此答案进行切片,可以很好地获取我想要的列。 But I can't then assign that to a vector. 但是我不能再将其分配给向量。

What I have: 我有的:

Eigen::Tensor<double, 3> my_tens(2, 3, 4);
my_tens.setRandom();

Eigen::array<Eigen::Index, 3> dims = my_tens.dimensions();

Eigen::array<Eigen::Index, 3> offsets = {0, 1, 0};
Eigen::array<Eigen::Index, 3> extents = {dims[0], 1, 1};

// This works perfectly, and is exactly the column I want:
std::cout << my_tens.slice(offsets, extents);

// ... and I want it as a VectorXd, so:
Eigen::VectorXd my_vec(dims[0]);

The following things I've tried all FAIL: 我尝试以下所有操作均失败:

// Direct assignment (won't compile, no viable overloaded '=')
my_vec = my_tens.slice(offsets, extents);

// Initialisation (won't compile, no viable overloaded '<<')
my_vec << my_tens.slice(offsets, extents);

// Same problem with reshaping:
g_a = signature_a.g.slice(offsets, extents).reshape(Eigen::array<Eigen::Index, 2>{dims[0], 1});

// Converting the base (won't compile, no member 'matrix')
my_vec << my_tens.slice(offsets, extents).matrix();

I also tried mapping as in this answer , but that doesn't work either ( EDIT: I thought this was due to the to the storage ordering but actually is due to incorrect offset, see my answer ): 我也在这个答案中尝试了映射,但是也不起作用( 编辑:我认为这是由于存储顺序,但实际上是由于不正确的偏移量,请参见我的答案 ):

// This produces a part of a row of the tensor, not a column. Gah!
auto page_offset = offsets[2] * dims[0] * dims[1];
auto col_offset = offsets[1] * dims[0];
auto bytes_offset = sizeof(double) * (page_offset + col_offset)
Eigen::Map<Eigen::VectorXd> my_mapped_vec(my_tens.data() + bytes_offset, dims[0]);

Should it really be this hard, or am I missing something simple? 真的应该这么难,还是我错过了一些简单的事情? Thanks for any and all help! 感谢您提供的所有帮助!

Answered my own question: Yes, I was missing something simple. 回答了我自己的问题:是的,我缺少一些简单的东西。 By comparing what numbers I got out of the Map operation I realised the offsets were a factor of 8 out; 通过比较我从Map操作中得到的数字,我意识到偏移量是8的因数。 ie out by sizeof(double) . 即超出sizeof(double)

I hadn't realised that operation my_tens.data() + bytes_offset takes my_tens.data() , a const double * , and rather than adding a fixed number of bytes to offset the pointer, offsets it by that number of elements. 我还没有意识到,操作my_tens.data() + bytes_offset my_tens.data()const double * ,而不是添加固定数量的字节来偏移指针,而是将其偏移该数量的元素。

Here's the correct code: 这是正确的代码:

Eigen::Tensor<double, 3> my_tens(2, 3, 4);
my_tens.setRandom();
Eigen::array<Eigen::Index, 3> dims = my_tens.dimensions();
Eigen::array<Eigen::Index, 3> offsets = {0, 1, 0};
Eigen::array<Eigen::Index, 3> extents = {dims[0], 1, 1};

// Compute the offset, correctly this time!
auto page_offset = offsets[2] * dims[0] * dims[1];
auto col_offset = offsets[1] * dims[0];
auto elements_offset = page_offset + col_offset;

// Map into the array
Eigen::Map<Eigen::VectorXd> my_mapped_vec(my_tens.data() + elements_offset, dims[0]);

// Compare the two:
std::cout << my_tens.slice(offsets, extents) << std::endl;
std::cout << my_mapped_vec.transpose() << std::endl;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM