1function Graph = graph (G, varargin)
2%GRAPH convert a GraphBLAS matrix into a MATLAB undirected Graph.
3% Graph = graph (G) converts a GraphBLAS matrix G into an undirected MATLAB
4% Graph.  G is assumed to be symmetric; only tril (G) is used by default.
5% G must be square.  If G is logical, then no weights are added to the
6% Graph.  If G is single or double, these become the weights of the MATLAB
7% Graph.  If G is integer, the Graph is constructed with weights of type
8% double.
9%
10% Graph = graph (G, ..., 'upper') uses triu (G) to construct the Graph.
11% Graph = graph (G, ..., 'lower') uses tril (G) to construct the Graph.
12% The default is 'lower'.
13%
14% Graph = graph (G, ..., 'omitselfloops') ignores the diagonal of G, and
15% the resulting MATLAB Graph has no self-edges.  The default is that
16% self-edges are created from any diagonal entries of G.
17%
18% Example:
19%
20%   G = GrB (bucky) ;
21%   Graph = graph (G)
22%   plot (Graph)
23%
24% See also graph, digraph, GrB/digraph.
25
26% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
27% SPDX-License-Identifier: GPL-3.0-or-later
28
29G = G.opaque ;
30
31[m, n, type] = gbsize (G) ;
32if (m ~= n)
33    error ('G must be square') ;
34end
35
36% get the string options
37side = 'lower' ;
38omitself = false ;
39for k = 1:nargin-1
40    arg = lower (varargin {k}) ;
41    switch arg
42        case { 'upper', 'lower' }
43            side = arg ;
44        case { 'omitselfloops' }
45            omitself = true ;
46        otherwise
47            error ('unknown option') ;
48    end
49end
50
51% apply the options
52if (omitself)
53    % ignore diagonal entries of G
54    if (isequal (side, 'upper'))
55        G = gbselect ('triu', G, 1) ;
56    elseif (isequal (side, 'lower'))
57        G = gbselect ('tril', G, -1) ;
58    end
59else
60    % include diagonal entries of G
61    if (isequal (side, 'upper'))
62        G = gbselect ('triu', G, 0) ;
63    elseif (isequal (side, 'lower'))
64        G = gbselect ('tril', G, 0) ;
65    end
66end
67
68% construct the graph
69switch (type)
70
71    case { 'single' }
72
73        % The MATLAB graph(...) function can accept x as single, but not
74        % from a MATLAB sparse matrix.  So extract the tuples of G first.
75        [i, j, x] = gbextracttuples (G) ;
76        Graph = graph (i, j, x, n) ;
77
78    case { 'logical' }
79
80        % The MATLAB digraph(...) function allows for logical
81        % adjacency matrices (no edge weights are created).
82        Graph = graph (gbmatlab (G, 'logical'), side) ;
83
84    otherwise
85
86        % typecast to double
87        Graph = graph (gbmatlab (G, 'double'), side) ;
88end
89
90