Please, help us to better know about our user community by answering the following short survey: https://forms.gle/wpyrxWi18ox9Z5ae9
 Eigen  3.3.9

Eigen does not expose convenient methods to take slices or to reshape a matrix yet. Nonetheless, such features can easily be emulated using the Map class.

# Reshape

A reshape operation consists in modifying the sizes of a matrix while keeping the same coefficients. Instead of modifying the input matrix itself, which is not possible for compile-time sizes, the approach consist in creating a different view on the storage using class Map. Here is a typical example creating a 1D linear view of a matrix:

Example:Output:
MatrixXf M1(3,3); // Column-major storage
M1 << 1, 2, 3,
4, 5, 6,
7, 8, 9;
Map<RowVectorXf> v1(M1.data(), M1.size());
cout << "v1:" << endl << v1 << endl;
Matrix<float,Dynamic,Dynamic,RowMajor> M2(M1);
Map<RowVectorXf> v2(M2.data(), M2.size());
cout << "v2:" << endl << v2 << endl;
v1:
1 4 7 2 5 8 3 6 9
v2:
1 2 3 4 5 6 7 8 9


Remark how the storage order of the input matrix modifies the order of the coefficients in the linear view. Here is another example reshaping a 2x6 matrix to a 6x2 one:

Example:Output:
MatrixXf M1(2,6); // Column-major storage
M1 << 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12;
Map<MatrixXf> M2(M1.data(), 6,2);
cout << "M2:" << endl << M2 << endl;
M2:
1  4
7 10
2  5
8 11
3  6
9 12


# Slicing

Slicing consists in taking a set of rows, columns, or elements, uniformly spaced within a matrix. Again, the class Map allows to easily mimic this feature.

For instance, one can skip every P elements in a vector:

Example:Output:
RowVectorXf v = RowVectorXf::LinSpaced(20,0,19);
cout << "Input:" << endl << v << endl;
Map<RowVectorXf,0,InnerStride<2> > v2(v.data(), v.size()/2);
cout << "Even:" << v2 << endl;
Input:
0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
Even: 0  2  4  6  8 10 12 14 16 18


One can olso take one column over three using an adequate outer-stride or inner-stride depending on the actual storage order:

Example:Output:
MatrixXf M1 = MatrixXf::Random(3,8);
cout << "Column major input:" << endl << M1 << "\n";
Map<MatrixXf,0,OuterStride<> > M2(M1.data(), M1.rows(), (M1.cols()+2)/3, OuterStride<>(M1.outerStride()*3));
cout << "1 column over 3:" << endl << M2 << "\n";
typedef Matrix<float,Dynamic,Dynamic,RowMajor> RowMajorMatrixXf;
RowMajorMatrixXf M3(M1);
cout << "Row major input:" << endl << M3 << "\n";
Map<RowMajorMatrixXf,0,Stride<Dynamic,3> > M4(M3.data(), M3.rows(), (M3.cols()+2)/3,
Stride<Dynamic,3>(M3.outerStride(),3));
cout << "1 column over 3:" << endl << M4 << "\n";
Column major input:
-1 -0.0827  -0.906   0.869   0.662  0.0594  -0.233   0.374
-0.737  0.0655   0.358  -0.233  -0.931   0.342  -0.866   0.178
0.511  -0.562   0.359  0.0388  -0.893  -0.985  -0.165   0.861
1 column over 3:
-1  0.869 -0.233
-0.737 -0.233 -0.866
0.511 0.0388 -0.165
Row major input:
-1 -0.0827  -0.906   0.869   0.662  0.0594  -0.233   0.374
-0.737  0.0655   0.358  -0.233  -0.931   0.342  -0.866   0.178
0.511  -0.562   0.359  0.0388  -0.893  -0.985  -0.165   0.861
1 column over 3:
-1  0.869 -0.233
-0.737 -0.233 -0.866
0.511 0.0388 -0.165

Eigen::DenseBase::LinSpaced
static const SequentialLinSpacedReturnType LinSpaced(Sequential_t, Index size, const Scalar &low, const Scalar &high)
Definition: CwiseNullaryOp.h:224
Eigen::DenseBase::Random
static const RandomReturnType Random()
Definition: Random.h:113