5

I have the following Eigen Tensor:

Eigen::Tensor<float, 3> m(3,10,10);

I want to access the 1st matrix. In numpy I would do it as such

m(0,:,:)

How would I do this in Eigen

raaj
  • 2,869
  • 4
  • 38
  • 58
  • 1
    I usually don't work with tensors in eigen, but here is some documentation I found that may help: https://github.com/RLovelett/eigen/tree/master/unsupported/Eigen/CXX11/src/Tensor. There is also a workaround here for using matrices instead of tensors when dimensions are > 2: https://studywolf.wordpress.com/2012/09/16/n-dimensional-matrices-in-c/. Good luck – rmilletich Feb 06 '18 at 20:00
  • I looked through the entire doc. There isn't any reference on how to access a block /matrix of a 3d tensor – raaj Feb 06 '18 at 20:24
  • You may have to create your own unique solution like the other stackoverflow post...here are some other workarounds using the MatrixXd type: https://stackoverflow.com/questions/17098218/most-efficient-option-for-build-3d-structures-using-eigen-matrices. – rmilletich Feb 06 '18 at 20:33
  • By the way, if you like numpy, then check out xtensor library for c++ if you have time. The api is very similar to numpy and you can access multidimensional arrays similar to numpy. – rmilletich Feb 06 '18 at 20:35
  • is this library fast? – raaj Feb 07 '18 at 18:45

1 Answers1

9

You can access parts of a tensor using .slice(...) or .chip(...). Do this to access the first matrix, equivalent to numpy m(0,:,:):

Eigen::Tensor<double,3> m(3,10,10);          //Initialize
m.setRandom();                               //Set random values 
std::array<long,3> offset = {0,0,0};         //Starting point
std::array<long,3> extent = {1,10,10};       //Finish point
std::array<long,2> shape2 = {10,10};         //Shape of desired rank-2 tensor (matrix)
std::cout <<  m.slice(offset, extent).reshape(shape2) << std::endl;  //Extract slice and reshape it into a 10x10 matrix.

If you want the "second" matrix, you use offset={1,0,0} instead, and so on.

You can find the most recent documentation here.

DavidAce
  • 466
  • 4
  • 7
  • While it does print, ```m.slice(offset, extent).reshape(shape2)``` does not return an Eigen Matrix type. – Madeleine P. Vincent May 01 '21 at 11:32
  • @MadeleineP.Vincent You are correct, this returns an expression of type `Eigen::TensorReshapingOp`. [See this post on how to convert back to Eigen::Matrix](https://stackoverflow.com/questions/48795789/eigen-unsupported-tensor-to-eigen-matrix) – DavidAce Aug 17 '21 at 08:27
  • @DavidAce is it possible to extract a slice and reshape it into a 3-by-10 matrix instead? I am struggling to extract a non-square matrix. This in MATLAB would be equivalent to ``val(:,:,1) `` – Jamie Aug 30 '22 at 04:45
  • 2
    @Jamie Yes! For a slice along the third axis in this example, you should take `offset = {0,0,0}`, `extent = {3,10,1}`, and then `shape2 = {3,10}`. – DavidAce Aug 31 '22 at 09:34