Перестройка
Начиная с версии 3.4, Eigen предоставляет удобные методы для перестройки матрицы в другую матрицу разных размеров или вектор. Все случаи обрабатываются функциями DenseBase::reshaped(NRowsType,NColsType) и DenseBase::reshaped(). Эти функции не выполняют перестройку на месте, а вместо этого возвращают просмотр входного выражения.
Просмотр 2D перестроек
Более общая операция перестройки обрабатывается с помощью: reshaped(nrows,ncols). Вот пример перестройки 4x4 матрицы в 2x8:
| Пример: | Вывод: |
|---|---|
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: 7 9 -5 -3 -2 -6 1 0 6 -3 0 9 6 6 3 9 Here is m.reshaped(2, 8): 7 6 9 -3 -5 0 -3 9 -2 6 -6 6 1 3 0 9 |
По умолчанию входные коэффициенты всегда интерпретируются в порядке следования столбцов независимо от порядка хранения входного выражения. Для большего контроля над порядком, размерами времени компиляции и автоматическим выводом размеров, пожалуйста, ознакомьтесь с документацией DenseBase::reshaped(NRowsType,NColsType), которая содержит все подробности с множеством примеров.
1D линейные просмотры
Очень распространенное использование перестройки — создание 1D линейного просмотра заданной 2D матрицы или выражения. В этом случае размеры могут быть вычислены и, таким образом, опущены, как в следующем примере:
| Пример: |
|---|
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; |
| Вывод: |
Here is the matrix m: 7 9 -5 -3 -2 -6 1 0 6 -3 0 9 6 6 3 9 Here is m.reshaped().transpose(): 7 -2 6 6 9 -6 -3 6 -5 1 0 3 -3 0 9 9 Here is m.reshaped<RowMajor>().transpose(): 7 9 -5 -3 -2 -6 1 0 6 -3 0 9 6 6 3 9 |
Этот сокращенный вариант всегда возвращает вектор-столбец, и по умолчанию входные коэффициенты всегда интерпретируются в порядке следования столбцов. Опять же, см. документацию DenseBase::reshaped() для большего контроля над порядком.
TutorialReshapeInPlace
Приведенные выше примеры создают просмотры перестроек, но как насчет перестройки заданной матрицы на месте? Конечно, эта задача возможна только для матриц и массивов с размерами во время выполнения. Во многих случаях это можно сделать с помощью PlainObjectBase::resize(Index,Index):
| Пример: |
|---|
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; |
| Вывод: |
Here is the matrix m: 7 9 -5 -3 -2 -6 1 0 6 -3 0 9 6 6 3 9 Here is m.reshaped(2, 8): 7 6 9 -3 -5 0 -3 9 -2 6 -6 6 1 3 0 9 Here is the matrix m after m.resize(2,8): 7 6 9 -3 -5 0 -3 9 -2 6 -6 6 1 3 0 9 |
Однако следует учитывать, что в отличие от reshaped, результат resize зависит от порядка хранения входных данных. Таким образом, он ведет себя аналогично reshaped<AutoOrder>.
| Пример: |
|---|
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; |
| Вывод: |
Here is the matrix m: 7 -2 6 6 9 -6 -3 6 -5 1 0 3 -3 0 9 9 Here is m.reshaped(2, 8): 7 -5 -2 1 6 0 6 3 9 -3 -6 0 -3 9 6 9 Here is m.reshaped<AutoOrder>(2, 8): 7 -2 6 6 9 -6 -3 6 -5 1 0 3 -3 0 9 9 Here is the matrix m after m.resize(2,8): 7 -2 6 6 9 -6 -3 6 -5 1 0 3 -3 0 9 9 |
Наконец, присвоение перестроенной матрицы самой себе в настоящее время не поддерживается и приведет к неопределенному поведению из-за алиасинга. Следующее запрещено:
A = A.reshaped(2,8);
Это нормально:
A = A.reshaped(2,8).eval();
© Eigen.
Licensed under the MPL2 License.
https://eigen.tuxfamily.org/dox/group__TutorialReshape.html