Reputation: 2137
I have a huge Eigen::SparseMatrix
, and I would like to add a scalar to the nonzero entries in the matrix.
That is, if I had a matrix A
with the values _
signifies a 0
entry in the sparse matrix, i.e. it was never inserted.
1 _ 2
A = _ 3 _
4 5 6
I would like to do something like A += 1
and arrive at
2 _ 3
A = _ 4 _
5 6 7
Where the zero entries are unaffected.
Is there any efficient way to do this?
Upvotes: 2
Views: 798
Reputation: 668
As a supplement to @m7913d's second answer: coeffs()
is a very useful function in processing coefficient-wise math functions. Eigen documents only provided dense matrix based math calculation -> https://eigen.tuxfamily.org/dox/group__CoeffwiseMathFunctions.html
For example, you can do sth like:
A.coeffs() = A.coeffs.exp();
Upvotes: 0
Reputation: 11072
I am aware of three different approaches:
Loop over all the non-zero values using an InnerIterator
for (int k=0; k<A.outerSize(); ++k)
for (SparseMatrix<double>::InnerIterator it(A,k); it; ++it)
it.valueRef() += 1;
This is a general method, which works in all cases, but may be slower than the other methods.
Using the coeffs
operator to obtain a 1D vector containing all the non-zero elements
A.makeCompressed();
A.coeffs() += 1;
This method may be faster if the matrix was already in compressed form or you need the compressed format.
Accessing the raw data using valuePtr
typedef Map<const Array<double,Dynamic,1> > CoeffMap;
CoeffMap coeffs(A.valuePtr(), A.outerIndexPtr()[A.outerSize()]);
coeffs += 1;
This method is probably the fastest method, but also the trickiest one and may be even slower on some machines due to performing a floating base operation on uninitialised data (see comment of chtz). If A
is in compressed format, this approach is equivalent to method 2.
Note that I have not benchmarked the different approaches. The performance information is purely based on intuition. If you want to do it, be sure to use real sized matrices.
Upvotes: 6