te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>matlab - Fastest way to find first ZERO element of a sparse matrix - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

matlab - Fastest way to find first ZERO element of a sparse matrix - Stack Overflow

programmeradmin3浏览0评论

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?

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?

Share Improve this question asked Feb 17 at 23:26 magnesiummagnesium 4852 silver badges11 bronze badges 8
  • Sparse arrays store non-zero elements in order. Just look through those until you find a missing element. – Cris Luengo Commented Feb 18 at 0:12
  • i.e. the naive loop I have above (in the second part of the snippet) -- or do you mean something else? Is that really the fastest way? – magnesium Commented Feb 18 at 0:46
  • 1 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 that idx(n) = ii + (jj-1)*n is the same as idx(n) = kk. And x(ii,jj)==0 is the same as x(kk)==0. So removing the call to ind2sub should simplify and hopefully speed up your code. – Cris Luengo Commented Feb 18 at 1:37
  • But I was thinking of looking through the data as stored: a sparse matrix stores indices to non-zero elements and their values. You should be able to iterate faster over just the indices of the non-zero elements. Except I don’t know how to get that data in MATLAB. In a MEX-file this would be simple: mathworks/help/matlab/apiref/mxgetir.html — indexing into a sparse array is more expensive than indexing into a full array. – Cris Luengo Commented Feb 18 at 1:42
  • 1 How big is your actual array? Because 5000x1 is tiny and it's not worth using a sparse array for. You need much, much larger arrays to make the sparse array overhead worth while. – Cris Luengo Commented Feb 18 at 6:07
 |  Show 3 more comments

1 Answer 1

Reset to default 2

For positive arrays min is probably the fastest solution:

x = sparse(5000, 1);
x(randsample(5000, 500)) = 1; 
[~, idx] = min(x);

ismember can also be used:

[~, ind] = ismember(0, x);
发布评论

评论列表(0)

  1. 暂无评论