1 //------------------------------------------------------------------------------
2 // gb_string_and_type_to_unop: get a GraphBLAS operator from a string and type
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 #include "gb_matlab.h"
11 
12 // op_name: a MATLAB string defining the operator name.
13 
14 // For all 13 types:
15 //      identity, ainv, minv, one, abs
16 //      (for complex, abs returns a real result)
17 
18 // For all 11 real types: (result is same type as input)
19 //      lnot
20 
21 // For 4 floating-point types (real & complex)x(single & double)
22 //      (result is same type as input):
23 //      sqrt, log, exp,
24 //      sin, cos, tan, acos, asin, atan,
25 //      sinh, cosh, tanh, acosh, asinh, atanh,
26 //      signum, ceil, floor, round, trunc, exp2, expm1, log10, log1p, log2
27 
28 // for complex only:
29 //      creal, cimag, carg  (result is real)
30 //      conj (result is complex)
31 
32 // For all 4 floating-point types (result is logical)
33 //      isinf, isnan, isfinite
34 
35 // For single and double:
36 //      lgamma, tgamma, erf, erfc, frexpx, frexpe (result same type as input)
37 
38 // for integer types only:
39 //      bitcmp
40 
41 // for int32 and int64:
42 //      positioni0, positioni1
43 //      positionj0, positionj1
44 
45 // The following equivalent synonyms are available:
46 //  identity    +       uplus
47 //  ainv        -       uminus  negate
48 //  lnot        ~       not
49 //  one         1
50 //  creal       real
51 //  cimag       imag
52 //  carg        angle
53 //  lgamma      gammaln
54 //  tgamma      gamma
55 //  exp2        pow2
56 //  i           i1  positioni   positioni1 (since MATLAB is 1-based)
57 //  i0          positioni0
58 //  j           j1  positionj   positionj1 (since MATLAB is 1-based)
59 //  j0          positionj0
60 
gb_string_and_type_to_unop(const char * op_name,const GrB_Type type,const bool type_not_given)61 GrB_UnaryOp gb_string_and_type_to_unop  // return op from string and type
62 (
63     const char *op_name,        // name of the operator, as a string
64     const GrB_Type type,        // type of the input to the operator
65     const bool type_not_given   // true if no type present in the string
66 )
67 {
68 
69     if (MATCH (op_name, "identity") || MATCH (op_name, "+") ||
70         MATCH (op_name, "uplus"))
71     {
72 
73         if (type == GrB_BOOL  ) return (GrB_IDENTITY_BOOL  ) ;
74         if (type == GrB_INT8  ) return (GrB_IDENTITY_INT8  ) ;
75         if (type == GrB_INT16 ) return (GrB_IDENTITY_INT16 ) ;
76         if (type == GrB_INT32 ) return (GrB_IDENTITY_INT32 ) ;
77         if (type == GrB_INT64 ) return (GrB_IDENTITY_INT64 ) ;
78         if (type == GrB_UINT8 ) return (GrB_IDENTITY_UINT8 ) ;
79         if (type == GrB_UINT16) return (GrB_IDENTITY_UINT16) ;
80         if (type == GrB_UINT32) return (GrB_IDENTITY_UINT32) ;
81         if (type == GrB_UINT64) return (GrB_IDENTITY_UINT64) ;
82         if (type == GrB_FP32  ) return (GrB_IDENTITY_FP32  ) ;
83         if (type == GrB_FP64  ) return (GrB_IDENTITY_FP64  ) ;
84         if (type == GxB_FC32  ) return (GxB_IDENTITY_FC32  ) ;
85         if (type == GxB_FC64  ) return (GxB_IDENTITY_FC64  ) ;
86 
87     }
88     else if (MATCH (op_name, "ainv"  ) || MATCH (op_name, "-") ||
89              MATCH (op_name, "negate") || MATCH (op_name, "uminus"))
90     {
91 
92         if (type == GrB_BOOL  ) return (GrB_AINV_BOOL  ) ;
93         if (type == GrB_INT8  ) return (GrB_AINV_INT8  ) ;
94         if (type == GrB_INT16 ) return (GrB_AINV_INT16 ) ;
95         if (type == GrB_INT32 ) return (GrB_AINV_INT32 ) ;
96         if (type == GrB_INT64 ) return (GrB_AINV_INT64 ) ;
97         if (type == GrB_UINT8 ) return (GrB_AINV_UINT8 ) ;
98         if (type == GrB_UINT16) return (GrB_AINV_UINT16) ;
99         if (type == GrB_UINT32) return (GrB_AINV_UINT32) ;
100         if (type == GrB_UINT64) return (GrB_AINV_UINT64) ;
101         if (type == GrB_FP32  ) return (GrB_AINV_FP32  ) ;
102         if (type == GrB_FP64  ) return (GrB_AINV_FP64  ) ;
103         if (type == GxB_FC32  ) return (GxB_AINV_FC32  ) ;
104         if (type == GxB_FC64  ) return (GxB_AINV_FC64  ) ;
105 
106     }
107     else if (MATCH (op_name, "minv"))
108     {
109 
110         if (type == GrB_BOOL  ) return (GrB_MINV_BOOL  ) ;
111         if (type == GrB_INT8  ) return (GrB_MINV_INT8  ) ;
112         if (type == GrB_INT16 ) return (GrB_MINV_INT16 ) ;
113         if (type == GrB_INT32 ) return (GrB_MINV_INT32 ) ;
114         if (type == GrB_INT64 ) return (GrB_MINV_INT64 ) ;
115         if (type == GrB_UINT8 ) return (GrB_MINV_UINT8 ) ;
116         if (type == GrB_UINT16) return (GrB_MINV_UINT16) ;
117         if (type == GrB_UINT32) return (GrB_MINV_UINT32) ;
118         if (type == GrB_UINT64) return (GrB_MINV_UINT64) ;
119         if (type == GrB_FP32  ) return (GrB_MINV_FP32  ) ;
120         if (type == GrB_FP64  ) return (GrB_MINV_FP64  ) ;
121         if (type == GxB_FC32  ) return (GxB_MINV_FC32  ) ;
122         if (type == GxB_FC64  ) return (GxB_MINV_FC64  ) ;
123 
124     }
125     else if (MATCH (op_name, "lnot") || MATCH (op_name, "~") ||
126              MATCH (op_name, "not"))
127     {
128 
129         if (type == GrB_BOOL  ) return (GxB_LNOT_BOOL  ) ;  // == GrB_LNOT
130         if (type == GrB_INT8  ) return (GxB_LNOT_INT8  ) ;
131         if (type == GrB_INT16 ) return (GxB_LNOT_INT16 ) ;
132         if (type == GrB_INT32 ) return (GxB_LNOT_INT32 ) ;
133         if (type == GrB_INT64 ) return (GxB_LNOT_INT64 ) ;
134         if (type == GrB_UINT8 ) return (GxB_LNOT_UINT8 ) ;
135         if (type == GrB_UINT16) return (GxB_LNOT_UINT16) ;
136         if (type == GrB_UINT32) return (GxB_LNOT_UINT32) ;
137         if (type == GrB_UINT64) return (GxB_LNOT_UINT64) ;
138         if (type == GrB_FP32  ) return (GxB_LNOT_FP32  ) ;
139         if (type == GrB_FP64  ) return (GxB_LNOT_FP64  ) ;
140 
141     }
142     else if (MATCH (op_name, "one") || MATCH (op_name, "1"))
143     {
144 
145         if (type == GrB_BOOL  ) return (GxB_ONE_BOOL  ) ;
146         if (type == GrB_INT8  ) return (GxB_ONE_INT8  ) ;
147         if (type == GrB_INT16 ) return (GxB_ONE_INT16 ) ;
148         if (type == GrB_INT32 ) return (GxB_ONE_INT32 ) ;
149         if (type == GrB_INT64 ) return (GxB_ONE_INT64 ) ;
150         if (type == GrB_UINT8 ) return (GxB_ONE_UINT8 ) ;
151         if (type == GrB_UINT16) return (GxB_ONE_UINT16) ;
152         if (type == GrB_UINT32) return (GxB_ONE_UINT32) ;
153         if (type == GrB_UINT64) return (GxB_ONE_UINT64) ;
154         if (type == GrB_FP32  ) return (GxB_ONE_FP32  ) ;
155         if (type == GrB_FP64  ) return (GxB_ONE_FP64  ) ;
156         if (type == GxB_FC32  ) return (GxB_ONE_FC32  ) ;
157         if (type == GxB_FC64  ) return (GxB_ONE_FC64  ) ;
158 
159     }
160     else if (MATCH (op_name, "abs"))
161     {
162 
163         if (type == GrB_BOOL  ) return (GrB_ABS_BOOL  ) ;
164         if (type == GrB_INT8  ) return (GrB_ABS_INT8  ) ;
165         if (type == GrB_INT16 ) return (GrB_ABS_INT16 ) ;
166         if (type == GrB_INT32 ) return (GrB_ABS_INT32 ) ;
167         if (type == GrB_INT64 ) return (GrB_ABS_INT64 ) ;
168         if (type == GrB_UINT8 ) return (GrB_ABS_UINT8 ) ;
169         if (type == GrB_UINT16) return (GrB_ABS_UINT16) ;
170         if (type == GrB_UINT32) return (GrB_ABS_UINT32) ;
171         if (type == GrB_UINT64) return (GrB_ABS_UINT64) ;
172         if (type == GrB_FP32  ) return (GrB_ABS_FP32  ) ;
173         if (type == GrB_FP64  ) return (GrB_ABS_FP64  ) ;
174         if (type == GxB_FC32  ) return (GxB_ABS_FC32  ) ;
175         if (type == GxB_FC64  ) return (GxB_ABS_FC64  ) ;
176 
177     }
178     else if (MATCH (op_name, "sqrt"))
179     {
180 
181         if (type == GrB_FP32  ) return (GxB_SQRT_FP32) ;
182         if (type == GrB_FP64  ) return (GxB_SQRT_FP64) ;
183         if (type == GxB_FC32  ) return (GxB_SQRT_FC32) ;
184         if (type == GxB_FC64  ) return (GxB_SQRT_FC64) ;
185 
186     }
187     else if (MATCH (op_name, "log"))
188     {
189 
190         if (type == GrB_FP32  ) return (GxB_LOG_FP32) ;
191         if (type == GrB_FP64  ) return (GxB_LOG_FP64) ;
192         if (type == GxB_FC32  ) return (GxB_LOG_FC32) ;
193         if (type == GxB_FC64  ) return (GxB_LOG_FC64) ;
194 
195     }
196     else if (MATCH (op_name, "exp"))
197     {
198 
199         if (type == GrB_FP32  ) return (GxB_EXP_FP32) ;
200         if (type == GrB_FP64  ) return (GxB_EXP_FP64) ;
201         if (type == GxB_FC32  ) return (GxB_EXP_FC32) ;
202         if (type == GxB_FC64  ) return (GxB_EXP_FC64) ;
203 
204     }
205     else if (MATCH (op_name, "sin"))
206     {
207 
208         if (type == GrB_FP32  ) return (GxB_SIN_FP32) ;
209         if (type == GrB_FP64  ) return (GxB_SIN_FP64) ;
210         if (type == GxB_FC32  ) return (GxB_SIN_FC32) ;
211         if (type == GxB_FC64  ) return (GxB_SIN_FC64) ;
212 
213     }
214     else if (MATCH (op_name, "cos"))
215     {
216 
217         if (type == GrB_FP32  ) return (GxB_COS_FP32) ;
218         if (type == GrB_FP64  ) return (GxB_COS_FP64) ;
219         if (type == GxB_FC32  ) return (GxB_COS_FC32) ;
220         if (type == GxB_FC64  ) return (GxB_COS_FC64) ;
221 
222     }
223     else if (MATCH (op_name, "tan"))
224     {
225 
226         if (type == GrB_FP32  ) return (GxB_TAN_FP32) ;
227         if (type == GrB_FP64  ) return (GxB_TAN_FP64) ;
228         if (type == GxB_FC32  ) return (GxB_TAN_FC32) ;
229         if (type == GxB_FC64  ) return (GxB_TAN_FC64) ;
230 
231     }
232     else if (MATCH (op_name, "asin"))
233     {
234 
235         if (type == GrB_FP32  ) return (GxB_ASIN_FP32) ;
236         if (type == GrB_FP64  ) return (GxB_ASIN_FP64) ;
237         if (type == GxB_FC32  ) return (GxB_ASIN_FC32) ;
238         if (type == GxB_FC64  ) return (GxB_ASIN_FC64) ;
239 
240     }
241     else if (MATCH (op_name, "acos"))
242     {
243 
244         if (type == GrB_FP32  ) return (GxB_ACOS_FP32) ;
245         if (type == GrB_FP64  ) return (GxB_ACOS_FP64) ;
246         if (type == GxB_FC32  ) return (GxB_ACOS_FC32) ;
247         if (type == GxB_FC64  ) return (GxB_ACOS_FC64) ;
248 
249     }
250     else if (MATCH (op_name, "atan"))
251     {
252 
253         if (type == GrB_FP32  ) return (GxB_ATAN_FP32) ;
254         if (type == GrB_FP64  ) return (GxB_ATAN_FP64) ;
255         if (type == GxB_FC32  ) return (GxB_ATAN_FC32) ;
256         if (type == GxB_FC64  ) return (GxB_ATAN_FC64) ;
257 
258     }
259     else if (MATCH (op_name, "sinh"))
260     {
261 
262         if (type == GrB_FP32  ) return (GxB_SINH_FP32) ;
263         if (type == GrB_FP64  ) return (GxB_SINH_FP64) ;
264         if (type == GxB_FC32  ) return (GxB_SINH_FC32) ;
265         if (type == GxB_FC64  ) return (GxB_SINH_FC64) ;
266 
267     }
268     else if (MATCH (op_name, "cosh"))
269     {
270 
271         if (type == GrB_FP32  ) return (GxB_COSH_FP32) ;
272         if (type == GrB_FP64  ) return (GxB_COSH_FP64) ;
273         if (type == GxB_FC32  ) return (GxB_COSH_FC32) ;
274         if (type == GxB_FC64  ) return (GxB_COSH_FC64) ;
275 
276     }
277     else if (MATCH (op_name, "tanh"))
278     {
279 
280         if (type == GrB_FP32  ) return (GxB_TANH_FP32) ;
281         if (type == GrB_FP64  ) return (GxB_TANH_FP64) ;
282         if (type == GxB_FC32  ) return (GxB_TANH_FC32) ;
283         if (type == GxB_FC64  ) return (GxB_TANH_FC64) ;
284 
285     }
286     else if (MATCH (op_name, "asinh"))
287     {
288 
289         if (type == GrB_FP32  ) return (GxB_ASINH_FP32) ;
290         if (type == GrB_FP64  ) return (GxB_ASINH_FP64) ;
291         if (type == GxB_FC32  ) return (GxB_ASINH_FC32) ;
292         if (type == GxB_FC64  ) return (GxB_ASINH_FC64) ;
293 
294     }
295     else if (MATCH (op_name, "acosh"))
296     {
297 
298         if (type == GrB_FP32  ) return (GxB_ACOSH_FP32) ;
299         if (type == GrB_FP64  ) return (GxB_ACOSH_FP64) ;
300         if (type == GxB_FC32  ) return (GxB_ACOSH_FC32) ;
301         if (type == GxB_FC64  ) return (GxB_ACOSH_FC64) ;
302 
303     }
304     else if (MATCH (op_name, "atanh"))
305     {
306 
307         if (type == GrB_FP32  ) return (GxB_ATANH_FP32) ;
308         if (type == GrB_FP64  ) return (GxB_ATANH_FP64) ;
309         if (type == GxB_FC32  ) return (GxB_ATANH_FC32) ;
310         if (type == GxB_FC64  ) return (GxB_ATANH_FC64) ;
311 
312     }
313     else if (MATCH (op_name, "sign") ||  MATCH (op_name, "signum"))
314     {
315 
316         if (type == GrB_FP32  ) return (GxB_SIGNUM_FP32) ;
317         if (type == GrB_FP64  ) return (GxB_SIGNUM_FP64) ;
318         if (type == GxB_FC32  ) return (GxB_SIGNUM_FC32) ;
319         if (type == GxB_FC64  ) return (GxB_SIGNUM_FC64) ;
320 
321     }
322     else if (MATCH (op_name, "ceil"))
323     {
324 
325         if (type == GrB_FP32  ) return (GxB_CEIL_FP32) ;
326         if (type == GrB_FP64  ) return (GxB_CEIL_FP64) ;
327         if (type == GxB_FC32  ) return (GxB_CEIL_FC32) ;
328         if (type == GxB_FC64  ) return (GxB_CEIL_FC64) ;
329 
330     }
331     else if (MATCH (op_name, "floor"))
332     {
333 
334         if (type == GrB_FP32  ) return (GxB_FLOOR_FP32) ;
335         if (type == GrB_FP64  ) return (GxB_FLOOR_FP64) ;
336         if (type == GxB_FC32  ) return (GxB_FLOOR_FC32) ;
337         if (type == GxB_FC64  ) return (GxB_FLOOR_FC64) ;
338 
339     }
340     else if (MATCH (op_name, "round"))
341     {
342 
343         if (type == GrB_FP32  ) return (GxB_ROUND_FP32) ;
344         if (type == GrB_FP64  ) return (GxB_ROUND_FP64) ;
345         if (type == GxB_FC32  ) return (GxB_ROUND_FC32) ;
346         if (type == GxB_FC64  ) return (GxB_ROUND_FC64) ;
347 
348     }
349     else if (MATCH (op_name, "trunc") || MATCH (op_name, "fix"))
350     {
351 
352         if (type == GrB_FP32  ) return (GxB_TRUNC_FP32) ;
353         if (type == GrB_FP64  ) return (GxB_TRUNC_FP64) ;
354         if (type == GxB_FC32  ) return (GxB_TRUNC_FC32) ;
355         if (type == GxB_FC64  ) return (GxB_TRUNC_FC64) ;
356 
357     }
358     else if (MATCH (op_name, "exp2") || MATCH (op_name, "pow2"))
359     {
360 
361         if (type == GrB_FP32  ) return (GxB_EXP2_FP32) ;
362         if (type == GrB_FP64  ) return (GxB_EXP2_FP64) ;
363         if (type == GxB_FC32  ) return (GxB_EXP2_FC32) ;
364         if (type == GxB_FC64  ) return (GxB_EXP2_FC64) ;
365 
366     }
367     else if (MATCH (op_name, "expm1"))
368     {
369 
370         if (type == GrB_FP32  ) return (GxB_EXPM1_FP32) ;
371         if (type == GrB_FP64  ) return (GxB_EXPM1_FP64) ;
372         if (type == GxB_FC32  ) return (GxB_EXPM1_FC32) ;
373         if (type == GxB_FC64  ) return (GxB_EXPM1_FC64) ;
374 
375     }
376     else if (MATCH (op_name, "log10"))
377     {
378 
379         if (type == GrB_FP32  ) return (GxB_LOG10_FP32) ;
380         if (type == GrB_FP64  ) return (GxB_LOG10_FP64) ;
381         if (type == GxB_FC32  ) return (GxB_LOG10_FC32) ;
382         if (type == GxB_FC64  ) return (GxB_LOG10_FC64) ;
383 
384     }
385     else if (MATCH (op_name, "log1p"))
386     {
387 
388         if (type == GrB_FP32  ) return (GxB_LOG1P_FP32) ;
389         if (type == GrB_FP64  ) return (GxB_LOG1P_FP64) ;
390         if (type == GxB_FC32  ) return (GxB_LOG1P_FC32) ;
391         if (type == GxB_FC64  ) return (GxB_LOG1P_FC64) ;
392 
393     }
394     else if (MATCH (op_name, "log2"))
395     {
396 
397         if (type == GrB_FP32  ) return (GxB_LOG2_FP32) ;
398         if (type == GrB_FP64  ) return (GxB_LOG2_FP64) ;
399         if (type == GxB_FC32  ) return (GxB_LOG2_FC32) ;
400         if (type == GxB_FC64  ) return (GxB_LOG2_FC64) ;
401 
402     }
403     else if (MATCH (op_name, "lgamma") || MATCH (op_name, "gammaln"))
404     {
405 
406         if (type == GrB_FP32  ) return (GxB_LGAMMA_FP32) ;
407         if (type == GrB_FP64  ) return (GxB_LGAMMA_FP64) ;
408 
409     }
410     else if (MATCH (op_name, "tgamma") || MATCH (op_name, "gamma"))
411     {
412 
413         if (type == GrB_FP32  ) return (GxB_TGAMMA_FP32) ;
414         if (type == GrB_FP64  ) return (GxB_TGAMMA_FP64) ;
415 
416     }
417     else if (MATCH (op_name, "erf"))
418     {
419 
420         if (type == GrB_FP32  ) return (GxB_ERF_FP32) ;
421         if (type == GrB_FP64  ) return (GxB_ERF_FP64) ;
422 
423     }
424     else if (MATCH (op_name, "erfc"))
425     {
426 
427         if (type == GrB_FP32  ) return (GxB_ERFC_FP32) ;
428         if (type == GrB_FP64  ) return (GxB_ERFC_FP64) ;
429 
430     }
431     else if (MATCH (op_name, "conj"))
432     {
433 
434         if (type == GxB_FC32  ) return (GxB_CONJ_FC32) ;
435         if (type == GxB_FC64  ) return (GxB_CONJ_FC64) ;
436 
437     }
438     else if (MATCH (op_name, "creal") || MATCH (op_name, "real"))
439     {
440 
441         if (type == GxB_FC32  ) return (GxB_CREAL_FC32) ;
442         if (type == GxB_FC64  ) return (GxB_CREAL_FC64) ;
443 
444     }
445     else if (MATCH (op_name, "cimag") || MATCH (op_name, "imag"))
446     {
447 
448         if (type == GxB_FC32  ) return (GxB_CIMAG_FC32) ;
449         if (type == GxB_FC64  ) return (GxB_CIMAG_FC64) ;
450 
451     }
452     else if (MATCH (op_name, "carg") || MATCH (op_name, "angle"))
453     {
454 
455         if (type == GxB_FC32  ) return (GxB_CARG_FC32) ;
456         if (type == GxB_FC64  ) return (GxB_CARG_FC64) ;
457 
458     }
459     else if (MATCH (op_name, "isinf"))
460     {
461 
462         if (type == GrB_FP32  ) return (GxB_ISINF_FP32) ;
463         if (type == GrB_FP64  ) return (GxB_ISINF_FP64) ;
464         if (type == GxB_FC32  ) return (GxB_ISINF_FC32) ;
465         if (type == GxB_FC64  ) return (GxB_ISINF_FC64) ;
466 
467     }
468     else if (MATCH (op_name, "isnan"))
469     {
470 
471         if (type == GrB_FP32  ) return (GxB_ISNAN_FP32) ;
472         if (type == GrB_FP64  ) return (GxB_ISNAN_FP64) ;
473         if (type == GxB_FC32  ) return (GxB_ISNAN_FC32) ;
474         if (type == GxB_FC64  ) return (GxB_ISNAN_FC64) ;
475 
476     }
477     else if (MATCH (op_name, "isfinite"))
478     {
479 
480         if (type == GrB_FP32  ) return (GxB_ISFINITE_FP32) ;
481         if (type == GrB_FP64  ) return (GxB_ISFINITE_FP64) ;
482         if (type == GxB_FC32  ) return (GxB_ISFINITE_FC32) ;
483         if (type == GxB_FC64  ) return (GxB_ISFINITE_FC64) ;
484 
485     }
486     else if (MATCH (op_name, "frexpx"))
487     {
488 
489         if (type == GrB_FP32  ) return (GxB_FREXPX_FP32) ;
490         if (type == GrB_FP64  ) return (GxB_FREXPX_FP64) ;
491 
492     }
493     else if (MATCH (op_name, "frexpe"))
494     {
495 
496         if (type == GrB_FP32  ) return (GxB_FREXPE_FP32) ;
497         if (type == GrB_FP64  ) return (GxB_FREXPE_FP64) ;
498 
499     }
500     else if (MATCH (op_name, "bitcmp") || MATCH (op_name, "bitnot"))
501     {
502 
503         if (type == GrB_INT8  ) return (GrB_BNOT_INT8  ) ;
504         if (type == GrB_INT16 ) return (GrB_BNOT_INT16 ) ;
505         if (type == GrB_INT32 ) return (GrB_BNOT_INT32 ) ;
506         if (type == GrB_INT64 ) return (GrB_BNOT_INT64 ) ;
507         if (type == GrB_UINT8 ) return (GrB_BNOT_UINT8 ) ;
508         if (type == GrB_UINT16) return (GrB_BNOT_UINT16) ;
509         if (type == GrB_UINT32) return (GrB_BNOT_UINT32) ;
510         if (type == GrB_UINT64) return (GrB_BNOT_UINT64) ;
511 
512     }
513     else if (MATCH (op_name, "positioni0") || MATCH (op_name, "i0"))
514     {
515 
516         if (type == GrB_INT32) return (GxB_POSITIONI_INT32) ;
517         if (type == GrB_INT64
518         ||  type_not_given   ) return (GxB_POSITIONI_INT64) ;
519 
520     }
521     else if (MATCH (op_name, "positioni1") || MATCH (op_name, "i1") ||
522              MATCH (op_name, "positioni" ) || MATCH (op_name, "i"))
523     {
524 
525         if (type == GrB_INT32) return (GxB_POSITIONI1_INT32) ;
526         if (type == GrB_INT64
527         ||  type_not_given   ) return (GxB_POSITIONI1_INT64) ;
528 
529     }
530     else if (MATCH (op_name, "positionj0") || MATCH (op_name, "j0"))
531     {
532 
533         if (type == GrB_INT32) return (GxB_POSITIONJ_INT32) ;
534         if (type == GrB_INT64
535         ||  type_not_given   ) return (GxB_POSITIONJ_INT64) ;
536 
537     }
538     else if (MATCH (op_name, "positionj1") || MATCH (op_name, "j1") ||
539              MATCH (op_name, "positionj" ) || MATCH (op_name, "j"))
540     {
541 
542         if (type == GrB_INT32) return (GxB_POSITIONJ1_INT32) ;
543         if (type == GrB_INT64
544         ||  type_not_given   ) return (GxB_POSITIONJ1_INT64) ;
545 
546     }
547 
548     //--------------------------------------------------------------------------
549     // unknown type or operator
550     //--------------------------------------------------------------------------
551 
552     // the type can be NULL for positional operators, but no others
553 
554     CHECK_ERROR (type == NULL, "unknown type") ;
555     ERROR2 ("unknown unary operator", op_name) ;
556     return (NULL) ;
557 }
558 
559