When using sparse matrices, it's easy to find non-zero entries quickly (as these are the only elements stored). However, what's the best way to find the first ZERO entry? Using approaches like find(X==0,1) or find(~X,1) tend to be slow as these require the negation of the whole matrix. It doesn't feel like that should be necessary -- is there a better way?
For instance, naively iterating over the array seems to be slightly faster than using find(X==0,1):
% Create a sparse array [10% filled]
x = sparse(5000,1);
x(randsample(5000,500)) = 1;
nRuns = 1e5;
% Find the first element, a million times
idx = zeros(nRuns,1);
tic
for n=1:nRuns
idx(n) = find(x==0,1);
end
toc
%%
% Create a sparse array [10% filled]
x = sparse(5000,1);
x(randsample(5000,500)) = 1;
nRuns = 1e5;
% Find the first element, a million times
idx = zeros(nRuns,1);
tic
for n=1:nRuns
for kk = 1:numel(x)
[ii,jj] = ind2sub(size(x), kk);
if x(ii,jj)==0; idx(n) = ii + (jj-1)*n; break; end
end
end
toc
But what is the best way to do this?
find(X==0,1)compares the whole matrix to zero (maybe even producing a full matrix?), then looks for the first non-zero element. In the loop you don’t touch most of the matrix. And it being a sparse matrix, you likely have mostly zero elements (if not, don’t use a sparse matrix), so the loop should terminate really quickly. Note thatidx(n) = ii + (jj-1)*nis the same asidx(n) = kk. Andx(ii,jj)==0is the same asx(kk)==0. So removing the call toind2subshould simplify and hopefully speed up your code.