Eigen  5.0.1
 
Loading...
Searching...
No Matches

Since the version 3.4, Eigen exposes convenient methods to reshape a matrix to another matrix of different sizes or vector. All cases are handled via the DenseBase::reshaped(NRowsType,NColsType) and DenseBase::reshaped() functions. Those functions do not perform in-place reshaping, but instead return a view on the input expression.

Reshaped 2D views

The more general reshaping transformation is handled via: reshaped(nrows,ncols). Here is an example reshaping a 4x4 matrix to a 2x8 one:

Example:Output:
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
Matrix4i m = Matrix4i::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is m.reshaped(2, 8):" << endl << m.reshaped(2, 8) << endl;
Here is the matrix m:
 1804289383 -1550966999  -782303108   336465782
 -465790871 -1122281286 -1843394476   278722862
 1957747793 -1364114958    35005211  2145174067
-1427598262  -102585885 -1852781081 -1045969719
Here is m.reshaped(2, 8):
 1804289383  1957747793 -1550966999 -1364114958  -782303108    35005211   336465782  2145174067
 -465790871 -1427598262 -1122281286  -102585885 -1843394476 -1852781081   278722862 -1045969719

By default, the input coefficients are always interpreted in column-major order regardless of the storage order of the input expression. The following example with increasing coefficients makes this reading order explicit:

Example:Output:
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
MatrixXf M1(2, 6); // Column-major storage
M1 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
cout << "M2:" << endl << M1.reshaped(6, 2) << endl;
M2:
 1  4
 7 10
 2  5
 8 11
 3  6
 9 12

For more control on ordering, compile-time sizes, and automatic size deduction, please see the documentation of DenseBase::reshaped(NRowsType,NColsType) that contains all the details with many examples.

1D linear views

A very common usage of reshaping is to create a 1D linear view over a given 2D matrix or expression. In this case, sizes can be deduced and thus omitted as in the following example:

Example:
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
Matrix4i m = Matrix4i::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is m.reshaped().transpose():" << endl << m.reshaped().transpose() << endl;
cout << "Here is m.reshaped<RowMajor>().transpose(): " << endl << m.reshaped<RowMajor>().transpose() << endl;
Output:
Here is the matrix m:
 1804289383 -1550966999  -782303108   336465782
 -465790871 -1122281286 -1843394476   278722862
 1957747793 -1364114958    35005211  2145174067
-1427598262  -102585885 -1852781081 -1045969719
Here is m.reshaped().transpose():
 1804289383  -465790871  1957747793 -1427598262 -1550966999 -1122281286 -1364114958  -102585885  -782303108 -1843394476    35005211 -1852781081   336465782   278722862  2145174067 -1045969719
Here is m.reshaped<RowMajor>().transpose():  
 1804289383 -1550966999  -782303108   336465782  -465790871 -1122281286 -1843394476   278722862  1957747793 -1364114958    35005211  2145174067 -1427598262  -102585885 -1852781081 -1045969719

This shortcut always returns a column vector and by default input coefficients are always interpreted in column-major order. To follow the storage order of the input instead, pass AutoOrder, as in the following example flattening the same data stored in column-major and row-major order:

Example:
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
MatrixXf M1(3, 3); // Column-major storage
M1 << 1, 2, 3, 4, 5, 6, 7, 8, 9;
cout << "v1:" << endl << M1.reshaped().transpose() << endl;
Matrix<float, Dynamic, Dynamic, RowMajor> M2(M1);
cout << "v2:" << endl << M2.reshaped<AutoOrder>().transpose() << endl;
Output:
v1:
1 4 7 2 5 8 3 6 9
v2:
1 2 3 4 5 6 7 8 9

Again, see the documentation of DenseBase::reshaped() for more control on the ordering.

Reshaping in place

The above examples create reshaped views, but what about reshaping inplace a given matrix? Of course this task is only conceivable for matrices and arrays having runtime dimensions. In many cases, this can be accomplished via PlainObjectBase::resize(Index,Index):

Example:
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
MatrixXi m = Matrix4i::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is m.reshaped(2, 8):" << endl << m.reshaped(2, 8) << endl;
m.resize(2, 8);
cout << "Here is the matrix m after m.resize(2,8):" << endl << m << endl;
Output:
Here is the matrix m:
 1804289383 -1550966999  -782303108   336465782
 -465790871 -1122281286 -1843394476   278722862
 1957747793 -1364114958    35005211  2145174067
-1427598262  -102585885 -1852781081 -1045969719
Here is m.reshaped(2, 8):
 1804289383  1957747793 -1550966999 -1364114958  -782303108    35005211   336465782  2145174067
 -465790871 -1427598262 -1122281286  -102585885 -1843394476 -1852781081   278722862 -1045969719
Here is the matrix m after m.resize(2,8):
 1804289383  1957747793 -1550966999 -1364114958  -782303108    35005211   336465782  2145174067
 -465790871 -1427598262 -1122281286  -102585885 -1843394476 -1852781081   278722862 -1045969719

However beware that unlike reshaped, the result of resize depends on the input storage order. It thus behaves similarly to reshaped<AutoOrder>:

Example:
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
Matrix<int, Dynamic, Dynamic, RowMajor> m = Matrix4i::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is m.reshaped(2, 8):" << endl << m.reshaped(2, 8) << endl;
cout << "Here is m.reshaped<AutoOrder>(2, 8):" << endl << m.reshaped<AutoOrder>(2, 8) << endl;
m.resize(2, 8);
cout << "Here is the matrix m after m.resize(2,8):" << endl << m << endl;
Output:
Here is the matrix m:
 1804289383  -465790871  1957747793 -1427598262
-1550966999 -1122281286 -1364114958  -102585885
 -782303108 -1843394476    35005211 -1852781081
  336465782   278722862  2145174067 -1045969719
Here is m.reshaped(2, 8):
 1804289383  -782303108  -465790871 -1843394476  1957747793    35005211 -1427598262 -1852781081
-1550966999   336465782 -1122281286   278722862 -1364114958  2145174067  -102585885 -1045969719
Here is m.reshaped<AutoOrder>(2, 8):
 1804289383  -465790871  1957747793 -1427598262 -1550966999 -1122281286 -1364114958  -102585885
 -782303108 -1843394476    35005211 -1852781081   336465782   278722862  2145174067 -1045969719
Here is the matrix m after m.resize(2,8):
 1804289383  -465790871  1957747793 -1427598262 -1550966999 -1122281286 -1364114958  -102585885
 -782303108 -1843394476    35005211 -1852781081   336465782   278722862  2145174067 -1045969719

Finally, assigning a reshaped matrix to itself is currently not supported and results in undefined behavior because of aliasing . The following is forbidden:

A = A.reshaped(2,8);

This is OK:

A = A.reshaped(2,8).eval();