File: find.m

package info (click to toggle)
suitesparse-graphblas 7.4.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 67,112 kB
  • sloc: ansic: 1,072,243; cpp: 8,081; sh: 512; makefile: 503; asm: 369; python: 125; awk: 10
file content (116 lines) | stat: -rw-r--r-- 3,449 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
function [I, J, X] = find (G, k, search)
%FIND extract entries from a matrix.
% [I, J, X] = find (G) extracts the nonzeros from a matrix G.
% X has the same type as G ('double', 'single', 'int8', ...).
%
% Linear 1D indexing (I = find (S) for the built-in matrix S) is not yet
% supported.
%
% A GraphBLAS matrix G may contain explicit zero entries, and by default
% these are excluded from the result.  Use GrB.extracttuples (G) to return
% these explicit zero entries.
%
% For a column vector, I = find (G) returns I as a list of the row indices
% of nonzeros in G.  For a row vector, I = find (G) returns I as a list of
% the column indices of nonzeros in G.
%
% [...] = find (G, k, 'first') returns the first k nonozeros of G.
% [...] = find (G, k, 'last')  returns the last k nonozeros of G.
% For this usage, the first and last k are in terms of nonzeros in the
% column-major order.
%
% See also sparse, GrB.build, GrB.extracttuples.

% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
% SPDX-License-Identifier: Apache-2.0

% FUTURE: find (G,k,'first') and find (G,k,'last') are slow.
% They are currently implemented, all entries are extracted and then the
% first or last k are selected from the extracted tuples.  It would be
% faster to use a mexFunction that directly accesses the opaque content
% of G, instead of using GrB_Matrix_extractTuples_*, which always extracts
% the entire matrix.

if (isobject (G))
    G = G.opaque ;
end

if (nargin > 1)
    k = ceil (double (gb_get_scalar (k))) ;
    if (k < 1)
        error ('GrB:error', 'k must be positive') ;
    end
    if (~isequal (gbformat (G), 'by col'))
        % find (G, k) assumes the matrix is stored by column, so reformat G
        % if it is stored by row.
        G = gbnew (G, 'by col') ;
    end
end

% prune explicit zeros
G = gbselect (G, 'nonzero') ;

[m, n] = gbsize (G) ;

if (nargout == 3)
    [I, J, X] = gbextracttuples (G) ;
    if (m == 1)
        I = I' ;
        J = J' ;
        X = X' ;
    end
elseif (nargout == 2)
    [I, J] = gbextracttuples (G) ;
    if (m == 1)
        I = I' ;
        J = J' ;
    end
else
    if (m == 1)
        % extract indices from a row vector
        [~, I] = gbextracttuples (G) ;
        I = I' ;
    elseif (n == 1)
        % extract indices from a column vector
        I = gbextracttuples (G) ;
    else
        % extract linear indices from a matrix
        [I, J] = gbextracttuples (G) ;
        % use the built-in sub2ind to convert the 2D indices to linear indices
        I = sub2ind ([m n], I, J) ;
    end
end

if (nargin > 1)
    % find (G, k, ...): get the first or last k entries
    if (nargin < 3)
        search = 'first' ;
    end
    n = length (I) ;
    if (k >= n)
        % output already has all k first or last entries;
        % nothing more to do
    elseif (isequal (search, 'first'))
        % find (G, k, 'first'): get the first k entries
        I = I (1:k) ;
        if (nargout > 1)
            J = J (1:k) ;
        end
        if (nargout > 2)
            X = X (1:k) ;
        end
    elseif (isequal (search, 'last'))
        % find (G, k, 'last'): get the last k entries
        I = I (n-k+1:n) ;
        if (nargout > 1)
            J = J (n-k+1:n) ;
        end
        if (nargout > 2)
            X = X (n-k+1:n) ;
        end
    else
        error ('GrB:error', ...
            'invalid search option; must be ''first'' or ''last''') ;
    end
end