1classdef GrB
2%GrB GraphBLAS sparse matrices for MATLAB.
3%
4% GraphBLAS is a library for creating graph algorithms based on sparse
5% linear algebraic operations over semirings.  Visit http://graphblas.org
6% for more details and resources.  See also the SuiteSparse:GraphBLAS User
7% Guide in this package.
8%
9% The MATLAB GrB class represents a GraphBLAS sparse matrix.  The GrB
10% method creates a GraphBLAS sparse matrix from a MATLAB matrix.  Other
11% methods also generate GrB matrices.  For example:
12%
13%   G = GrB.subassign (C, M, A) ;
14%
15% constructs a GraphBLAS matrix G, which is the result of C<M>=A in
16% GraphBLAS notation (like C(M)=A(M) in MATLAB).  The matrices used in any
17% GrB.method may be MATLAB matrices (sparse or full) or GraphBLAS matrices
18% (hyper, sparse, bitmap, or full, by row or column), in any combination.
19%
20% --------------------
21% The GrB constructor:
22% --------------------
23%
24%   The GrB constructor creates a GraphBLAS matrix.  The input A may be
25%   any MATLAB or GraphBLAS matrix:
26%
27%   C = GrB (A) ;            GraphBLAS copy of a matrix A, same type
28%   C = GrB (m, n) ;         m-by-n GraphBLAS double matrix, no entries
29%   C = GrB (..., type) ;    create or typecast to a different type
30%   C = GrB (..., format) ;  create in a specified format
31%
32%   The m and n parameters above are MATLAB scalars.  The type and format
33%   parameters are strings.  The default format is 'by col', to match the
34%   format used in MATLAB (see also GrB.format), but many graph
35%   algorithms are faster if the format is 'by row'.  The format can also
36%   specify the data structure to use (hypersparse, sparse, bitmap, and/or
37%   full).
38%
39%   The usage C = GrB (m, n, type) is analgous to A = sparse (m, n),
40%   which creates an empty MATLAB sparse matrix A.  The type parameter is
41%   a string, which defaults to 'double' if not present.
42%
43%   For the usage C = GrB (A, type), A is either a MATLAB sparse or full
44%   matrix, or a GraphBLAS sparse matrix object.  C is created as a
45%   GraphBLAS sparse matrix object that contains a copy of A, typecasted
46%   to the given type if the type string does not match the type of A.
47%   If the type string is not present it defaults to 'double'.
48%
49% --------------------
50% Matrix types:
51% --------------------
52%
53%   Most of the valid type strings correspond to MATLAB class of the same
54%   name (see 'help class'):
55%
56%       'logical'           8-bit boolean
57%       'int8'              8-bit signed integer
58%       'int16'             16-bit signed integer
59%       'int32'             32-bit signed integer
60%       'int64'             64-bit signed integer
61%       'uint8'             8-bit unsigned integer
62%       'uint16'            16-bit unsigned integer
63%       'uint32'            32-bit unsigned integer
64%       'uint64'            64-bit unsigned integer
65%       'double'            64-bit floating-point (real, not complex)
66%       'single'            32-bit floating-point (real, not complex)
67%       'single complex'    single complex
68%       'double complex'    double complex (also just 'complex')
69%
70%   In MATLAB matrices, complex is an attribute, not a class.  In GrB
71%   matrices, 'double complex' and 'single complex' are treated as their
72%   own data types.
73%
74% ---------------
75% Matrix formats:
76% ---------------
77%
78%   The format of a GraphBLAS matrix can have a large impact on
79%   performance.  GraphBLAS matrices can be stored by column or by row.
80%   The corresponding format string is 'by col' or 'by row', respectively.
81%   Since the only format that MATLAB supports for its sparse and full
82%   matrices is 'by col', that is the default format for GraphBLAS
83%   matrices via this MATLAB interfance.  However, the default for the C
84%   API is 'by row' since graph algorithms tend to be faster with that
85%   format.
86%
87%   Column vectors are always stored 'by col', and row vectors are always
88%   stored 'by row'.  The format for new matrices propagates from the
89%   format of their inputs.  For example with C=A*B, C takes on the same
90%   format as A, unless A is a vector, in which case C takes on the format
91%   of B.  If both A and B are vectors, then the format of C is determined
92%   by the descriptor (if present), or by the default format (see
93%   GrB.format).
94%
95%   When a GraphBLAS matrix is converted into a MATLAB sparse or full
96%   matrix, it is always returned to MATLAB 'by col'.
97%
98%   The format can also specify the data structure to use.  By default
99%   GraphBLAS selects automatically between hypersparse, sparse, bitmap,
100%   and full formats.  See 'help GrB.format' for details.
101%
102%--------------------
103% Integer operations:
104%--------------------
105%
106%   Operations on integer values differ from MATLAB.  In MATLAB,
107%   uint8(255)+1 is 255, since the arithmetic saturates.  This is not
108%   possible in matrix operations such as C=A*B, since saturation of
109%   integer arithmetic would render most of the monoids useless.
110%   GraphBLAS instead computes a result modulo the word size, so that
111%   GrB(uint8(255))+1 is zero.  However, new unary and binary operators
112%   could be added so that element-wise operations saturate.  The C
113%   interface allows for arbitrary creation of user-defined operators, so
114%   this could be added in the future.  See 'help GrB/MATLAB_vs_GrB' for
115%   more details.
116%
117%-------------------------------------------------------------------------
118% Methods for the GrB class:
119%-------------------------------------------------------------------------
120%
121%   C = GrB (...)           construct a GraphBLAS matrix
122%
123% Overloaded MATLAB operators (all except 'colon'):
124%
125%   C = and (A, B)          C = A & B
126%   C = ctranspose (G)      C = G'
127%   i = end (G, k, ndims)   A(1:end,1:end)
128%   C = eq (A, B)           C = A == B
129%   C = ge (A, B)           C = A >= B
130%   C = gt (A, B)           C = A > B
131%   C = horzcat (A, B)      C = [A , B]
132%   C = ldivide (A, B)      C = A .\ B
133%   C = le (A, B)           C = A <= B
134%   C = lt (A, B)           C = A < B
135%   C = minus (A, B)        C = A - B
136%   C = mldivide (A, B)     C = A \ B
137%   C = mpower (A, B)       C = A ^ B
138%   C = mrdivide (A, B)     C = A / B
139%   C = mtimes (A, B)       C = A * B
140%   C = ne (A, B)           C = A ~= B
141%   C = not (G)             C = ~G
142%   C = or (A, B)           C = A | B
143%   C = plus (A, B)         C = A + B
144%   C = power (A, B)        C = A .^ B
145%   C = rdivide (A, B)      C = A ./ B
146%   I = subsindex (G)       X = A (G)
147%   C = subsasgn (C, S, A)  C (I,J) = A or C (M) = A
148%   C = subsref (A, S)      C = A (I,J) or C = A (M)
149%   C = times (A, B)        C = A .* B
150%   C = transpose (G)       C = G.'
151%   C = uminus (G)          C = -G
152%   C = uplus (G)           C = +G
153%   C = vertcat (A, B)      C = [A ; B]
154%
155% Overloaded MATLAB functions:
156%
157%   C = abs (G)             absolute value
158%   C = acos (G)            inverse cosine
159%   C = acosh (G)           inverse hyperbolic cosine
160%   C = acot (G)            inverse cotangent
161%   C = acoth (G)           inverse hyperbolic cotangent
162%   C = acsc (G)            inverse cosecant
163%   C = acsch (G)           inverse hyperbolic cosecant
164%   C = all (G, ...)        reduce via '&', to vector or scalar
165%   p = amd (G, ...)        approximate minimum degree ordering
166%   C = angle (G)           phase angle of a complex matrix
167%   C = any (G, ...)        reduce via '|', to vector or scalar
168%   C = asec (G)            inverse secant
169%   C = asech (G)           inverse hyperbolic secant
170%   C = asin (G)            inverse sine
171%   C = asinh (G)           inverse hyperbolic sine
172%   assert (G)              generate an error if G is false
173%   C = atan (G)            inverse tangent
174%   C = atanh (G)           inverse hyperbolic tangent
175%   C = atan2 (A, B)        inverse tangent (four-quadrant)
176%
177%   [lo, hi] = bandwidth (G, ...)   lower and upper bandwidth of G
178%   C = bitand (A, B, ...)          bitwise and
179%   C = bitcmp (A, ...)             bitwise negation
180%   C = bitget (A, B, ...)          get bits
181%   C = bitset (A, B, ...)          set bits
182%   C = bitshift (A, B, ...)        shift bits
183%   C = bitor (A, B, ...)           bitwise or
184%   C = bitxor (A, B, ...)          bitwise xor
185%
186%   C = cast (G, ...)       cast GrB matrix to MATLAB matrix
187%   C = cat (dim, ...)      contatenate matrices
188%   C = ceil (G)            round towards infinity
189%   C = cell2mat (A)        concatenate a cell array of matrices
190%   p = colamd (G)          column approximate minimum degree ordering
191%   C = complex (G)         cast GrB matrix to MATLAB sparse complex
192%   C = conj (G)            complex conjugate
193%   C = cos (G)             cosine
194%   C = cosh (G)            hyperbolic cosine
195%   C = cot (G)             cotangent
196%   C = coth (G)            hyperbolic cotangent
197%   C = csc (G)             cosecant
198%   C = csch (G)            hyperbolic cosecant
199%
200%   C = diag (A, k)         diagonal matrices and diagonals
201%   DiGraph = digraph (G,...)   directed Graph
202%   disp (A, level)         display a MATLAB or GrB matrix A
203%   display (G)             display a GrB matrix G; same as disp(G,2)
204%   [...] = dmperm (G)      Dulmage-Mendelsohn permutation
205%   C = double (G)          cast GrB matrix to MATLAB sparse double
206%
207%   [V, ...] = eig (G,...)  eigenvalues and eigenvectors
208%   G = GrB.empty (m, n)    empty matrix for the GrB class
209%   C = eps (G)             floating-point spacing
210%   C = erf (G)             error function
211%   C = erfc (G)            complementary error function
212%   p = etree (G)           elimination tree
213%   C = exp (G)             natural exponent
214%   C = expm1 (G)           exp (x) - 1
215%
216%   C = false (...)         all-false logical matrix
217%   [I,J,X] = find (G, ...) extract entries from a matrix
218%   C = fix (G)             round towards zero
219%   C = flip (G, dim)       flip the order of entries
220%   C = floor (G)           round towards -infinity
221%   c = fprintf (...)       print to a file or to the Command Window
222%   C = full (G, ...)       adds explicit zeros or id values
223%
224%   C = gamma (G)           gamma function
225%   C = gammaln (G)         logarithm of gamma function
226%   Graph = graph (G, ...)  undirected graph
227%
228%   C = hypot (A, B)        sqrt of sum of squares
229%
230%   C = imag (G)            imaginary part of a complex matrix
231%   C = int8 (G)            cast GrB matrix to MATLAB full int8
232%   C = int16 (G)           cast GrB matrix to MATLAB full int16
233%   C = int32 (G)           cast GrB matrix to MATLAB full int32
234%   C = int64 (G)           cast GrB matrix to MATLAB full int64
235%   s = isa (G, classname)  check if a GrB matrix is of a specific class
236%   s = isbanded (G,...)    true if G is banded
237%   s = iscolumn (G)        true if n=1, for an m-by-n GrB matrix G
238%   s = isdiag (G)          true if G is diagonal
239%   s = isempty (G)         true if any dimension of G is zero
240%   s = isequal (A, B)      test if equal
241%   C = isfinite (G)        test if finite
242%   s = isfloat (G)         true if GrB matrix is double, single, complex
243%   s = ishermitian (G)     true if G is Hermitian
244%   C = isinf (G)           test if infinite
245%   s = isinteger (G)       true if GrB matrix is int8, int16, ..., uint64
246%   s = islogical (G)       true if GrB matrix is logical
247%   s = ismatrix (G)        true for any GrB matrix G
248%   C = isnan (G)           test if NaN
249%   s = isnumeric (G)       true for any GrB matrix G (even logical)
250%   s = isreal (G)          true if GrB matrix is not complex
251%   s = isrow (G)           true if m=1, for an m-by-n GrB matrix G
252%   s = isscalar (G)        true if G is a 1-by-1 GrB matrix
253%   s = issparse (G)        true for any GrB matrix G
254%   s = issymmetric (G)     true if G is symmetric
255%   s = istril (G)          true if G is lower triangular
256%   s = istriu (G)          true if G is upper triangular
257%   s = isvector (G)        true if m=1 or n=1, for an m-by-n GrB matrix G
258%
259%   C = kron (A, B)         Kronecker product
260%
261%   n = length (G)          length of a GrB vector
262%   C = log (G)             natural logarithm
263%   C = log10 (G)           base-10 logarithm
264%   C = log1p (G)           log (1+x)
265%   [F, E] = log2 (G)       base-2 logarithm
266%   C = logical (G)         cast GrB matrix to MATLAB sparse logical
267%
268%   C = mat2cell (A,m,n)    break a matrix into a cell array of matrices
269%   C = max (A,B,option)    reduce via max, to vector or scalar
270%   C = min (A,B,option)    reduce via min, to vector or scalar
271%
272%   e = nnz (G)             number of entries in a GrB matrix G
273%   X = nonzeros (G)        extract all entries from a GrB matrix
274%   s = norm (G, kind)      norm of a GrB matrix
275%   C = num2cell (A,dim)    convert a matrix into a cell array
276%   e = numel (G)           m*n for an m-by-n GrB matrix G
277%   e = nzmax (G)           number of entries in a GrB matrix G
278%
279%   C = ones (...)          matrix with all ones, same type as G
280%
281%   C = pow2 (F, E)         base-2 power
282%   C = prod (G, option)    reduce via product, to vector or scalar
283%
284%   C = real (G)            real part of a complex matrix
285%   C = repmat (G, ...)     replicate and tile a GraphBLAS matrix
286%   C = reshape (G, ...)    reshape a GraphBLAS matrix
287%   C = round (G)           round towards nearest
288%
289%   C = sec (G)             secant
290%   C = sech (G)            hyperbolic secant
291%   C = sign (G)            signum function
292%   C = sin (G)             sine
293%   C = single (G)          cast GrB matrix to MATLAB full single
294%   C = sinh (G)            hyperbolic sine
295%   [m,n,t] = size (G,dim)  size and type of a GrB matrix
296%   C = sparse (G)          makes a copy of a GrB matrix
297%   C = spfun (fun, G)      evaluate a function on the entries of G
298%   C = spones (G, type)    return pattern of GrB matrix
299%   C = sprand (...)        random GraphBLAS matrix
300%   C = sprandn (...)       random GraphBLAS matrix, normal distribution
301%   C = sprandsym (...)     random symmetric GraphBLAS matrix
302%   c = sprintf (...)       print to a string
303%   C = sqrt (G)            element-wise square root
304%   C = sum (G, option)     reduce via sum, to vector or scalar
305%   p = symamd (G)          approximate minimum degree ordering
306%   p = symrcm (G)          reverse Cuthill-McKee ordering
307%
308%   C = tan (G)             tangent
309%   C = tanh (G)            hyperbolic tangent
310%   L = tril (G, k)         lower triangular part of GrB matrix G
311%   U = triu (G, k)         upper triangular part of GrB matrix G
312%   C = true (...)          all-true logical matrix
313%
314%   C = uint8 (G)           cast GrB matrix to MATLAB full uint8
315%   C = uint16 (G)          cast GrB matrix to MATLAB full uint16
316%   C = uint32 (G)          cast GrB matrix to MATLAB full uint32
317%   C = uint64 (G)          cast GrB matrix to MATLAB full uint64
318%
319%   C = xor (A, B)          exclusive or
320%
321%   C = zeros (...)         all-zero matrix, same type as G
322%
323%-------------------------------------------------------------------------
324% Static Methods:
325%-------------------------------------------------------------------------
326%
327%   The Static Methods for the GrB class can be used on input matrices of
328%   any kind: GraphBLAS sparse matrices, MATLAB sparse matrices, or MATLAB
329%   full matrices, in any combination.  The output matrix C is a GraphBLAS
330%   matrix, by default, but can be optionally returned as a MATLAB sparse
331%   or full matrix.  The static methods divide into three categories:
332%   those that perform basic functions, graph algorithms, and the 12
333%   foundational GraphBLAS operations.
334%
335%---------------------------
336% GraphBLAS basic functions:
337%---------------------------
338%
339%   context:
340%   GrB.clear                    clear GraphBLAS workspace and settings
341%   GrB.finalize                 finish GraphBLAS
342%   GrB.init                     initialize GraphBLAS
343%   t = GrB.threads (t)          set/get # of threads to use in GraphBLAS
344%   c = GrB.chunk (c)            set/get chunk size to use in GraphBLAS
345%   b = GrB.burble (b)           set/get burble (diagnostic output)
346%
347%   info:
348%   GrB.binopinfo (op, type)     list properties of a binary operator
349%   GrB.descriptorinfo (d)       list properties of a descriptor
350%   GrB.monoidinfo (op, type)    list properties of a monoid
351%   GrB.selectopinfo (op)        list properties of a select operator
352%   GrB.semiringinfo (s, type)   list properties of a semiring
353%   GrB.unopinfo (op, type)      list properties of a unary operator
354%
355%   operations:
356%   C = GrB.build (I,J,X,m,n,dup,type,desc) build a GrB matrix from
357%                                list of entries (like C=sparse(I,J,X...))
358%   [C,I,J] = GrB.compact (A,id) remove empty rows and columns
359%   c = GrB.entries (A,...)      count or query entries in a matrix
360%   C = GrB.expand (scalar, A)   expand a scalar (C = scalar*spones(A))
361%   [I,J,X] = GrB.extracttuples (A,desc) extract all entries (like 'find')
362%   C = GrB.eye (m,n,type)       identity matrix of any type (like 'speye')
363%   f = GrB.format (f)           set/get matrix format by row or col
364%   s = GrB.isbyrow (A)          true if format f A is 'by row'
365%   s = GrB.isbycol (A)          true if format f A is 'by col'
366%   s = GrB.isfull (A)           true if all entries present
367%   s = GrB.issigned (type)      true if type is signed
368%   c = GrB.nonz (A,...)         count or query nonzeros in a matrix
369%   s = GrB.normdiff (A,B,kind)  norm (A-B,kind)
370%   C = GrB.offdiag (A)          prune diagonal entries
371%   C = GrB.prune (A, id)        prune entries equal to id
372%   C = GrB.random (...)         random GraphBLAS matrix (like 'sprand')
373%   C = GrB.speye (m,n,type)     identity matrix of any type (like 'speye')
374%   t = GrB.type (A)             get the type of a MATLAB or GrB matrix A
375%   v = GrB.version              string with SuiteSparse:GraphBLAS version
376%   v = GrB.ver                  struct with SuiteSparse:GraphBLAS version
377%
378%   load/save:
379%   C = GrB.load (filename)      load a single matrix from a file
380%   GrB.save (A, filename)       save a single matrix to a file
381%
382%-------------------------------------
383% Static Methods for graph algorithms:
384%-------------------------------------
385%
386%   [v, parent] = GrB.bfs (A, s, ...) ;     breadth-first search
387%   Y = GrB.dnn (W, bias, Y0) ;             deep neural network
388%   C = GrB.incidence (A, ...) ;            incidence matrix
389%   C = GrB.ktruss (A, k, check) ;          k-truss
390%   L = GrB.laplacian (A, type, check) ;    Laplacian graph
391%   iset = GrB.mis (A, check) ;             maximal independent set
392%   r = GrB.pagerank (A, opts) ;            PageRank of a matrix
393%   s = GrB.tricount (A, check) ;           triangle count
394%
395%-----------------------------------
396% Foundational GraphBLAS operations:
397%-----------------------------------
398%
399%   GraphBLAS has 12 foundational operations, listed below.  All have
400%   similar parameters.  The full set of input parameters is listed in
401%   the order in which they appear in the GraphBLAS C API, except that
402%   for the MATLAB interface, Cin and C are different matrices.  They
403%   combine into a single input/output matrix in the GraphBLAS C API.  In
404%   the MATLAB interface, many of the parameters become optional, and
405%   they can appear in different order.
406%
407%   GrB.apply       apply a unary operator
408%   GrB.apply2      apply a binary operator
409%   GrB.assign      sparse matrix assignment, such as C(I,J)=A
410%   GrB.eadd        element-wise addition
411%   GrB.emult       element-wise multiplication
412%   GrB.extract     extract submatrix, like C=A(I,J) in MATLAB
413%   GrB.kronecker   Kronecker product
414%   GrB.mxm         sparse matrix-matrix multiplication over a semiring
415%   GrB.reduce      reduce a matrix to a scalar
416%   GrB.select      select a subset of entries from a matrix
417%   GrB.subassign   sparse matrix assignment, such as C(I,J)=A
418%   GrB.trans       transpose a matrix
419%   GrB.vreduce     reduce a matrix to a vector
420%
421%   In GraphBLAS notation (with C, Cin arguments for the one matrix
422%   C), these take the following form:
423%
424%       C<#M,replace> = accum (C, operation (A or A', B or B'))
425%
426%   C is both an input and output matrix.  In this MATLAB interface to
427%   GraphBLAS, it is split into Cin (the value of C on input) and C
428%   (the value of C on output).  M is the optional mask matrix, and #M is
429%   either M or ~M depending on whether or not the mask is complemented
430%   via the desc.mask option.  The replace option is determined by
431%   desc.out; if present, C is cleared after it is used in the accum
432%   operation but before the final assignment.  A and/or B may optionally
433%   be transposed via the descriptor fields desc.in0 and desc.in1,
434%   respectively.  To select the format of C, use desc.format.  See
435%   GrB.descriptorinfo for more details.
436%
437%   accum is optional; if not is not present, then the operation becomes
438%   C<...> = operation(A,B).  Otherwise, C = C + operation(A,B) is
439%   computed where '+' is the accum operator.  It acts like a sparse
440%   matrix addition (see GrB.eadd), in terms of the structure of the
441%   result C, but any binary operator can be used.
442%
443%   The mask M acts like MATLAB logical indexing.  If M(i,j)=1 then
444%   C(i,j) can be modified; if zero, it cannot be modified by the
445%   operation.
446%
447%   The full list of parameters is shown below:
448%
449%       C = GrB.apply     (Cin, M, accum, op, A,          desc)
450%       C = GrB.apply2    (Cin, M, accum, op, A, B,       desc)
451%       C = GrB.assign    (Cin, M, accum,     A,    I, J, desc)
452%       C = GrB.eadd      (Cin, M, accum, op, A, B,       desc)
453%       C = GrB.emult     (Cin, M, accum, op, A, B,       desc)
454%       C = GrB.extract   (Cin, M, accum,     A,    I, J, desc)
455%       C = GrB.kronecker (Cin, M, accum, op, A, B,       desc)
456%       C = GrB.mxm       (Cin, M, accum, op, A, B,       desc)
457%       C = GrB.reduce    (Cin,    accum, op, A,          desc)
458%       C = GrB.select    (Cin, M, accum, op, A, b,       desc)
459%       C = GrB.subassign (Cin, M, accum,     A,    I, J, desc)
460%       C = GrB.trans     (Cin, M, accum,     A,          desc)
461%       C = GrB.vreduce   (Cin, M, accum, op, A,          desc)
462%
463%   The parameters divide into 4 classes: matrices, strings, cells, and a
464%   single optional struct (the descriptor).  The order of parameters
465%   between the matrices, strings, and cell classes is arbitrary.  The
466%   order of parameters within a class is important; for example, if a
467%   method takes 4 matrix inputs, then they must appear in the order Cin,
468%   M, A, and then B.  However, if a single string appears as a
469%   parameter, it can appear anywhere within the list of 4 matrices.
470%
471%   (1) Cin, M, A, B are matrices.  If the method takes up to 4 matrices
472%       (mxm, kronecker, select (with operator requiring a b
473%       parameter), eadd, emult, apply2), then they appear in this order:
474%       with 2 matrix inputs: A, B
475%       with 3 matrix inputs: Cin, A, B
476%       with 4 matrix inputs: Cin, M, A, B
477%       For GrB.select, b is a scalar.  For GrB.apply2, either A or B
478%       is be a scalar.
479%
480%       If the method takes up to 3 matrices (vreduce, apply, assign,
481%       subassign, extract, trans, or select without b):
482%       with 1 matrix input:  A
483%       with 2 matrix inputs: Cin, A
484%       with 3 matrix inputs: Cin, M, A
485%       Note that assign and subassign require Cin.
486%
487%       If the method takes up to 2 input matrices (the reduce method):
488%       with 1 matrix input:  A
489%       with 2 matrix inputs: Cin, A
490%
491%   (2) accum and op are strings.  The accum string is always optional.
492%       If the method has an op parameter, then it is a required input.
493%
494%       If the method has both parameters, and just one string appears,
495%       it is the op, which is a semiring for mxm, a unary operator for
496%       apply, a select operator for the select method, and a binary
497%       operator for all other methods.  If 2 strings appear, the first
498%       one is the accum the second is the op.  If the accum appears then
499%       Cin must also appear as a matrix input.
500%
501%       If the method has no op (assign, subassign, extract, trans), but
502%       just an accum parameter, then 0 or 1 strings may appear in the
503%       parameter list.  If a string appears, it is the accum.
504%
505%   (3) I and J are cell arrays.  For details, see the assign, subassign,
506%       and extract methods; a short summary appears below.  Both are
507%       optional:
508%       with no cell inputs: default for I and J
509%       with 1  cell inputs: I, default for J
510%       with 2  cell inputs: I, J
511%
512%       Each cell array may appear with 0, 1, 2, or 3 items:
513%           0: { }                  ":" in MATLAB notation
514%           1: { list }             a list of integer indices
515%           2: { start,fini }       start:fini in MATLAB notation
516%           3: { start,inc,fini }   start:inc:fini in MATLAB notation
517%
518%   (4) The descriptor is an optional struct.  If present, it must
519%       appear last, after all other parameters.
520%
521%   Some valid uses are shown below, along with their equivalent in
522%   GraphBLAS notation.  For the first three mxm examples, the four
523%   matrices C, M, A, and B must appear in that order, and the two
524%   strings '+' and '+.*' must appear in that order, but the matrices and
525%   strings may be interleaved arbitrarily.
526%
527%       C = GrB.apply (C, M, '|', '~', A)           C<M> |= ~A
528%       C = GrB.apply ('~', A)                      C = ~A
529%
530%       C = GrB.assign (C, M, '+', A, I, J)         C(I,J)<M> += A
531%       C = GrB.assign (C, I, J, M, '+', A)         C(I,J)<M> += A
532%
533%       C = GrB.assign (C, A, I, J)                 C(I,J) = A
534%       C = GrB.assign (C, I, J, A)                 C(I,J) = A
535%       C = GrB.assign (C, A)                       C = A
536%       C = GrB.assign (C, M, A)                    C<M> = A
537%       C = GrB.assign (C, M, '+', A)               C<M> += A
538%       C = GrB.assign (C, '+', A, I)               C (I,:) += A
539%
540%       C = GrB.emult (C, M, '+', A, '*', B)        C<M> += A.*B
541%       C = GrB.emult (A, '*', B)                   C = A.*B
542%
543%       C = GrB.extract (C, M, '+', A, I, J)        C<M> += A(I,J)
544%       C = GrB.extract (A, I, J)                   C = A(I,J)
545%       C = GrB.extract (I, J, A)                   C = A(I,J)
546%       C = GrB.extract (A)                         C = A
547%       C = GrB.extract (C, M, A)                   C<M> = A
548%       C = GrB.extract (C, M, '+', A)              C<M> += A
549%       C = GrB.extract (C, '+', A, I)              C += A(I,:)
550%
551%       C = GrB.mxm (C, M, '+', '+.*', A, B)        C<M> += A*B
552%       C = GrB.mxm (C, M, '+', A, '+.*', B)        C<M> += A*B
553%       C = GrB.mxm ('+', '+,*', C, M, A, B)        C<M> += A*B
554%
555%       C = GrB.mxm ('+.*', A, B)                   C = A*B
556%       C = GrB.mxm (A, '+.*', B)                   C = A*B
557%       C = GrB.mxm (C, M, A, '+.*', B)             C<M> = A*B
558%
559%       c = GrB.reduce (c, '+', 'max', A)           c += max (A)
560%       c = GrB.reduce ('max', A)                   c = max (A)
561%       c = GrB.reduce (A, 'max')                   c = max (A)
562%       c = GrB.reduce (c, 'max', A)                c = max (A)
563%
564% See also sparse.
565%
566% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
567% SPDX-License-Identifier: GPL-3.0-or-later
568
569properties (SetAccess = private, GetAccess = private)
570    % The struct contains the entire opaque content of a GraphBLAS
571    % GrB_Matrix.
572    opaque = [ ] ;
573end
574
575methods
576
577    %---------------------------------------------------------------------
578    % GrB: GraphBLAS matrix constructor
579    %---------------------------------------------------------------------
580
581    function C = GrB (arg1, arg2, arg3, arg4)
582    %GRB GraphBLAS constructor: create a GraphBLAS sparse matrix.
583    %
584    % C = GrB (A) ;          GrB copy of a matrix A, same type and format
585    %
586    % C = GrB (A, type) ;    GrB typecasted copy of a matrix A, same format
587    % C = GrB (A, format) ;  GrB copy of a matrix A, with given format
588    % C = GrB (m, n) ;       empty m-by-n GrB double matrix, default format
589    %
590    % C = GrB (A, type, format) ;   GrB copy of A, new type and format
591    % C = GrB (A, format, type) ;   ditto
592    %
593    % C = GrB (m,n, type) ;   empty m-by-n GrB type matrix, default format
594    % C = GrB (m,n, format) ; empty m-by-n GrB double matrix, given format
595    %
596    % C = GrB (m,n,type,format) ;  empty m-by-n matrix, given type & format
597    % C = GrB (m,n,format,type) ;  ditto
598    %
599    % See also sparse.
600        if (nargin == 1)
601            if (isstruct (arg1))
602                % C = GrB (A), where the input A is a GraphBLAS struct as
603                % returned by another GrB* function, but this usage is not
604                % meant for the end-user.  It is only used internally in
605                % @GrB, to convert a GraphBLAS struct computed by a
606                % GraphBLAS mexFunction into a GrB matrix object.
607                C.opaque = arg1 ;
608            elseif (isobject (arg1))
609                % arg1 is already a GrB matrix; make a deep copy
610                C.opaque = gbnew (arg1.opaque) ;
611            else
612                % arg1 is a MATLAB matrix; convert to a GrB matrix
613                C.opaque = gbnew (arg1) ;
614            end
615        else
616            if (isobject (arg1))
617                % extract the contents of the GrB object as its opaque
618                % struct so the gbnew mexFunction can access it.
619                arg1 = arg1.opaque ;
620            end
621            % varargin is more elegant, but it is slower than the switch
622            switch (nargin)
623                case 2
624                    C.opaque = gbnew (arg1, arg2) ;
625                case 3
626                    C.opaque = gbnew (arg1, arg2, arg3) ;
627                case 4
628                    C.opaque = gbnew (arg1, arg2, arg3, arg4) ;
629            end
630        end
631    end
632
633    %---------------------------------------------------------------------
634    % implicitly-defined methods
635    %---------------------------------------------------------------------
636
637    % The following methods work without any implemention needed here,
638    % because they are built-in MATLAB m-files that can operate with GrB
639    % inputs:
640    %
641    %   matrix operations: flipdim fliplr flipud cast isrow iscolumn ndims
642    %   sprank etreeplot spy gplot reallog realpow realsqrt
643    %
644    %   iterative solvers: bicgstabl bicgstab cgs minres gmres bicg pcg
645    %   qmr rjr tfqmr lsqr
646
647    %---------------------------------------------------------------------
648    % FUTURE:: many these could also be overloaded:
649    %---------------------------------------------------------------------
650
651    % methods in the MATLAB/ops folder:
652    %
653    %   colon idivide ismembertol uniquetol
654    %   m-files: intersect ismember setdiff setxorunion unique
655    %       (if 'sort' is overloaded, and 1D indexing added,
656    %       then all these will work for GrB matrices)
657
658    % methods in the MATLAB/datatypes folder:
659    %
660    %   typecast swapbytes
661
662    % methods in the MATLAB/datafun folder:
663    %
664    %   cummax cummin cumprod cumsum diff histcounts islocalmax
665    %   ismissing issorted maxk mink movmad movmax movmean movmedian
666    %   movmin movprod movstd movsum movvar rmmissing rmoutliers
667    %   sort sortrows standardizeMissing topkrows
668    %
669    %   m-files: bounds corrcoef cov del2 fillmissing filloutliers
670    %   gradient isoutlier issortedrows mean median mode normalize
671    %   rescale smoothdata std var
672
673    % methods the 'double' class that are not yet implemented here:
674    %
675    %   Possible 'double' functions to overload in the future (note that
676    %   mod and rem are not the same as the ANSI fmod or remainder, but
677    %   the MATLAB rem is almost the same as the ANSI fmod):
678    %
679    %       mod rem unwrap sind asind cosd acosd tand
680    %       atand secd asecd cscd acscd cotd acotd atan2d
681    %
682    %   not needed:
683    %
684    %       special functions: airy bernoulli besselh besseli besselj
685    %       besselk bessely betainc betaincinv chebyshevT chebyshevU
686    %       coshint cosint dawson dilog dirac ei ellipticCE ellipticCK
687    %       ellipticCPi ellipticE ellipticF ellipticK ellipticNome
688    %       ellipticPi erfcinv erfcx erfi erfinv fresnelc fresnels
689    %       gammainc gammaincinv harmonic igamma jacobiP kummerU laguerreL
690    %       legendreP logint pochhammer psi signIm sinhint sinint ssinint
691    %       whittakerM whittakerW wrightOmega zeta triangularPulse
692    %       rectangularPulse
693    %
694    %       eigenvalue-related: charpoly euler gegenbauerC hermiteH jordan
695    %       minpoly poly2sym polylog
696    %
697    %       others: colon factor divisors superiorfloat
698
699    % methods in MATLAB/matfun not implemented here:
700    %
701    %       balance cdf2rdf chol cholupdate condeig condest cond
702    %       decomposition det expm funm gsvd hess inv ldl linsolve logm
703    %       lscov lsqminnorm ltitr lu normest1 normest null ordeig ordqz
704    %       ordschur orth pinv planerot polyeig qrdelete qrinsert qr
705    %       qrupdate qz rank rcond rref rsf2csf schur sqrtm svd sylvester
706    %       trace vecnorm
707
708    % methods in MATLAB/sparfun not implemented here:
709    %
710    %       colperm delsq dissect eigs ichol ilu spalloc spaugment
711    %       spconvert spdiags svds symbfact symmlq unmesh
712    %
713    %       not needed: treeplot treelayout numgrid nested spparms
714
715    % methods in MATLAB/elmat not implemented here:
716    %
717    %       accumarray blkdiag bsxfun circshift compan gallery
718    %       hadamard hankel hilb inf invhilb ipermute isequaln nan ndgrid
719    %       pascal permute repelem rot90 shiftdim toeplitz vander
720    %       wilkinson
721    %
722    %       not needed: linspace logspace ind2sub sub2ind meshgrid pi
723    %       freqspace flintmax intmax intmin squeeze realmin realmax i j
724    %       magic rosser
725
726    % methods for classes graph and digraph not yet implemented:
727    %
728    %       addedge addnode bfsearch centrality conncomp dfsearch
729    %       distances findedge findnode isisomorphic isomorphism maxflow
730    %       nearest outedges rmedge rmnode shortestpath shortestpathtree
731    %       simplify
732
733    % methods for class graph (not in digraph class) not yet implemented:
734    %
735    %       bctree biconncomp minspantree neighbors
736
737    % methods for class digraph (not in graph class) not yet implemented:
738    %
739    %       condensation inedges isdag predecessors successors toposort
740    %       transclosure transreduction
741
742    % methods in LAGraph: (see the LAGraph/Source folder)
743
744    %---------------------------------------------------------------------
745    % MATLAB operator overloading
746    %---------------------------------------------------------------------
747
748    C = and (A, B) ;            % C = (A & B)
749    C = ctranspose (A) ;        % C = A'
750    i = end (A, k, ndims) ;     % for A (1:end,1:end)
751    C = eq (A, B) ;             % C = (A == B)
752    C = ge (A, B) ;             % C = (A >= B)
753    C = gt (A, B) ;             % C = (A > B)
754    C = horzcat (varargin) ;    % C = [A , B]
755    C = ldivide (A, B) ;        % C = A .\ B
756    C = le (A, B) ;             % C = (A <= B)
757    C = lt (A, B) ;             % C = (A < B)
758    C = minus (A, B) ;          % C = A - B
759    C = mldivide (A, B) ;       % C = A \ B
760    C = mpower (A, B) ;         % C = A^B
761    C = mrdivide (A, B) ;       % C = A / B
762    C = mtimes (A, B) ;         % C = A * B
763    C = ne (A, B) ;             % C = (A ~= B)
764    C = not (G) ;               % C = ~A
765    C = or (A, B) ;             % C = (A | B)
766    C = plus (A, B) ;           % C = A + B
767    C = power (A, B) ;          % C = A .^ B
768    C = rdivide (A, B) ;        % C = A ./ B
769    I = subsindex (A) ;         % for C = X (A), using A as index I
770    C = subsasgn (C, S, A) ;    % C (I,J) = A or C (M) = A
771    C = subsref (A, S) ;        % C = A (I,J) or C = A (M)
772    C = times (A, B) ;          % C = A .* B
773    C = transpose (G) ;         % C = A.'
774    C = uminus (G) ;            % C = -A
775    C = uplus (G) ;             % C = +A
776    C = vertcat (varargin) ;    % C = [A ; B]
777
778    %---------------------------------------------------------------------
779    % Methods that overload built-in MATLAB functions:
780    %---------------------------------------------------------------------
781
782    %   In the list below, G is always a GraphBLAS matrix.  The inputs A
783    %   and B can be a mix of GraphBLAS and/or MATLAB matrices, but at
784    %   least one will be a GraphBLAS matrix because these are all
785    %   methods that are overloaded from the MATLAB versions.  If all
786    %   inputs are MATLAB matrices, these methods are not used.  The
787    %   output matrix (C, L, or U) is always a GraphBLAS matrix.  Lower
788    %   case variables i, e, s, and n are scalars.  Outputs p, parent, I,
789    %   J, and X are MATLAB vectors.  Graph is a MATLAB undirected graph.
790    %   DiGraph is a MATLAB directed digraph.
791
792    C = abs (G) ;
793    C = acos (G) ;
794    C = acosh (G) ;
795    C = acot (G) ;
796    C = acoth (G) ;
797    C = acsc (G) ;
798    C = acsch (G) ;
799    C = all (G, option) ;
800    p = amd (G, varargin) ;
801    C = angle (G) ;
802    C = any (G, option) ;
803    C = asec (G) ;
804    C = asech (G) ;
805    C = asin (G) ;
806    C = asinh (G) ;
807    assert (G) ;            % test assertion
808    C = atan (G) ;
809    C = atanh (G) ;
810    C = atan2 (A, B) ;
811
812    [lo, hi] = bandwidth (G, uplo) ;
813    C = bitand (A, B, assumedtype) ;
814    C = bitcmp (A, assumedtype) ;
815    C = bitget (A, B, assumedtype) ;
816    C = bitset (A, B, arg3, arg4) ;
817    C = bitshift (A, B, arg3) ;
818    C = bitor (A, B, assumedtype) ;
819    C = bitxor (A, B, assumedtype) ;
820
821%   C = cast (G, ...)       built-in works as-is
822    C = cat (dim, varargin) ;
823    C = ceil (G) ;
824    [p, varargout] = colamd (G, varargin) ;
825    C = complex (A, B) ;
826    C = conj (G) ;
827    C = cos (G) ;
828    C = cosh (G) ;
829    C = cot (G) ;
830    C = coth (G) ;
831    C = csc (G) ;
832    C = csch (G) ;
833
834    C = diag (A, k) ;
835    DiGraph = digraph (G, option) ;
836    disp (A, level) ;
837    display (G) ;
838    [p, varargout] = dmperm (G) ;
839    C = double (G) ;
840
841    [V, varargout] = eig (G, varargin) ;        % uses GrB matrices
842    C = eps (G) ;
843    C = erf (G) ;
844    C = erfc (G) ;
845    [parent, varargout] = etree (G, varargin) ;
846    C = exp (G) ;
847    C = expm1 (G) ;
848
849    C = false (varargin) ;
850    [I,J,X] = find (G, k, search) ;
851    C = fix (G) ;
852    C = flip (G, dim) ;
853    C = floor (G) ;
854    c = fprintf (varargin) ;
855    C = full (A, type, identity) ;
856
857    C = gamma (G) ;
858    C = gammaln (G) ;
859    Graph = graph (G, varargin) ;               % uses GrB matrices
860
861    C = hypot (A, B) ;
862
863    C = imag (G) ;
864    C = int8 (G) ;
865    C = int16 (G) ;
866    C = int32 (G) ;
867    C = int64 (G) ;
868    s = isa (G, type) ;
869    s = isbanded (G, lo, hi) ;
870%   s = iscolumn (G)        built-in works as-is
871    s = isdiag (G) ;
872    s = isempty (G) ;
873    s = isequal (A, B) ;
874    C = isfinite (G) ;
875    s = isfloat (G) ;
876    s = ishermitian (G, option) ;
877    C = isinf (G) ;
878    s = isinteger (G) ;
879    s = islogical (G) ;
880    s = ismatrix (G) ;
881    C = isnan (G) ;
882    s = isnumeric (G) ;
883    s = isreal (G) ;
884%   s = isrow (G)           built-in works as-is
885    s = isscalar (G) ;
886    s = issparse (G) ;
887    s = issymmetric (G, option) ;
888    s = istril (G) ;
889    s = istriu (G) ;
890    s = isvector (G) ;
891
892    C = kron (A, B) ;
893
894    n = length (G) ;
895    C = log (G) ;
896    C = log10 (G) ;
897    C = log1p (G) ;
898    [F, E] = log2 (G) ;
899    C = logical (G) ;
900
901    C = mat2cell (A, m, n) ;
902    C = max (A, B, option) ;
903    C = min (A, B, option) ;
904
905    e = nnz (G) ;
906    X = nonzeros (G) ;
907    s = norm (G, kind) ;
908    C = num2cell (A, dim) ;
909    s = numel (G) ;
910    e = nzmax (G) ;
911
912    C = ones (varargin) ;
913
914    C = pow2 (A, B) ;
915    C = prod (G, option) ;
916
917    C = real (G) ;
918    C = repmat (G, m, n) ;
919    C = reshape (G, arg1, arg2) ;
920    C = round (G) ;
921
922    C = sec (G) ;
923    C = sech (G) ;
924    C = sign (G) ;
925    C = sin (G) ;
926    C = single (G) ;
927    C = sinh (G) ;
928    [m, n, t] = size (G, dim) ;
929    C = sparse (G) ;
930    C = spfun (fun, G) ;
931    C = spones (G, type) ;
932    C = sprand (arg1, arg2, arg3) ;
933    C = sprandn (arg1, arg2, arg3) ;
934    C = sprandsym (arg1, arg2) ;
935    c = sprintf (varargin) ;
936    C = sqrt (G) ;
937    S = struct (G) ;
938    C = sum (G, option) ;
939    [p, varargout] = symamd (G, varargin) ;
940    p = symrcm (G) ;
941
942    C = tan (G) ;
943    C = tanh (G) ;
944    L = tril (G, k) ;
945    U = triu (G, k) ;
946    C = true (varargin) ;
947
948    C = uint8 (G) ;
949    C = uint16 (G) ;
950    C = uint32 (G) ;
951    C = uint64 (G) ;
952
953    C = xor (A, B) ;
954
955    C = zeros (varargin) ;
956
957end
958
959methods (Static)
960
961    %---------------------------------------------------------------------
962    % Static Methods:
963    %---------------------------------------------------------------------
964
965    % All of these are used as GrB.method (...), with the "GrB." prefix.
966    % The input matrices (A, B, C, M, ...) are of any kind (GraphBLAS,
967    % MATLAB sparse, or MATLAB full).  The output matrix C is a GraphBLAS
968    % matrix.
969
970    % Some of the methods listed below are high-level graph algorithms that
971    % rely on GrB objects internally (bfs, dnn, ktruss, mis, pagerank, and
972    % tricount), for simplicity and readability.  All of the other methods
973    % extract the opaque content of the GrB objects just once, operate on
974    % them, and then cast their results back into a MATLAB GrB object just
975    % once.  This makes for less-readable MATLAB code, but it avoids the
976    % performance cost of accessing/modifying a MATLAB object.
977
978    MATLAB_vs_GrB ;
979    C = apply (Cin, M, accum, op, A, desc) ;
980    C = apply2 (Cin, M, accum, op, A, B, desc) ;
981    C = assign (Cin, M, accum, A, I, J, desc) ;
982    [v, parent] = bfs (A, s, varargin) ;        % uses GrB matrices
983    binopinfo (op, type) ;
984    C = build (I, J, X, m, n, dup, type, desc) ;
985    b = burble (b) ;
986    C = cell2mat (A) ;
987    c = chunk (c) ;
988    clear ;
989    [C, I, J] = compact (A, id) ;
990    descriptorinfo (d) ;
991    Y = dnn (W, bias, Y0) ;                     % uses GrB matrices
992    C = eadd (Cin, M, accum, op, A, B, desc) ;
993    C = empty (arg1, arg2) ;
994    C = emult (Cin, M, accum, op, A, B, desc) ;
995    x = entries (A, arg2, arg3) ;
996    C = expand (scalar, A, type) ;
997    C = extract (Cin, M, accum, A, I, J, desc) ;
998    [I, J, X] = extracttuples (A, desc) ;
999    C = eye (m, n, type) ;
1000    finalize ;
1001    [f, s] = format (arg) ;
1002    C = incidence (A, varargin) ;
1003    init ;
1004    s = isbyrow (A) ;
1005    s = isbycol (A) ;
1006    s = isfull (A) ;
1007    s = issigned (arg) ;
1008    C = kronecker (Cin, M, accum, op, A, B, desc) ;
1009    C = ktruss (A, k, check) ;                  % uses GrB matrices
1010    L = laplacian (A, type, check) ;
1011    C = load (filename) ;
1012    iset = mis (A, check) ;                     % uses GrB matrices
1013    monoidinfo (monoid, type) ;
1014    C = mxm (Cin, M, accum, semiring, A, B, desc) ;
1015    result = nonz (A, varargin) ;
1016    s = normdiff (A, B, kind) ;
1017    C = offdiag (A) ;
1018    ctype = optype (a, b) ;
1019    [r, stats] = pagerank (A, opts) ;           % uses GrB matrices
1020    C = prune (A, identity) ;
1021    C = random (varargin) ;
1022    C = reduce (cin, accum, monoid, A, desc) ;
1023    filename_used = save (C, filename) ;
1024    C = select (Cin, M, accum, selectop, A, b, desc) ;
1025    selectopinfo (op) ;
1026    semiringinfo (s, type) ;
1027    C = speye (m, n, type) ;
1028    C = subassign (Cin, M, accum, A, I, J, desc) ;
1029    nthreads = threads (nthreads) ;
1030    C = trans (Cin, M, accum, A, desc) ;
1031    s = tricount (A, check, d) ;                % uses GrB matrices
1032    s = type (A) ;
1033    unopinfo (op, type) ;
1034    v = version ;
1035    v = ver ;
1036    C = vreduce (Cin, M, accum, monoid, A, desc) ;
1037
1038end
1039end
1040
1041