3
votes

let's say I have a big Matrix X with a lot of zeros, so of course I make it sparse in order to save on memory and CPU. After that I do some stuff and at some point I want to have the nonzero elements. My code looks something like this:

 ind = M ~= 0; % Whereby M is the sparse Matrix

This looks however rather silly to me since the structure of the sparse Matrix should allow the direct extraction of the information.

To clarify: I do not look for a solution that works, but rather would like to avoid doing the same thing twice. A sparse Matrix should perdefinition already know it's nonzero values, so there should be no need to search for it.

yours magu_

4

4 Answers

2
votes

The direct way to retrieve nonzero elements from a sparse matrix, is to call nonzeros().

The direct way is obviously the fastest method, however I performed some tests against logical indexing on the sparse and its full() counterparty, and the indexing on the former is faster (results depend on the sparsity pattern and dimension of the matrix).

The sum of times over 100 iterations is:

nonzeros:   0.02657 seconds
sparse idx: 0.52946 seconds
full idx:   2.27051 seconds

The testing suite:

N = 100;
t = zeros(N,3);
for ii = 1:N
    s = sprand(10000,1000,0.01);
    r = full(s);

    % Direct call nonzeros
    tic
    nonzeros(s);
    t(ii,1) = toc;

    % Indexing sparse
    tic
    full(s(s ~= 0));
    t(ii,2) = toc;

    % Indexing full
    tic
    r(r~=0);
    t(ii,3) = toc;
end

sum(t)
1
votes

I'm not 100% sure what you're after but maybe [r c] = find(M) suits you better?

You can get to the values of M by going M(r,c) but the best method will surely be dictated by what you intend to do with the data next.

1
votes

find function is recommended by MATLAB:

[row,col] = find(X, ...) returns the row and column indices of the nonzero entries in the matrix X. This syntax is especially useful when working with sparse matrices.

1
votes

While find has been proposed before, I think this is an important addition:

[r,c,v] = find(M);

Gives you not only the indices r,c, but also the non-zero values v. Using the nonzeros command seems to be a bit faster, but find is in general very useful when dealing with sparse matrices because the [r,c,v] vectors describe the complete matrix (except matrix dimension).