1 //------------------------------------------------------------------------------
2 // GB_mex_reduce_bool: c = accum(c,reduce_to_scalar(A)) for boolean
3 //------------------------------------------------------------------------------
4 
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7 
8 //------------------------------------------------------------------------------
9 
10 // Reduce a boolean matrix or vector to a boolean.
11 
12 #include "GB_mex.h"
13 
14 #define USAGE "result = GB_mex_reduce_bool (A, op, identity, terminal)"
15 
16 #define FREE_ALL                        \
17 {                                       \
18     GrB_Matrix_free_(&A) ;              \
19     GrB_Monoid_free_(&reduce) ;         \
20     GB_mx_put_global (true) ;           \
21 }
22 
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])23 void mexFunction
24 (
25     int nargout,
26     mxArray *pargout [ ],
27     int nargin,
28     const mxArray *pargin [ ]
29 )
30 {
31 
32     bool malloc_debug = GB_mx_get_global (true) ;
33     GrB_Info info ;
34     GrB_Matrix A = NULL ;
35     GrB_Monoid reduce = NULL ;
36     GrB_BinaryOp reduceop = NULL ;
37 
38     // check inputs
39     if (nargout > 1 || nargin < 3 || nargin > 4)
40     {
41         mexErrMsgTxt ("Usage: " USAGE) ;
42     }
43 
44     #define GET_DEEP_COPY ;
45     #define FREE_DEEP_COPY ;
46 
47     // get A (shallow copy)
48     A = GB_mx_mxArray_to_Matrix (pargin [0], "A input", false, true) ;
49     if (A == NULL)
50     {
51         FREE_ALL ;
52         mexErrMsgTxt ("A failed") ;
53     }
54 
55     if (A->type != GrB_BOOL)
56     {
57         FREE_ALL ;
58         mexErrMsgTxt ("A must be boolean") ;
59     }
60 
61     // get the op (always boolean)
62     if (!GB_mx_mxArray_to_BinaryOp (&reduceop, pargin [1], "reduceop",
63         GrB_BOOL, false) || reduceop == NULL)
64     {
65         FREE_ALL ;
66         mexErrMsgTxt ("reduceop failed") ;
67     }
68 
69     // get the boolean identity value
70     bool GET_SCALAR (2, bool, identity, true) ;
71 
72     // get the boolean terminal value, if any.  default is true
73     bool terminal = true ;
74     bool has_terminal = (nargin == 4) ;
75     if (has_terminal)
76     {
77         GET_SCALAR (3, bool, terminal, true) ;
78     }
79 
80     // create the reduce monoid
81     if (has_terminal)
82     {
83         info = GxB_Monoid_terminal_new_BOOL_(&reduce, reduceop, identity, terminal) ;
84     }
85     else
86     {
87         info = GrB_Monoid_new_BOOL_(&reduce, reduceop, identity) ;
88     }
89 
90     if (info != GrB_SUCCESS)
91     {
92         FREE_ALL ;
93         mexErrMsgTxt ("monoid failed") ;
94     }
95 
96     // reduce to a scalar
97     bool result = false ;
98     info = GrB_Matrix_reduce_BOOL_(&result, NULL, reduce, A, NULL) ;
99 
100     if (info != GrB_SUCCESS)
101     {
102         FREE_ALL ;
103         mexErrMsgTxt ("GrB_reduce failed") ;
104     }
105 
106     // return result to MATLAB as a boolean scalar
107     pargout [0] = GB_mx_create_full (1, 1, GrB_BOOL) ;
108     GB_void *p = mxGetData (pargout [0]) ;
109     memcpy (p, &result, sizeof (bool)) ;
110 
111     FREE_ALL ;
112 }
113 
114