1function C = incidence (A, varargin) 2%GRB.INCIDENCE graph incidence matrix. 3% C = GrB.incidence (A) is the graph incidence matrix of the square 4% matrix A. C is GraphBLAS matrix of size n-by-e, if A is n-by-n with e 5% entries (not including diagonal entries). The jth column of C has 2 6% entries: C(s,j) = -1 and C(t,j) = 1, where A(s,t) is an entry A. 7% Diagonal entries in A are ignored. 8% 9% C = GrB.incidence (A, ..., 'directed') constructs a matrix C of size 10% n-by-e where e = GrB.entries (GrB.offdiag (A)). Any entry in the 11% upper or lower trianglar part of A results in a unique column of 12% C. The diagonal is ignored. This is the default. 13% 14% C = GrB.incidence (A, ..., 'unsymmetric') is the same as 'directed'. 15% 16% C = GrB.incidence (A, ..., 'undirected') assumes A is symmetric, and 17% only creates columns of C based on entries in tril (A,-1). The 18% diagonal and upper triangular part of A are ignored. 19% 20% C = GrB.incidence (A, ..., 'symmetric') is the same as 'undirected'. 21% 22% C = GrB.incidence (A, ..., 'lower') is the same as 'undirected'. 23% 24% C = GrB.incidence (A, ..., 'upper') is the same as 'undirected', 25% except that only entries in triu (A,1) are used. 26% 27% C = GrB.incidence (A, ..., type) constructs C with the type 'double', 28% 'single', 'int8', 'int16', 'int32', or 'int64'. The default is 29% 'double'. The type cannot be 'logical' or 'uint*' since C 30% must contain -1's. 31% 32% Examples: 33% 34% A = sprand (5, 5, 0.5) 35% C = GrB.incidence (A) 36% 37% See also graph/incidence, digraph/incidence. 38 39% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved. 40% SPDX-License-Identifier: GPL-3.0-or-later 41 42if (isobject (A)) 43 A = A.opaque ; 44end 45 46[m, n] = gbsize (A) ; 47if (m ~= n) 48 error ('A must be square') ; 49end 50 51% get the string options 52kind = 'directed' ; 53type = 'double' ; 54for k = 1:nargin-1 55 arg = lower (varargin {k}) ; 56 switch arg 57 case { 'directed', 'undirected', 'symmetric', 'unsymmetric', ... 58 'lower', 'upper' } 59 kind = arg ; 60 case { 'double', 'single', 'int8', 'int16', 'int32', 'int64' } 61 type = arg ; 62 case { 'uint8', 'uint16', 'uint32', 'uint64', 'logical' } 63 error ('type must be signed') ; 64 otherwise 65 error ('unknown option') ; 66 end 67end 68 69switch (kind) 70 71 case { 'directed', 'unsymmetric' } 72 73 % create the incidence matrix of a directed graph, using all of A; 74 % except that diagonal entries are ignored. 75 A = gbselect ('offdiag', A, 0) ; 76 77 case { 'upper' } 78 79 % create the incidence matrix of an undirected graph, using only 80 % entries in the strictly upper triangular part of A. 81 A = gbselect ('triu', A, 1) ; 82 83 otherwise % 'undirected', 'symmetric', or 'lower' 84 85 % create the incidence matrix of an undirected graph, using only 86 % entries in the strictly lower triangular part of A. 87 A = gbselect ('tril', A, -1) ; 88 89end 90 91% build the incidence matrix 92desc.base = 'zero-based' ; 93[I, J] = gbextracttuples (A, desc) ; 94e = length (I) ; 95I = [I ; J] ; 96J = (int64 (0) : int64 (e-1))' ; 97J = [J ; J] ; 98X = ones (e, 1, type) ; 99X = [-X ; X] ; 100C = GrB (gbbuild (I, J, X, n, e, desc)) ; 101 102