Spec-Zone.ru › Eigen3

Перестройка

Начиная с версии 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API