![]() |
Eigen
3.3.4
|
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.
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 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: 0.68 0.597 -0.33 0.108 -0.27 0.832 -0.717 -0.514 -0.211 0.823 0.536 -0.0452 0.0268 0.271 0.214 -0.726 0.566 -0.605 -0.444 0.258 0.904 0.435 -0.967 0.608 1 column over 3: 0.68 0.108 -0.717 -0.211 -0.0452 0.214 0.566 0.258 -0.967 Row major input: 0.68 0.597 -0.33 0.108 -0.27 0.832 -0.717 -0.514 -0.211 0.823 0.536 -0.0452 0.0268 0.271 0.214 -0.726 0.566 -0.605 -0.444 0.258 0.904 0.435 -0.967 0.608 1 column over 3: 0.68 0.108 -0.717 -0.211 -0.0452 0.214 0.566 0.258 -0.967 |