2015-11-06 4 views
0

У меня растущая база данных в виде Eigen::MatrixXd. Моя матрица пуста и получает строки, добавленные один за другим, пока не достигнет максимального предопределенного (известного во время компиляции) количества строк.Как распределить память для растущего Eigen :: MatrixXd

На данный момент я выращиваю это так (из документации Эйген и много сообщений здесь и в других местах):

MatrixXd new_database(database.rows()+1, database.cols()); 
new_database << database, new_row; 
database = new_database; 

Но это, кажется, путь более неэффективен, чем это должно быть, так как это делает много бесполезное перераспределение памяти и копирование данных каждый раз, когда добавляется новая строка ... Кажется, я должен иметь возможность предварительно выделить кучу памяти размером MAX_ROWS*N_COLS и позволить матрице расти в ней, однако я не могу найти эквивалент std::vectorcapacity с Eigen.

Примечание: Возможно, мне понадобится использовать матрицу в любое время, пока она не будет полностью заполнена. Поэтому мне нужно провести различие между тем, что было бы его size и что было бы его capacity.

Как это сделать?

EDIT 1: Я вижу, что есть MaxSizeAtCompileTime, но я считаю, что документ довольно неясен без примеров. Кто-нибудь знает, как это сделать, как использовать этот параметр и как он будет взаимодействовать с resize и conservativeResize?

EDIT 2: C++: Eigen conservativeResize too expensive? предлагает еще один интересный подход при постановке вопроса относительно несмежных данных ... У кого-нибудь есть хорошее представление по этому вопросу?

+0

Почему бы не использовать std :: vector? – Nandu

+0

потому что я делаю умножение матрицы. Я думал об использовании 'std :: vector'' Eigen :: Vector', но я предполагаю, что умножение «Eigen :: Matrix» с «Eigen :: Vector» будет оптимизировано и более эффективно, чем использование нескольких точечных продуктов из 'Eigen :: Vector''s в цикле for, чтобы затем заполнить новый« Eigen :: Vector »результатами ... – Julien

+0

В документах упоминается консервативная функцияResize, которая сохраняет значения матрицы. По крайней мере, это избавит вас от кодирования размера, как вы делали. Не уверен, что он имеет лучшую производительность. –

ответ

2

Прежде всего я хочу упомянуть, что вы можете захотеть использовать основную матрицу для хранения.

Простейшим (и, вероятно, лучшим) решением для вашего вопроса было бы использовать block operations для доступа к верхним строкам.

#include <Eigen/Core> 
#include <iostream> 

using namespace Eigen; 

int main(void) 
{ 
    const int rows = 5; 
    const int cols = 6; 

    MatrixXd database(rows, cols); 
    database.setConstant(-1.0); 

    std::cout << database << "\n\n"; 

    for (int i = 0; i < rows; i++) 
    { 
     database.row(i) = VectorXd::Constant(cols, i); 

     // Use block operations instead of the full matrix 
     std::cout << database.topRows(i+1) << "\n\n"; 

    } 

    std::cout << database << "\n\n"; 

    return 0; 
} 

Вместо того чтобы просто печатать матрицу, вы можете выполнять все необходимые операции.

+0

Чтобы выполнить ответ, чтобы избежать повторения '.topRows()' каждый раз, вы можете обернуть его, используя либо C++ ' auto' или в C++ 98, объявите: 'Eigen :: Ref db = database.topRows (i + 1)' и используйте db как регулярную 'Eigen :: Matrix'. – ggael

Смежные вопросы