1function result = nonz (A, varargin)
2%GRB.NONZ count or query the nonzeros of a matrix.
3% A GraphBLAS matrix can include explicit entries that have the value
4% zero.  These entries never appear in a MATLAB sparse matrix.  This
5% function counts or queries the nonzeros of matrix, checking their value
6% and treating explicit zeros the same as entries that do not appear in
7% the pattern of A.
8%
9% e = GrB.nonz (A)         number of nonzeros
10% e = GrB.nonz (A, 'all')  number of nonzeros
11% e = GrB.nonz (A, 'row')  number of rows with at least one nonzero
12% e = GrB.nonz (A, 'col')  number of columns with at least one nonzero
13%
14% X = GrB.nonz (A, 'list')         list of values of unique nonzeros
15% X = GrB.nonz (A, 'all', 'list')  list of values of unique nonzeros
16% I = GrB.nonz (A, 'row', 'list')  list of rows with at least one nonzero
17% J = GrB.nonz (A, 'col', 'list')  list of cols with at least one nonzero
18%
19% d = GrB.nonz (A, 'row', 'degree')
20%   If A is m-by-n, then d is a sparse column vector of size m, with d(i)
21%   equal to the number of nonzeros in A(i,:).  If A(i,:) has no
22%   nonzeros, then d(i) is an implicit zero, not present in the pattern
23%   of d, so I = find (d) is the same I = GrB.nonz (A, 'row', 'list').
24%
25% d = GrB.nonz (A, 'col', 'degree')
26%   If A is m-by-n, d is a sparse column vector of size n, with d(j)
27%   equal to the number of nonzeros in A(:,j).  If A(:,j) has no
28%   nonzeros, then d(j) is an implicit zero, not present in the pattern
29%   of d, so I = find (d) is the same I = GrB.nonz (A, 'col', 'list').
30%
31% With an optional scalar argument as the last argument, the value of the
32% 'zero' can be specified; d = GrB.nonz (A, ..., id).  For example, to
33% count all entries in A not equal to one, use GrB.nonz (A, 1).
34%
35% The result is a MATLAB scalar or vector, except for the 'degree'
36% usage, in which case the result is a GrB vector d.
37%
38% Example:
39%
40%   A = magic (5) ;
41%   A (A < 10) = 0              % MATLAB full matrix with explicit zeros
42%   nnz (A)
43%   GrB.nonz (A)                % same as nnz (A)
44%   G = GrB (A)                 % contains explicit zeros
45%   GrB.nonz (G)                % same as nnz (A)
46%   G (A > 18) = sparse (0)     % entries A>18 deleted, explicit zeros
47%   GrB.nonz (G)
48%   GrB.nonz (G, 'list')
49%   S = double (G)              % MATLAB sparse matrix; no explicit zeros
50%   GrB.nonz (S)
51%   GrB.nonz (S, 'list')
52%
53% See also GrB.entries, GrB/nnz, GrB/nonzeros, GrB.prune.
54
55% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
56% SPDX-License-Identifier: GPL-3.0-or-later
57
58matlab_sparse = false ;
59if (isobject (A))
60    % A is a GraphBLAS matrix; get its opaque content
61    A = A.opaque ;
62elseif (builtin ('issparse', A))
63    % A is a MATLAB sparse matrix
64    matlab_sparse = true ;
65end
66
67% get the identity value
68id = 0 ;
69nargs = nargin ;
70if (nargin > 1)
71    lastarg = varargin {nargs-1} ;
72    if (~ischar (lastarg))
73        % the last argument is id, if it is not a string
74        id = gb_get_scalar (lastarg) ;
75        nargs = nargs - 1 ;
76    end
77end
78
79if (id ~= 0)
80    % id is nonzero, so prune A first (for any matrix A)
81    A = gbselect (A, '~=', id) ;
82elseif (~matlab_sparse)
83    % id is zero, so prune A only if it is a GraphBLAS matrix,
84    % or a MATLAB full matrix.  A MATLAB sparse matrix can remain
85    % unchanged.
86    A = gbselect (A, 'nonzero') ;
87end
88
89% get the count/list of the entries of A
90result = gb_entries (A, varargin {1:nargs-1}) ;
91
92% if gb_entries returned a GraphBLAS struct, return it as a GrB matrix
93if (isstruct (result))
94    result = GrB (result) ;
95end
96
97