1 //------------------------------------------------------------------------------
2 // gb_get_sparsity: determine the sparsity of a matrix result
3 //------------------------------------------------------------------------------
4 
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: GPL-3.0-or-later
7 
8 //------------------------------------------------------------------------------
9 
10 // gb_get_sparsity determines the sparsity of a result matrix C, which may be
11 // computed from one or two input matrices A and B.  The following rules are
12 // used, in order:
13 
14 // (1) GraphBLAS operations of the form C = GrB.method (Cin, ...) use the
15 //      sparsity of Cin for the new matrix C.
16 
17 // (2) If the sparsity is determined by the descriptor to the method, then that
18 //      determines the sparsity of C.
19 
20 // (3) If both A and B are present and both matrices (not scalars), the
21 //      sparsity of C is A_sparsity | B_sparsity
22 
23 // (4) If A is present (and not a scalar), then the sparsity of C is A_sparsity.
24 
25 // (5) If B is present (and not a scalar), then the sparsity of C is B_sparsity.
26 
27 // (6) Otherwise, the global default sparsity is used for C.
28 
29 #include "gb_matlab.h"
30 
gb_get_sparsity(GrB_Matrix A,GrB_Matrix B,int sparsity_default)31 GxB_Format_Value gb_get_sparsity        // 0 to 15
32 (
33     GrB_Matrix A,                       // may be NULL
34     GrB_Matrix B,                       // may be NULL
35     int sparsity_default                // may be 0
36 )
37 {
38 
39     int sparsity ;
40     int A_sparsity = 0 ;
41     int B_sparsity = 0 ;
42     GrB_Index nrows, ncols ;
43 
44     //--------------------------------------------------------------------------
45     // get the sparsity of the matrices A and B
46     //--------------------------------------------------------------------------
47 
48     if (A != NULL)
49     {
50         OK (GrB_Matrix_nrows (&nrows, A)) ;
51         OK (GrB_Matrix_ncols (&ncols, A)) ;
52         if (nrows > 1 || ncols > 1)
53         {
54             // A is a vector or matrix, not a scalar
55             OK (GxB_Matrix_Option_get (A, GxB_SPARSITY_CONTROL, &A_sparsity)) ;
56         }
57     }
58 
59     if (B != NULL)
60     {
61         OK (GrB_Matrix_nrows (&nrows, B)) ;
62         OK (GrB_Matrix_ncols (&ncols, B)) ;
63         if (nrows > 1 || ncols > 1)
64         {
65             // B is a vector or matrix, not a scalar
66             OK (GxB_Matrix_Option_get (B, GxB_SPARSITY_CONTROL, &B_sparsity)) ;
67         }
68     }
69 
70     //--------------------------------------------------------------------------
71     // determine the sparsity of C
72     //--------------------------------------------------------------------------
73 
74     if (sparsity_default != 0)
75     {
76         // (2) the sparsity is defined by the descriptor to the method
77         sparsity = sparsity_default ;
78     }
79     else if (A_sparsity > 0 && B_sparsity > 0)
80     {
81         // (3) C is determined by the sparsity of A and B
82         sparsity = A_sparsity | B_sparsity ;
83     }
84     else if (A_sparsity > 0)
85     {
86         // (4) get the sparsity of A
87         sparsity = A_sparsity ;
88     }
89     else if (B_sparsity > 0)
90     {
91         // (5) get the sparsity of B
92         sparsity = B_sparsity ;
93     }
94     else
95     {
96         // (6) use the default sparsity
97         sparsity = GxB_AUTO_SPARSITY ;
98     }
99 
100     return (sparsity) ;
101 }
102 
103