Есть ли эффективный способ удаления уже выделенных, но пустых собственных строк без перераспределения? - PullRequest
0 голосов
/ 29 мая 2019

Я пытаюсь написать эффективный код во время выполнения, используя класс Eigen :: Matrix.Для улучшения времени выполнения я знаю, что изменение размера Eigen :: Matrix рекомендуется так, чтобы выделялось достаточно памяти и, таким образом, избегалось перераспределение.Тем не менее, я не знаю количество строк во время компиляции или при инициализации матрицы.Что я хочу сделать, так это использовать матрицу динамического размера, выделить память с известным верхним пределом, затем заполнить некоторые данные в матрице и, наконец, «обрезать / изменить» младшие строки, которые мне не нужны.

Итак, моя проблема выглядит следующим образом, за исключением того, что память, которую я выделяю, намного больше (5,3)

    Eigen::MatrixXi M;
    M.resize(5,3);
    std::cout << "M size: (" << M.rows() << "x" << M.cols()<< " ) with Entries:\n"<< M << std::endl;
    M.row(0) = Eigen::RowVector3i(1, 1, 1);
    M.row(1) = Eigen::RowVector3i(2, 2, 2);
    M.row(2) = Eigen::RowVector3i(3, 3, 3);
    //M.reshape(3, 3); ??
    std::cout << "M size: (" << M.rows() << "x" << M.cols() << " ) with Entries:\n" << M << std::endl;

Я знаю, что следующий код будет работать, но этот фрагмент включает перераспределение новой памяти вместопросто "освободить" нижние строки М или переназначить память М;

    // works but inefficient
    Eigen::MatrixXi M2;
    M2.resize(3, 3);
    M2 = M.topRows(3);

Есть ли у вас какие-либо идеи о том, как я могу реализовать эту идею более эффективно?

1 Ответ

0 голосов
/ 31 мая 2019

Прежде всего, если вы добавляете записи построчно, может быть более эффективно использовать матрицу мажорных строк.Кроме того, если во время компиляции известно, что число столбцов равно 3, вы можете выразить это в виде:

typedef Eigen::Matrix<int, Eigen::Dynamic, 3, Eigen::RowMajor> MatrixRX3i;
MatrixRX3i M;
M.resize(5,3);

Если вы не возражаете, что вся память M сохраняетсявсе время вы можете определить M2 как Eigen::Ref объект:

Eigen::Ref<MatrixRX3i> M2(M.topRows(3));

Если вы хотите освободить ненужную память, вы должны использовать conservativeResize():

M.conservativeResize(3,3);

В идеале это должно просто вызвать std::realloc (в случае, если внутреннее измерение не изменится), хотя могут быть некоторые связанные с выравниванием угловые случаи.

...