2017-02-21 15 views
3

Ich arbeite in C++ mit einer Sparse-Matrix in Eigen. Ich würde gerne die Daten lesen, die in einem bestimmten Zeilen- und Spaltenindex gespeichert sind, genau wie ich es bei einer regulären Eigenmatrix tun würde.Zugriff auf einen bestimmten (Zeilen-, Spalten-) Index in einer C++ Eigen-Sparse-Matrix?

std::vector<Eigen::Triplet<double>> tripletList; 

// TODO: populate triplet list with non-zero entries of matrix 

Eigen::SparseMatrix<double> matrix(nRows, nCols); 
matrix.setFromTriplets(tripletList.begin(), tripletList.end()); 

// TODO: set iRow and iCol to be valid indices. 

// How to read the value at a specific row and column index? 
// double value = matrix(iRow, iCol); // Compiler error 

Wie gehe ich bei der Durchführung dieser Art von Indizierung vor?

+0

Eine mögliche Lösung besteht darin, eine dichte Matrix aus der dünn besetzten Matrix aufzubauen ('Eigen :: MatrixXd dicht = Eigen :: MatrixXd (spärlich);'), aber dies hat einen hohen Rechenaufwand und ist in den meisten Anwendungen unerwünscht . – MattKelly

Antwort

7

Versuchen coeff:

double value = matrix.coeff(iRow, iCol); 

Wenn Sie eine nicht-const-Version verwenden wollen coeffRef statt. Beachten Sie, dass bei Verwendung von coeffRef, wenn das Element nicht existiert, es eingefügt wird.

+0

Genau das, was ich gesucht habe - danke! – MattKelly

+0

Dokumentation: https://eigen.tuxfamily.org/dox/classEigen_1_1SparseMatrix.html#ad2c8bc92696f39d53c5e598a50e58f68 – MattKelly

0

Dieser Kodex Arbeit für mich

for (int i=0; i<matrix.rows(); ++i){ 
     cout << " i,j=" << i << "," << j << " value=" << matrix.coeff(i,j) << std::endl; 
} 
0

Hier ist, wie es in der rohen zu tun:

Die Methoden, die Sie wollen, sind innerIndexPtr, outerIndexPtr, InnerNNZs und valuePtr.

struct sparseIndex { 
    std::size_t row, col; 
    template<class SparseMatrix, class Scalar=typename SparseMatrix::Scalar> 
    Scalar get_from(SparseMatrix const& m, Scalar def={}) const { 
    if ((std::size_t)m.cols() >= col) return def; 
    auto* inner_index_start = m.innerIndexPtr()+m.outerIndexPtr()[col]; 
    auto* inner_index_end = inner_index_start; 
    if (auto* nzp = m.innerNonZeroPtr()) { // returns null if compressed 
     inner_index_end += nzp[col]; 
    } else { 
     inner_index_end = m.innerIndexPtr()+m.outerIndexPtr()[col+1]; 
    } 
    auto search_result = std::equal_range(
     inner_index_start, 
     inner_index_end, 
     (typename SparseMatrix::StorageIndex)row 
    ); 
    if (search_result.first == search_result.second) return def; 
    if ((std::size_t)*search_result.first != row) return def; 
    return m.valuePtr()[search_result.first-m.innerIndexPtr()]; 
    } 
};  

Verwendung:

auto r = sparseIndex{2,2}.get_from(sparseMatrix); 

-Code nicht getestet. Basierend auf these docs und these docs, die in einigen Details nicht übereinstimmen.

Ich vermute, ich habe gerade .coeff reimplemeent, also nehmen Sie das mit einem Körnchen Salz. :)

Verwandte Themen