How to access a specific (row,col) index in an C++ Eigen sparse matrix?
Asked Answered
C

3

17

I'm working in C++ with a sparse matrix in Eigen. I would like to read the data stored in a specific row and column index just like I would with a regular eigen 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

How do I go about performing this type of indexing operation?

Chamber answered 21/2, 2017 at 19:21 Comment(1)
One possible solution is to construct a dense matrix from the sparse matrix (Eigen::MatrixXd dense = Eigen::MatrixXd(sparse);), but this has a large computational cost and is undesirable in most applications.Chamber
C
26

Try coeff:

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

If you want a non-const version use coeffRef instead. Note that when using coeffRef if the element doesn't exist, it will be inserted.

Cough answered 21/2, 2017 at 19:42 Comment(1)
Documentation: eigen.tuxfamily.org/dox/…Chamber
M
1

This Code work for me

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

Mcgovern answered 21/2, 2017 at 19:46 Comment(0)
R
-1

Here is how to do it in the raw:

The methods you want are innerIndexPtr, outerIndexPtr, InnerNNZs and 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()];
  }
};      

Use:

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

Code not tested. Based off these docs and these docs which disagree in some details.

I suspect I just reimplmeented .coeff, so take this with a grain of salt. :)

Recrudescence answered 21/2, 2017 at 19:53 Comment(1)
Please do not post not tested code or huge code blocks without explanation.Homestead

© 2022 - 2024 — McMap. All rights reserved.