kebs
kebs

Reputation: 6707

sparse matrices: fastest way to determine if value is null or not?

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

Answers (2)

chtz
chtz

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

timrau
timrau

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

Related Questions