Reputation: 6707
With Eigen: given a large sparse matrix, what would be the quickest way to determine if a value at a given position is null or not ?
It must be said that I use this sparse matrix implementation to store non-numeric values. It's related to this question.
At present, what I have is (with T
my data type):
Eigen::SparseMatrix<T> mat(n,n); // n could be 1000, 10000, ...
// fill
T e1( /* some values */ );
mat.insert( 3, 4 ) = e1;
...
Checking is done with:
T elem = mat.coeff( row, col );
if( elem == T() ) // use default constructor
std::cout << "empty !\n";
But this doesn't satisfy me, as it implies both a copy operation and a deep comparison operator. What I would like could be something like:
if( mat.isNull( row, col ) )
std::cout << "empty !\n";
Is there a way I can do this ? Or fetch a pointer that return nullptr
if empty?
I checked Tutorial pages, quick ref and relevant manual pages but didn't find anything.
If this appears to be not possible, then I am thinking about wrapping it in a class along with a map holding all the filled positions. That way I could quickly find out if a given row,col has a value.
Addendum: I have Eigen 3.2 but could switch to 3.3 if required.
Edit: the linked question asks how to get a set of non-null elements. What I am asking for is "how do I know if the value at (row,col) is null ?". Not a dupe AFAIK.
Upvotes: 2
Views: 1771
Reputation: 18807
Depending on the number of elements per column, the most efficient solution might be to do a binary search the same way as coeffRef()
. You can in fact copy that function, replace all returns by true
or false
and integrate it into the SparseMatrix
using the plugin-mechanism.
Most of the time it is inefficient to access individual elements of a sparse matrix, though.
Upvotes: 1
Reputation: 23058
Derived from https://eigen.tuxfamily.org/dox-devel/group__TutorialSparse.html , you can define the null checking function like
bool isNull(const Eigen::SparseMatrix<T>& mat, int row, int col)
{
for (Eigen::SparseMatrix<T>::InnerIterator it(mat, col); it; ++it) {
if (it.row() == row) return false;
}
return true;
}
This way you don't copy anything. You don't perform deep comparison either.
Upvotes: 1