2015-10-28 1 views
3

Интересно, есть ли хороший способ извлечь блоки/ROI с Eigen :: SparseMatrix? Точнее, то, что я хочу извлечь, это Внутренние векторы.Извлечение блоков/ROI от Eigen :: SparseMatrix без копирования

То, что я хочу сделать, это как:

typedef Eigen::SparseMatrix<double,Eigen::RowMajor> SpMat; 
// Prepare some sparse matrix 
SpMat spmat; 
// Extract lines from it 
const SpMat& row_i = spmat.innerVector(i); 
const SpMat& row_j = spmat.innerVector(j); 
// Some calculation with row_i and row_j... 

Как я тестировал, данные row_i и row_j является скопирована (!!) из spmat. Однако, очевидно, это неэффективно. Данные (например, row_i.m_data.m_values)) внутренних векторов является непрерывной частью исходных данных (spmat.m_data.m_values & spmat.m_data.m_indices соответственно), поэтому должен быть более умный способ.

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

Любая помощь будет благодарна! Спасибо заранее.

ответ

3

Вы можете использовать C++ 11 auto ключевое слово, чтобы объявить row_i и row_j как истинные выражения чтения-записи, или использовать соответствующий тип:

const auto row_i = spmap.innerVector(i); // C++11 version 
const SpMat::InnerVectorReturnType row_i = spmap.innerVector(i); // C++98 version 

Кроме того, не то, что по умолчанию SparseMatrix хранится в столбце major, поэтому «внутренний вектор» является столбцом. Если вы хотите ссылаться на ряды, то вам нужно использовать строение хранилища строк:

typedef Eigen::SparseMatrix<double,RowMajor> SpMat; 
+0

Он работает так, как я ожидал! Thxs :) А также спасибо за указание на колонку/строку-майор. Я изменил свой вопрос. –

1

Вы можете использовать класс MappedSparseMatrix. Он обертывает существующий набор данных и связанных параметров (я думаю, я никогда не использовал его). Я предполагаю, что он работает аналогично классу Eigen::Map, но я могу ошибаться.

MappedSparseMatrix<double> mat(int rows, int cols, int nnz, 
        int* outerIndexPtr, int* innerIndexPtr, 
        Scalar* valuePtr); 

Source

+0

Спасибо, он также решает мою проблему. Я могу сделать как 'Eigen :: MappedSparseMatrix row_i_map (1, spmat.innerSize(), nnz, spmat.outerIndexPtr() + j, spmat.innerIndexPtr(), spmat.valuePtr()); '. Для более поздних пользователей я указываю, что 'MappedSparseMatrix' ожидает, что' innerIndexPtr' и 'valuePtr' будут непрерывными в памяти. Это означает, что вы можете использовать только с 'innerVecotr (s)', и если вы хотите извлечь несколько внутренних векторов, исходной матрицей должно быть [compressd] (http://eigen.tuxfamily.org/dox/classEigen_1_1SparseMatrix.html#a4549e80dac9fd4f4c9ecee00814ecaa5). –

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