![]() |
Eigen
5.0.1
|
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.
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.
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.
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:
This is OK: