1 //------------------------------------------------------------------------------
2 // GB_mx_BinaryOp_to_Monoid: convert a binary op to a monoid
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 #include "GB_mex.h"
11 
GB_mx_BinaryOp_to_Monoid(const GrB_BinaryOp add)12 GrB_Monoid GB_mx_BinaryOp_to_Monoid // monoid, or NULL if error
13 (
14     const GrB_BinaryOp add          // monoid operator
15 )
16 {
17 
18     if (add == NULL)
19     {
20         mexWarnMsgIdAndTxt ("GB:warn", "monoid operator missing") ;
21         return (NULL) ;
22     }
23 
24     if (Complex != GxB_FC64) // && add->ztype == Complex)
25     {
26         // user-defined monoids
27         if (add == Complex_plus ) return (Complex_plus_monoid ) ;
28         if (add == Complex_times) return (Complex_times_monoid) ;
29     }
30 
31     switch (add->opcode)
32     {
33 
34         //----------------------------------------------------------------------
35         case GB_MIN_opcode     :
36         //----------------------------------------------------------------------
37 
38             // 11 MIN monoids
39             switch (add->xtype->code)
40             {
41                 // bool case redudant with AND
42                 case GB_BOOL_code   : return (GxB_LAND_BOOL_MONOID    ) ;
43                 case GB_INT8_code   : return (GxB_MIN_INT8_MONOID     ) ;
44                 case GB_UINT8_code  : return (GxB_MIN_UINT8_MONOID    ) ;
45                 case GB_INT16_code  : return (GxB_MIN_INT16_MONOID    ) ;
46                 case GB_UINT16_code : return (GxB_MIN_UINT16_MONOID   ) ;
47                 case GB_INT32_code  : return (GxB_MIN_INT32_MONOID    ) ;
48                 case GB_UINT32_code : return (GxB_MIN_UINT32_MONOID   ) ;
49                 case GB_INT64_code  : return (GxB_MIN_INT64_MONOID    ) ;
50                 case GB_UINT64_code : return (GxB_MIN_UINT64_MONOID   ) ;
51                 case GB_FP32_code   : return (GxB_MIN_FP32_MONOID     ) ;
52                 case GB_FP64_code   : return (GxB_MIN_FP64_MONOID     ) ;
53                 default:
54                     mexWarnMsgIdAndTxt ("GB:warn", "unknown type (MIN)") ;
55                     return (NULL) ;
56             }
57             break ;
58 
59         //----------------------------------------------------------------------
60         case GB_MAX_opcode     :
61         //----------------------------------------------------------------------
62 
63             // 11 MAX monoids
64             switch (add->xtype->code)
65             {
66                 // bool case redundant with OR
67                 case GB_BOOL_code   : return (GxB_LOR_BOOL_MONOID     ) ;
68                 case GB_INT8_code   : return (GxB_MAX_INT8_MONOID     ) ;
69                 case GB_UINT8_code  : return (GxB_MAX_UINT8_MONOID    ) ;
70                 case GB_INT16_code  : return (GxB_MAX_INT16_MONOID    ) ;
71                 case GB_UINT16_code : return (GxB_MAX_UINT16_MONOID   ) ;
72                 case GB_INT32_code  : return (GxB_MAX_INT32_MONOID    ) ;
73                 case GB_UINT32_code : return (GxB_MAX_UINT32_MONOID   ) ;
74                 case GB_INT64_code  : return (GxB_MAX_INT64_MONOID    ) ;
75                 case GB_UINT64_code : return (GxB_MAX_UINT64_MONOID   ) ;
76                 case GB_FP32_code   : return (GxB_MAX_FP32_MONOID     ) ;
77                 case GB_FP64_code   : return (GxB_MAX_FP64_MONOID     ) ;
78                 default:
79                     mexWarnMsgIdAndTxt ("GB:warn", "unknown type (MAX)") ;
80                     return (NULL) ;
81             }
82             break ;
83 
84         //----------------------------------------------------------------------
85         case GB_PLUS_opcode    :
86         //----------------------------------------------------------------------
87 
88             // 11 PLUS monoids
89             switch (add->xtype->code)
90             {
91                 // bool case redundant with OR
92                 case GB_BOOL_code   : return (GxB_LOR_BOOL_MONOID     ) ;
93                 case GB_INT8_code   : return (GxB_PLUS_INT8_MONOID    ) ;
94                 case GB_UINT8_code  : return (GxB_PLUS_UINT8_MONOID   ) ;
95                 case GB_INT16_code  : return (GxB_PLUS_INT16_MONOID   ) ;
96                 case GB_UINT16_code : return (GxB_PLUS_UINT16_MONOID  ) ;
97                 case GB_INT32_code  : return (GxB_PLUS_INT32_MONOID   ) ;
98                 case GB_UINT32_code : return (GxB_PLUS_UINT32_MONOID  ) ;
99                 case GB_INT64_code  : return (GxB_PLUS_INT64_MONOID   ) ;
100                 case GB_UINT64_code : return (GxB_PLUS_UINT64_MONOID  ) ;
101                 case GB_FP32_code   : return (GxB_PLUS_FP32_MONOID    ) ;
102                 case GB_FP64_code   : return (GxB_PLUS_FP64_MONOID    ) ;
103                 case GB_FC32_code   : return (GxB_PLUS_FC32_MONOID    ) ;
104                 case GB_FC64_code   : return (GxB_PLUS_FC64_MONOID    ) ;
105                 default:
106                     mexWarnMsgIdAndTxt ("GB:warn", "unknown type (PLUS)") ;
107                     return (NULL) ;
108             }
109             break ;
110 
111         //----------------------------------------------------------------------
112         case GB_TIMES_opcode   :
113         //----------------------------------------------------------------------
114 
115             // 11 TIMES monoids
116             switch (add->xtype->code)
117             {
118                 // bool case redundant with AND
119                 case GB_BOOL_code   : return (GxB_LAND_BOOL_MONOID    ) ;
120                 case GB_INT8_code   : return (GxB_TIMES_INT8_MONOID   ) ;
121                 case GB_UINT8_code  : return (GxB_TIMES_UINT8_MONOID  ) ;
122                 case GB_INT16_code  : return (GxB_TIMES_INT16_MONOID  ) ;
123                 case GB_UINT16_code : return (GxB_TIMES_UINT16_MONOID ) ;
124                 case GB_INT32_code  : return (GxB_TIMES_INT32_MONOID  ) ;
125                 case GB_UINT32_code : return (GxB_TIMES_UINT32_MONOID ) ;
126                 case GB_INT64_code  : return (GxB_TIMES_INT64_MONOID  ) ;
127                 case GB_UINT64_code : return (GxB_TIMES_UINT64_MONOID ) ;
128                 case GB_FP32_code   : return (GxB_TIMES_FP32_MONOID   ) ;
129                 case GB_FP64_code   : return (GxB_TIMES_FP64_MONOID   ) ;
130                 case GB_FC32_code   : return (GxB_TIMES_FC32_MONOID   ) ;
131                 case GB_FC64_code   : return (GxB_TIMES_FC64_MONOID   ) ;
132                 default:
133                     mexWarnMsgIdAndTxt ("GB:warn", "unknown type (TIMES)") ;
134                     return (NULL) ;
135             }
136             break ;
137 
138         //----------------------------------------------------------------------
139         case GB_ANY_opcode   :
140         //----------------------------------------------------------------------
141 
142             // 11 ANY monoids
143             switch (add->xtype->code)
144             {
145                 case GB_BOOL_code   : return (GxB_ANY_BOOL_MONOID   ) ;
146                 case GB_INT8_code   : return (GxB_ANY_INT8_MONOID   ) ;
147                 case GB_UINT8_code  : return (GxB_ANY_UINT8_MONOID  ) ;
148                 case GB_INT16_code  : return (GxB_ANY_INT16_MONOID  ) ;
149                 case GB_UINT16_code : return (GxB_ANY_UINT16_MONOID ) ;
150                 case GB_INT32_code  : return (GxB_ANY_INT32_MONOID  ) ;
151                 case GB_UINT32_code : return (GxB_ANY_UINT32_MONOID ) ;
152                 case GB_INT64_code  : return (GxB_ANY_INT64_MONOID  ) ;
153                 case GB_UINT64_code : return (GxB_ANY_UINT64_MONOID ) ;
154                 case GB_FP32_code   : return (GxB_ANY_FP32_MONOID   ) ;
155                 case GB_FP64_code   : return (GxB_ANY_FP64_MONOID   ) ;
156                 case GB_FC32_code   : return (GxB_ANY_FC32_MONOID   ) ;
157                 case GB_FC64_code   : return (GxB_ANY_FC64_MONOID   ) ;
158                 default:
159                     mexWarnMsgIdAndTxt ("GB:warn", "unknown type (ANY)") ;
160                     return (NULL) ;
161             }
162             break ;
163 
164         //----------------------------------------------------------------------
165         case GB_LOR_opcode      :
166         //----------------------------------------------------------------------
167 
168             // 2 OR boolean monoids
169             // both GrB_LOR and GxB_LOR_BOOL (same opcode)
170             switch (add->xtype->code)
171             {
172                 case GB_BOOL_code   : return (GxB_LOR_BOOL_MONOID     ) ;
173                 default:
174                     mexWarnMsgIdAndTxt ("GB:warn", "invalid monoid (OR)") ;
175                     return (NULL) ;
176             }
177             break ;
178 
179         //----------------------------------------------------------------------
180         case GB_LAND_opcode     :
181         //----------------------------------------------------------------------
182 
183             // 2 AND boolean monoids
184             // both GrB_LAND and GxB_LAND_BOOL (same opcode)
185             switch (add->xtype->code)
186             {
187                 case GB_BOOL_code   : return (GxB_LAND_BOOL_MONOID    ) ;
188                 default:
189                     mexWarnMsgIdAndTxt ("GB:warn", "invalid monoid (AND)") ;
190                     return (NULL) ;
191             }
192             break ;
193 
194         //----------------------------------------------------------------------
195         case GB_LXOR_opcode     : // GrB_LXOR and GxB_LXOR_BOOL (same opcode)
196         //----------------------------------------------------------------------
197 
198             // 2 XOR boolean monoids
199             switch (add->xtype->code)
200             {
201                 case GB_BOOL_code   : return (GxB_LXOR_BOOL_MONOID    ) ;
202                 default:
203                     mexWarnMsgIdAndTxt ("GB:warn", "invalid monoid (XOR)") ;
204                     return (NULL) ;
205             }
206             break ;
207 
208 
209         //----------------------------------------------------------------------
210         case GB_ISEQ_opcode     : // both GrB_EQ_BOOL and GxB_ISEQ_BOOL
211         case GB_EQ_opcode       : // (different opcode)
212         //----------------------------------------------------------------------
213 
214             // EQ and ISEQ boolean monoids
215             switch (add->xtype->code)
216             {
217                 case GB_BOOL_code   : return (GxB_EQ_BOOL_MONOID      ) ;
218                 default:
219                     mexWarnMsgIdAndTxt ("GB:warn", "invalid monoid (EQ)") ;
220                     return (NULL) ;
221             }
222             break ;
223 
224         //----------------------------------------------------------------------
225         case GB_BOR_opcode :     // z = (x | y), bitwise or
226         //----------------------------------------------------------------------
227 
228             switch (add->xtype->code)
229             {
230                 case GB_UINT8_code  : return (GxB_BOR_UINT8_MONOID ) ;
231                 case GB_UINT16_code : return (GxB_BOR_UINT16_MONOID) ;
232                 case GB_UINT32_code : return (GxB_BOR_UINT32_MONOID) ;
233                 case GB_UINT64_code : return (GxB_BOR_UINT64_MONOID) ;
234                 default: ;
235             }
236             break ;
237 
238         //----------------------------------------------------------------------
239         case GB_BAND_opcode :    // z = (x & y), bitwise and
240         //----------------------------------------------------------------------
241 
242             switch (add->xtype->code)
243             {
244                 case GB_UINT8_code  : return (GxB_BAND_UINT8_MONOID ) ;
245                 case GB_UINT16_code : return (GxB_BAND_UINT16_MONOID) ;
246                 case GB_UINT32_code : return (GxB_BAND_UINT32_MONOID) ;
247                 case GB_UINT64_code : return (GxB_BAND_UINT64_MONOID) ;
248                 default: ;
249             }
250             break ;
251 
252         //----------------------------------------------------------------------
253         case GB_BXOR_opcode :    // z = (x ^ y), bitwise xor
254         //----------------------------------------------------------------------
255 
256             switch (add->xtype->code)
257             {
258                 case GB_UINT8_code  : return (GxB_BXOR_UINT8_MONOID ) ;
259                 case GB_UINT16_code : return (GxB_BXOR_UINT16_MONOID) ;
260                 case GB_UINT32_code : return (GxB_BXOR_UINT32_MONOID) ;
261                 case GB_UINT64_code : return (GxB_BXOR_UINT64_MONOID) ;
262                 default: ;
263             }
264             break ;
265 
266         //----------------------------------------------------------------------
267         case GB_BXNOR_opcode :   // z = ~(x ^ y), bitwise xnor
268         //----------------------------------------------------------------------
269 
270             switch (add->xtype->code)
271             {
272                 case GB_UINT8_code  : return (GxB_BXNOR_UINT8_MONOID ) ;
273                 case GB_UINT16_code : return (GxB_BXNOR_UINT16_MONOID) ;
274                 case GB_UINT32_code : return (GxB_BXNOR_UINT32_MONOID) ;
275                 case GB_UINT64_code : return (GxB_BXNOR_UINT64_MONOID) ;
276                 default: ;
277             }
278             break ;
279 
280 
281         //----------------------------------------------------------------------
282         default:
283         //----------------------------------------------------------------------
284 
285             mexWarnMsgIdAndTxt ("GB:warn", "unsupported add operator") ;
286             return (NULL) ;
287     }
288 
289     mexWarnMsgIdAndTxt ("GB:warn", "unknown monoid") ;
290     return (NULL) ;
291 }
292 
293