1 //------------------------------------------------------------------------------
2 // GB_mx_string_to_UnaryOp.c: get a GraphBLAS operator from MATLAB strings
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 
12 // opname_mx: a MATLAB string defining the operator name
13 
14 // optype_mx: a MATLAB string defining the operator type for built-in ops
15 
16 // default_optype: default type if optype_mx is NULL
17 
GB_mx_string_to_UnaryOp(GrB_UnaryOp * op_handle,const GrB_Type default_optype,const mxArray * opname_mx,const mxArray * optype_mx,const bool user_complex)18 bool GB_mx_string_to_UnaryOp            // true if successful, false otherwise
19 (
20     GrB_UnaryOp *op_handle,             // the unary op
21     const GrB_Type default_optype,      // default operator type
22     const mxArray *opname_mx,           // MATLAB string with operator name
23     const mxArray *optype_mx,           // MATLAB string with operator type
24     const bool user_complex             // true if X is complex
25 )
26 {
27 
28     (*op_handle) = NULL ;
29     GrB_UnaryOp op = NULL ;
30 
31     //--------------------------------------------------------------------------
32     // get the string
33     //--------------------------------------------------------------------------
34 
35     #define LEN 256
36     char opname [LEN+2] ;
37     int len = GB_mx_mxArray_to_string (opname, LEN, opname_mx) ;
38     if (len < 0)
39     {
40         return (false) ;
41     }
42 
43     // get the optype from the optype_mx string, if present
44     GrB_Type optype = GB_mx_string_to_Type (optype_mx, default_optype) ;
45     if (optype == NULL)
46     {
47         mexWarnMsgIdAndTxt ("GB:warn", "unrecognized op type") ;
48         return (false) ;
49     }
50 
51     //--------------------------------------------------------------------------
52     // convert the string to a GraphBLAS unary operator, built-in or Complex
53     //--------------------------------------------------------------------------
54 
55     if (user_complex && optype == Complex)
56     {
57 
58         //----------------------------------------------------------------------
59         // X complex
60         //----------------------------------------------------------------------
61 
62         if (len == 0)
63         {
64             op = NULL ;                 // no default Complex operator
65         }
66 
67         // 7 unary operators z=f(x), both x,z are Complex (6 same as builtin)
68         else if (MATCH (opname, "one"     )) { op = Complex_one      ; }
69         else if (MATCH (opname, "identity")) { op = Complex_identity ; }
70         else if (MATCH (opname, "ainv"    )) { op = Complex_ainv     ; }
71         else if (MATCH (opname, "abs"     )) { op = Complex_abs      ; }
72         else if (MATCH (opname, "minv"    )) { op = Complex_minv     ; }
73 
74         // this is not built-in
75         else if (MATCH (opname, "not"     )) { op = Complex_not      ; }
76 
77         else if (MATCH (opname, "conj"    )) { op = Complex_conj     ; }
78         else if (MATCH (opname, "real"    )) { op = Complex_real     ; }
79         else if (MATCH (opname, "imag"    )) { op = Complex_imag     ; }
80         else if (MATCH (opname, "carg"    )) { op = Complex_angle    ; }
81 
82         else
83         {
84             mexWarnMsgIdAndTxt ("GB:warn", "Complex op unrecognized") ;
85         }
86 
87     }
88     else
89     {
90 
91         //----------------------------------------------------------------------
92         // X is real (Z might be Complex)
93         //----------------------------------------------------------------------
94 
95         GB_Opcode opcode ;
96 
97              if (MATCH (opname, "one"     )) { opcode = GB_ONE_opcode ; }
98         else if (MATCH (opname, "identity")) { opcode = GB_IDENTITY_opcode ; }
99         else if (MATCH (opname, "ainv"    )) { opcode = GB_AINV_opcode ; }
100         else if (MATCH (opname, "abs"     )) { opcode = GB_ABS_opcode ; }
101         else if (MATCH (opname, "minv"    )) { opcode = GB_MINV_opcode ; }
102         else if (MATCH (opname, "not"     )) { opcode = GB_LNOT_opcode ; }
103 
104         else if (MATCH (opname, "conj"    )) { opcode = GB_CONJ_opcode ; }
105         else if (MATCH (opname, "real"    )) { opcode = GB_CREAL_opcode ; }
106         else if (MATCH (opname, "imag"    )) { opcode = GB_CIMAG_opcode ; }
107         else if (MATCH (opname, "carg"    )) { opcode = GB_CARG_opcode ; }
108 
109         else if (MATCH (opname, "sqrt"    )) { opcode = GB_SQRT_opcode ; }
110         else if (MATCH (opname, "log"     )) { opcode = GB_LOG_opcode ; }
111         else if (MATCH (opname, "exp"     )) { opcode = GB_EXP_opcode ; }
112 
113         else if (MATCH (opname, "sin"     )) { opcode = GB_SIN_opcode ; }
114         else if (MATCH (opname, "cos"     )) { opcode = GB_COS_opcode ; }
115         else if (MATCH (opname, "tan"     )) { opcode = GB_TAN_opcode ; }
116 
117         else if (MATCH (opname, "asin"    )) { opcode = GB_ASIN_opcode ; }
118         else if (MATCH (opname, "acos"    )) { opcode = GB_ACOS_opcode ; }
119         else if (MATCH (opname, "atan"    )) { opcode = GB_ATAN_opcode ; }
120 
121         else if (MATCH (opname, "sinh"    )) { opcode = GB_SINH_opcode ; }
122         else if (MATCH (opname, "cosh"    )) { opcode = GB_COSH_opcode ; }
123         else if (MATCH (opname, "tanh"    )) { opcode = GB_TANH_opcode ; }
124 
125         else if (MATCH (opname, "asinh"   )) { opcode = GB_ASINH_opcode ; }
126         else if (MATCH (opname, "acosh"   )) { opcode = GB_ACOSH_opcode ; }
127         else if (MATCH (opname, "atanh"   )) { opcode = GB_ATANH_opcode ; }
128 
129         else if (MATCH (opname, "signum"  )) { opcode = GB_SIGNUM_opcode ; }
130         else if (MATCH (opname, "ceil"    )) { opcode = GB_CEIL_opcode ; }
131         else if (MATCH (opname, "floor"   )) { opcode = GB_FLOOR_opcode ; }
132         else if (MATCH (opname, "round"   )) { opcode = GB_ROUND_opcode ; }
133         else if (MATCH (opname, "trunc"   )) { opcode = GB_TRUNC_opcode ; }
134 
135         else if (MATCH (opname, "exp2"    )) { opcode = GB_EXP2_opcode ; }
136         else if (MATCH (opname, "expm1"   )) { opcode = GB_EXPM1_opcode ; }
137         else if (MATCH (opname, "log10"   )) { opcode = GB_LOG10_opcode ; }
138         else if (MATCH (opname, "log1p"   )) { opcode = GB_LOG1P_opcode ; }
139         else if (MATCH (opname, "log2"    )) { opcode = GB_LOG2_opcode ; }
140 
141         else if (MATCH (opname, "lgamma"  )) { opcode = GB_LGAMMA_opcode ; }
142         else if (MATCH (opname, "tgamma"  )) { opcode = GB_TGAMMA_opcode ; }
143         else if (MATCH (opname, "erf"     )) { opcode = GB_ERF_opcode ; }
144         else if (MATCH (opname, "erfc"    )) { opcode = GB_ERFC_opcode ; }
145         else if (MATCH (opname, "frexpx"  )) { opcode = GB_FREXPX_opcode ; }
146         else if (MATCH (opname, "frexpe"  )) { opcode = GB_FREXPE_opcode ; }
147 
148         else if (MATCH (opname, "isinf"   )) { opcode = GB_ISINF_opcode ; }
149         else if (MATCH (opname, "isnan"   )) { opcode = GB_ISNAN_opcode ; }
150         else if (MATCH (opname, "isfinite")) { opcode = GB_ISFINITE_opcode ; }
151 
152         else if (MATCH (opname, "bitnot"  )) { opcode = GB_BNOT_opcode ; }
153         else if (MATCH (opname, "bitcmp"  )) { opcode = GB_BNOT_opcode ; }
154         else if (MATCH (opname, "bnot"    )) { opcode = GB_BNOT_opcode ; }
155         else if (MATCH (opname, "bcmp"    )) { opcode = GB_BNOT_opcode ; }
156 
157         else if (MATCH (opname, "positioni" )) { opcode = GB_POSITIONI_opcode ; }
158         else if (MATCH (opname, "i"         )) { opcode = GB_POSITIONI_opcode ; }
159         else if (MATCH (opname, "positioni1")) { opcode = GB_POSITIONI1_opcode ; }
160         else if (MATCH (opname, "i1"        )) { opcode = GB_POSITIONI1_opcode ; }
161         else if (MATCH (opname, "positionj" )) { opcode = GB_POSITIONJ_opcode ; }
162         else if (MATCH (opname, "j"         )) { opcode = GB_POSITIONJ_opcode ; }
163         else if (MATCH (opname, "positionj1")) { opcode = GB_POSITIONJ1_opcode ; }
164         else if (MATCH (opname, "j1"        )) { opcode = GB_POSITIONJ1_opcode ; }
165 
166         else
167         {
168             mexWarnMsgIdAndTxt ("GB:warn", "unrecognized function name") ;
169             return (false) ;
170         }
171 
172         GB_Type_code xcode = optype->code ;
173         bool is64 = (xcode == GB_INT64_code) ;
174 
175         if (GB_OPCODE_IS_POSITIONAL (opcode))
176         {
177             if (! (xcode == GB_INT64_code || xcode == GB_INT32_code))
178             {
179                 mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
180                 return (false) ;
181             }
182         }
183 
184         switch (opcode)
185         {
186 
187             case GB_ONE_opcode:
188 
189                 switch (xcode)
190                 {
191                     case GB_BOOL_code    : op = GxB_ONE_BOOL   ; break ;
192                     case GB_INT8_code    : op = GxB_ONE_INT8   ; break ;
193                     case GB_INT16_code   : op = GxB_ONE_INT16  ; break ;
194                     case GB_INT32_code   : op = GxB_ONE_INT32  ; break ;
195                     case GB_INT64_code   : op = GxB_ONE_INT64  ; break ;
196                     case GB_UINT8_code   : op = GxB_ONE_UINT8  ; break ;
197                     case GB_UINT16_code  : op = GxB_ONE_UINT16 ; break ;
198                     case GB_UINT32_code  : op = GxB_ONE_UINT32 ; break ;
199                     case GB_UINT64_code  : op = GxB_ONE_UINT64 ; break ;
200                     case GB_FP32_code    : op = GxB_ONE_FP32   ; break ;
201                     case GB_FP64_code    : op = GxB_ONE_FP64   ; break ;
202                     case GB_FC32_code    : op = GxB_ONE_FC32   ; break ;
203                     case GB_FC64_code    : op = GxB_ONE_FC64   ; break ;
204                     default              :
205                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
206                         return (false) ;
207                 }
208                 break ;
209 
210             case GB_IDENTITY_opcode:
211 
212                 switch (xcode)
213                 {
214                     case GB_BOOL_code    : op = GrB_IDENTITY_BOOL   ; break ;
215                     case GB_INT8_code    : op = GrB_IDENTITY_INT8   ; break ;
216                     case GB_INT16_code   : op = GrB_IDENTITY_INT16  ; break ;
217                     case GB_INT32_code   : op = GrB_IDENTITY_INT32  ; break ;
218                     case GB_INT64_code   : op = GrB_IDENTITY_INT64  ; break ;
219                     case GB_UINT8_code   : op = GrB_IDENTITY_UINT8  ; break ;
220                     case GB_UINT16_code  : op = GrB_IDENTITY_UINT16 ; break ;
221                     case GB_UINT32_code  : op = GrB_IDENTITY_UINT32 ; break ;
222                     case GB_UINT64_code  : op = GrB_IDENTITY_UINT64 ; break ;
223                     case GB_FP32_code    : op = GrB_IDENTITY_FP32   ; break ;
224                     case GB_FP64_code    : op = GrB_IDENTITY_FP64   ; break ;
225                     case GB_FC32_code    : op = GxB_IDENTITY_FC32   ; break ;
226                     case GB_FC64_code    : op = GxB_IDENTITY_FC64   ; break ;
227                     default              :
228                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
229                         return (false) ;
230                 }
231                 break ;
232 
233             case GB_ABS_opcode:
234 
235                 switch (xcode)
236                 {
237                     case GB_BOOL_code    : op = GrB_ABS_BOOL   ; break ;
238                     case GB_INT8_code    : op = GrB_ABS_INT8   ; break ;
239                     case GB_INT16_code   : op = GrB_ABS_INT16  ; break ;
240                     case GB_INT32_code   : op = GrB_ABS_INT32  ; break ;
241                     case GB_INT64_code   : op = GrB_ABS_INT64  ; break ;
242                     case GB_UINT8_code   : op = GrB_ABS_UINT8  ; break ;
243                     case GB_UINT16_code  : op = GrB_ABS_UINT16 ; break ;
244                     case GB_UINT32_code  : op = GrB_ABS_UINT32 ; break ;
245                     case GB_UINT64_code  : op = GrB_ABS_UINT64 ; break ;
246                     case GB_FP32_code    : op = GrB_ABS_FP32   ; break ;
247                     case GB_FP64_code    : op = GrB_ABS_FP64   ; break ;
248                     case GB_FC32_code    : op = GxB_ABS_FC32   ; break ;
249                     case GB_FC64_code    : op = GxB_ABS_FC64   ; break ;
250                     default              :
251                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
252                         return (false) ;
253                 }
254                 break ;
255 
256             case GB_AINV_opcode:
257 
258                 switch (xcode)
259                 {
260                     case GB_BOOL_code    : op = GrB_AINV_BOOL   ; break ;
261                     case GB_INT8_code    : op = GrB_AINV_INT8   ; break ;
262                     case GB_INT16_code   : op = GrB_AINV_INT16  ; break ;
263                     case GB_INT32_code   : op = GrB_AINV_INT32  ; break ;
264                     case GB_INT64_code   : op = GrB_AINV_INT64  ; break ;
265                     case GB_UINT8_code   : op = GrB_AINV_UINT8  ; break ;
266                     case GB_UINT16_code  : op = GrB_AINV_UINT16 ; break ;
267                     case GB_UINT32_code  : op = GrB_AINV_UINT32 ; break ;
268                     case GB_UINT64_code  : op = GrB_AINV_UINT64 ; break ;
269                     case GB_FP32_code    : op = GrB_AINV_FP32   ; break ;
270                     case GB_FP64_code    : op = GrB_AINV_FP64   ; break ;
271                     case GB_FC32_code    : op = GxB_AINV_FC32   ; break ;
272                     case GB_FC64_code    : op = GxB_AINV_FC64   ; break ;
273                     default              :
274                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
275                         return (false) ;
276                 }
277                 break ;
278 
279             case GB_MINV_opcode   :
280 
281                 switch (xcode)
282                 {
283                     case GB_BOOL_code    : op = GrB_MINV_BOOL   ; break ;
284                     case GB_INT8_code    : op = GrB_MINV_INT8   ; break ;
285                     case GB_INT16_code   : op = GrB_MINV_INT16  ; break ;
286                     case GB_INT32_code   : op = GrB_MINV_INT32  ; break ;
287                     case GB_INT64_code   : op = GrB_MINV_INT64  ; break ;
288                     case GB_UINT8_code   : op = GrB_MINV_UINT8  ; break ;
289                     case GB_UINT16_code  : op = GrB_MINV_UINT16 ; break ;
290                     case GB_UINT32_code  : op = GrB_MINV_UINT32 ; break ;
291                     case GB_UINT64_code  : op = GrB_MINV_UINT64 ; break ;
292                     case GB_FP32_code    : op = GrB_MINV_FP32   ; break ;
293                     case GB_FP64_code    : op = GrB_MINV_FP64   ; break ;
294                     case GB_FC32_code    : op = GxB_MINV_FC32   ; break ;
295                     case GB_FC64_code    : op = GxB_MINV_FC64   ; break ;
296                     default              :
297                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
298                         return (false) ;
299                 }
300                 break ;
301 
302             case GB_LNOT_opcode   :
303 
304                 switch (xcode)
305                 {
306                     case GB_BOOL_code    : op = GrB_LNOT        ; break ;
307                     case GB_INT8_code    : op = GxB_LNOT_INT8   ; break ;
308                     case GB_INT16_code   : op = GxB_LNOT_INT16  ; break ;
309                     case GB_INT32_code   : op = GxB_LNOT_INT32  ; break ;
310                     case GB_INT64_code   : op = GxB_LNOT_INT64  ; break ;
311                     case GB_UINT8_code   : op = GxB_LNOT_UINT8  ; break ;
312                     case GB_UINT16_code  : op = GxB_LNOT_UINT16 ; break ;
313                     case GB_UINT32_code  : op = GxB_LNOT_UINT32 ; break ;
314                     case GB_UINT64_code  : op = GxB_LNOT_UINT64 ; break ;
315                     case GB_FP32_code    : op = GxB_LNOT_FP32   ; break ;
316                     case GB_FP64_code    : op = GxB_LNOT_FP64   ; break ;
317                     default              :
318                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
319                         return (false) ;
320                 }
321                 break ;
322 
323             case GB_BNOT_opcode   :
324 
325                 switch (xcode)
326                 {
327                     case GB_INT8_code    : op = GrB_BNOT_INT8   ; break ;
328                     case GB_INT16_code   : op = GrB_BNOT_INT16  ; break ;
329                     case GB_INT32_code   : op = GrB_BNOT_INT32  ; break ;
330                     case GB_INT64_code   : op = GrB_BNOT_INT64  ; break ;
331                     case GB_UINT8_code   : op = GrB_BNOT_UINT8  ; break ;
332                     case GB_UINT16_code  : op = GrB_BNOT_UINT16 ; break ;
333                     case GB_UINT32_code  : op = GrB_BNOT_UINT32 ; break ;
334                     case GB_UINT64_code  : op = GrB_BNOT_UINT64 ; break ;
335                     default              :
336                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
337                         return (false) ;
338                 }
339                 break ;
340 
341     //--------------------------------------------------------------------------
342     // unary operators for floating-point types (real and complex)
343     //--------------------------------------------------------------------------
344 
345             case GB_SQRT_opcode :    // z = sqrt (x)
346 
347                 switch (xcode)
348                 {
349                     case GB_FP32_code    : op = GxB_SQRT_FP32   ; break ;
350                     case GB_FP64_code    : op = GxB_SQRT_FP64   ; break ;
351                     case GB_FC32_code    : op = GxB_SQRT_FC32   ; break ;
352                     case GB_FC64_code    : op = GxB_SQRT_FC64   ; break ;
353                     default              :
354                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
355                         return (false) ;
356                 }
357                 break ;
358 
359             case GB_LOG_opcode :     // z = log (x)
360 
361                 switch (xcode)
362                 {
363                     case GB_FP32_code    : op = GxB_LOG_FP32   ; break ;
364                     case GB_FP64_code    : op = GxB_LOG_FP64   ; break ;
365                     case GB_FC32_code    : op = GxB_LOG_FC32   ; break ;
366                     case GB_FC64_code    : op = GxB_LOG_FC64   ; break ;
367                     default              :
368                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
369                         return (false) ;
370                 }
371                 break ;
372 
373             case GB_EXP_opcode :     // z = exp (x)
374 
375                 switch (xcode)
376                 {
377                     case GB_FP32_code    : op = GxB_EXP_FP32   ; break ;
378                     case GB_FP64_code    : op = GxB_EXP_FP64   ; break ;
379                     case GB_FC32_code    : op = GxB_EXP_FC32   ; break ;
380                     case GB_FC64_code    : op = GxB_EXP_FC64   ; break ;
381                     default              :
382                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
383                         return (false) ;
384                 }
385                 break ;
386 
387 
388             case GB_SIN_opcode :     // z = sin (x)
389 
390                 switch (xcode)
391                 {
392                     case GB_FP32_code    : op = GxB_SIN_FP32   ; break ;
393                     case GB_FP64_code    : op = GxB_SIN_FP64   ; break ;
394                     case GB_FC32_code    : op = GxB_SIN_FC32   ; break ;
395                     case GB_FC64_code    : op = GxB_SIN_FC64   ; break ;
396                     default              :
397                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
398                         return (false) ;
399                 }
400                 break ;
401 
402             case GB_COS_opcode :     // z = cos (x)
403 
404                 switch (xcode)
405                 {
406                     case GB_FP32_code    : op = GxB_COS_FP32   ; break ;
407                     case GB_FP64_code    : op = GxB_COS_FP64   ; break ;
408                     case GB_FC32_code    : op = GxB_COS_FC32   ; break ;
409                     case GB_FC64_code    : op = GxB_COS_FC64   ; break ;
410                     default              :
411                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
412                         return (false) ;
413                 }
414                 break ;
415 
416             case GB_TAN_opcode :     // z = tan (x)
417 
418                 switch (xcode)
419                 {
420                     case GB_FP32_code    : op = GxB_TAN_FP32   ; break ;
421                     case GB_FP64_code    : op = GxB_TAN_FP64   ; break ;
422                     case GB_FC32_code    : op = GxB_TAN_FC32   ; break ;
423                     case GB_FC64_code    : op = GxB_TAN_FC64   ; break ;
424                     default              :
425                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
426                         return (false) ;
427                 }
428                 break ;
429 
430 
431             case GB_ASIN_opcode :    // z = asin (x)
432 
433                 switch (xcode)
434                 {
435                     case GB_FP32_code    : op = GxB_ASIN_FP32   ; break ;
436                     case GB_FP64_code    : op = GxB_ASIN_FP64   ; break ;
437                     case GB_FC32_code    : op = GxB_ASIN_FC32   ; break ;
438                     case GB_FC64_code    : op = GxB_ASIN_FC64   ; break ;
439                     default              :
440                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
441                         return (false) ;
442                 }
443                 break ;
444 
445             case GB_ACOS_opcode :    // z = acos (x)
446 
447                 switch (xcode)
448                 {
449                     case GB_FP32_code    : op = GxB_ACOS_FP32   ; break ;
450                     case GB_FP64_code    : op = GxB_ACOS_FP64   ; break ;
451                     case GB_FC32_code    : op = GxB_ACOS_FC32   ; break ;
452                     case GB_FC64_code    : op = GxB_ACOS_FC64   ; break ;
453                     default              :
454                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
455                         return (false) ;
456                 }
457                 break ;
458 
459             case GB_ATAN_opcode :    // z = atan (x)
460 
461                 switch (xcode)
462                 {
463                     case GB_FP32_code    : op = GxB_ATAN_FP32   ; break ;
464                     case GB_FP64_code    : op = GxB_ATAN_FP64   ; break ;
465                     case GB_FC32_code    : op = GxB_ATAN_FC32   ; break ;
466                     case GB_FC64_code    : op = GxB_ATAN_FC64   ; break ;
467                     default              :
468                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
469                         return (false) ;
470                 }
471                 break ;
472 
473 
474             case GB_SINH_opcode :    // z = sinh (x)
475 
476                 switch (xcode)
477                 {
478                     case GB_FP32_code    : op = GxB_SINH_FP32   ; break ;
479                     case GB_FP64_code    : op = GxB_SINH_FP64   ; break ;
480                     case GB_FC32_code    : op = GxB_SINH_FC32   ; break ;
481                     case GB_FC64_code    : op = GxB_SINH_FC64   ; break ;
482                     default              :
483                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
484                         return (false) ;
485                 }
486                 break ;
487 
488             case GB_COSH_opcode :    // z = cosh (x)
489 
490                 switch (xcode)
491                 {
492                     case GB_FP32_code    : op = GxB_COSH_FP32   ; break ;
493                     case GB_FP64_code    : op = GxB_COSH_FP64   ; break ;
494                     case GB_FC32_code    : op = GxB_COSH_FC32   ; break ;
495                     case GB_FC64_code    : op = GxB_COSH_FC64   ; break ;
496                     default              :
497                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
498                         return (false) ;
499                 }
500                 break ;
501 
502             case GB_TANH_opcode :    // z = tanh (x)
503 
504                 switch (xcode)
505                 {
506                     case GB_FP32_code    : op = GxB_TANH_FP32   ; break ;
507                     case GB_FP64_code    : op = GxB_TANH_FP64   ; break ;
508                     case GB_FC32_code    : op = GxB_TANH_FC32   ; break ;
509                     case GB_FC64_code    : op = GxB_TANH_FC64   ; break ;
510                     default              :
511                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
512                         return (false) ;
513                 }
514                 break ;
515 
516 
517             case GB_ASINH_opcode :   // z = asinh (x)
518 
519                 switch (xcode)
520                 {
521                     case GB_FP32_code    : op = GxB_ASINH_FP32   ; break ;
522                     case GB_FP64_code    : op = GxB_ASINH_FP64   ; break ;
523                     case GB_FC32_code    : op = GxB_ASINH_FC32   ; break ;
524                     case GB_FC64_code    : op = GxB_ASINH_FC64   ; break ;
525                     default              :
526                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
527                         return (false) ;
528                 }
529                 break ;
530 
531             case GB_ACOSH_opcode :   // z = acosh (x)
532 
533                 switch (xcode)
534                 {
535                     case GB_FP32_code    : op = GxB_ACOSH_FP32   ; break ;
536                     case GB_FP64_code    : op = GxB_ACOSH_FP64   ; break ;
537                     case GB_FC32_code    : op = GxB_ACOSH_FC32   ; break ;
538                     case GB_FC64_code    : op = GxB_ACOSH_FC64   ; break ;
539                     default              :
540                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
541                         return (false) ;
542                 }
543                 break ;
544 
545             case GB_ATANH_opcode :   // z = atanh (x)
546 
547                 switch (xcode)
548                 {
549                     case GB_FP32_code    : op = GxB_ATANH_FP32   ; break ;
550                     case GB_FP64_code    : op = GxB_ATANH_FP64   ; break ;
551                     case GB_FC32_code    : op = GxB_ATANH_FC32   ; break ;
552                     case GB_FC64_code    : op = GxB_ATANH_FC64   ; break ;
553                     default              :
554                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
555                         return (false) ;
556                 }
557                 break ;
558 
559 
560             case GB_SIGNUM_opcode :    // z = signum (x)
561 
562                 switch (xcode)
563                 {
564                     case GB_FP32_code    : op = GxB_SIGNUM_FP32   ; break ;
565                     case GB_FP64_code    : op = GxB_SIGNUM_FP64   ; break ;
566                     case GB_FC32_code    : op = GxB_SIGNUM_FC32   ; break ;
567                     case GB_FC64_code    : op = GxB_SIGNUM_FC64   ; break ;
568                     default              :
569                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
570                         return (false) ;
571                 }
572                 break ;
573 
574             case GB_CEIL_opcode :    // z = ceil (x)
575 
576                 switch (xcode)
577                 {
578                     case GB_FP32_code    : op = GxB_CEIL_FP32   ; break ;
579                     case GB_FP64_code    : op = GxB_CEIL_FP64   ; break ;
580                     case GB_FC32_code    : op = GxB_CEIL_FC32   ; break ;
581                     case GB_FC64_code    : op = GxB_CEIL_FC64   ; break ;
582                     default              :
583                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
584                         return (false) ;
585                 }
586                 break ;
587 
588             case GB_FLOOR_opcode :   // z = floor (x)
589 
590                 switch (xcode)
591                 {
592                     case GB_FP32_code    : op = GxB_FLOOR_FP32   ; break ;
593                     case GB_FP64_code    : op = GxB_FLOOR_FP64   ; break ;
594                     case GB_FC32_code    : op = GxB_FLOOR_FC32   ; break ;
595                     case GB_FC64_code    : op = GxB_FLOOR_FC64   ; break ;
596                     default              :
597                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
598                         return (false) ;
599                 }
600                 break ;
601 
602             case GB_ROUND_opcode :   // z = round (x)
603 
604                 switch (xcode)
605                 {
606                     case GB_FP32_code    : op = GxB_ROUND_FP32   ; break ;
607                     case GB_FP64_code    : op = GxB_ROUND_FP64   ; break ;
608                     case GB_FC32_code    : op = GxB_ROUND_FC32   ; break ;
609                     case GB_FC64_code    : op = GxB_ROUND_FC64   ; break ;
610                     default              :
611                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
612                         return (false) ;
613                 }
614                 break ;
615 
616             case GB_TRUNC_opcode :   // z = trunc (x)
617 
618                 switch (xcode)
619                 {
620                     case GB_FP32_code    : op = GxB_TRUNC_FP32   ; break ;
621                     case GB_FP64_code    : op = GxB_TRUNC_FP64   ; break ;
622                     case GB_FC32_code    : op = GxB_TRUNC_FC32   ; break ;
623                     case GB_FC64_code    : op = GxB_TRUNC_FC64   ; break ;
624                     default              :
625                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
626                         return (false) ;
627                 }
628                 break ;
629 
630 
631             case GB_EXP2_opcode :    // z = exp2 (x)
632 
633                 switch (xcode)
634                 {
635                     case GB_FP32_code    : op = GxB_EXP2_FP32   ; break ;
636                     case GB_FP64_code    : op = GxB_EXP2_FP64   ; break ;
637                     case GB_FC32_code    : op = GxB_EXP2_FC32   ; break ;
638                     case GB_FC64_code    : op = GxB_EXP2_FC64   ; break ;
639                     default              :
640                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
641                         return (false) ;
642                 }
643                 break ;
644 
645             case GB_EXPM1_opcode :   // z = expm1 (x)
646 
647                 switch (xcode)
648                 {
649                     case GB_FP32_code    : op = GxB_EXPM1_FP32   ; break ;
650                     case GB_FP64_code    : op = GxB_EXPM1_FP64   ; break ;
651                     case GB_FC32_code    : op = GxB_EXPM1_FC32   ; break ;
652                     case GB_FC64_code    : op = GxB_EXPM1_FC64   ; break ;
653                     default              :
654                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
655                         return (false) ;
656                 }
657                 break ;
658 
659             case GB_LOG10_opcode :   // z = log10 (x)
660 
661                 switch (xcode)
662                 {
663                     case GB_FP32_code    : op = GxB_LOG10_FP32   ; break ;
664                     case GB_FP64_code    : op = GxB_LOG10_FP64   ; break ;
665                     case GB_FC32_code    : op = GxB_LOG10_FC32   ; break ;
666                     case GB_FC64_code    : op = GxB_LOG10_FC64   ; break ;
667                     default              :
668                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
669                         return (false) ;
670                 }
671                 break ;
672 
673             case GB_LOG1P_opcode :   // z = log1P (x)
674 
675                 switch (xcode)
676                 {
677                     case GB_FP32_code    : op = GxB_LOG1P_FP32   ; break ;
678                     case GB_FP64_code    : op = GxB_LOG1P_FP64   ; break ;
679                     case GB_FC32_code    : op = GxB_LOG1P_FC32   ; break ;
680                     case GB_FC64_code    : op = GxB_LOG1P_FC64   ; break ;
681                     default              :
682                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
683                         return (false) ;
684                 }
685                 break ;
686 
687             case GB_LOG2_opcode :    // z = log2 (x)
688 
689                 switch (xcode)
690                 {
691                     case GB_FP32_code    : op = GxB_LOG2_FP32   ; break ;
692                     case GB_FP64_code    : op = GxB_LOG2_FP64   ; break ;
693                     case GB_FC32_code    : op = GxB_LOG2_FC32   ; break ;
694                     case GB_FC64_code    : op = GxB_LOG2_FC64   ; break ;
695                     default              :
696                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
697                         return (false) ;
698                 }
699                 break ;
700 
701     //--------------------------------------------------------------------------
702     // unary operators for real floating-point types
703     //--------------------------------------------------------------------------
704 
705             case GB_LGAMMA_opcode :  // z = lgamma (x)
706 
707                 switch (xcode)
708                 {
709                     case GB_FP32_code    : op = GxB_LGAMMA_FP32   ; break ;
710                     case GB_FP64_code    : op = GxB_LGAMMA_FP64   ; break ;
711                     default              :
712                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
713                         return (false) ;
714                 }
715                 break ;
716 
717             case GB_TGAMMA_opcode :  // z = tgamma (x)
718 
719                 switch (xcode)
720                 {
721                     case GB_FP32_code    : op = GxB_TGAMMA_FP32   ; break ;
722                     case GB_FP64_code    : op = GxB_TGAMMA_FP64   ; break ;
723                     default              :
724                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
725                         return (false) ;
726                 }
727                 break ;
728 
729             case GB_ERF_opcode :     // z = erf (x)
730 
731                 switch (xcode)
732                 {
733                     case GB_FP32_code    : op = GxB_ERF_FP32   ; break ;
734                     case GB_FP64_code    : op = GxB_ERF_FP64   ; break ;
735                     default              :
736                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
737                         return (false) ;
738                 }
739                 break ;
740 
741             case GB_ERFC_opcode :    // z = erfc (x)
742 
743                 switch (xcode)
744                 {
745                     case GB_FP32_code    : op = GxB_ERFC_FP32   ; break ;
746                     case GB_FP64_code    : op = GxB_ERFC_FP64   ; break ;
747                     default              :
748                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
749                         return (false) ;
750                 }
751                 break ;
752 
753             case GB_FREXPX_opcode :  // z = frexpx (x), mantissa from frexp
754 
755                 switch (xcode)
756                 {
757                     case GB_FP32_code    : op = GxB_FREXPX_FP32   ; break ;
758                     case GB_FP64_code    : op = GxB_FREXPX_FP64   ; break ;
759                     default              :
760                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
761                         return (false) ;
762                 }
763                 break ;
764 
765             case GB_FREXPE_opcode :  // z = frexpe (x), exponent from frexp
766 
767                 switch (xcode)
768                 {
769                     case GB_FP32_code    : op = GxB_FREXPE_FP32   ; break ;
770                     case GB_FP64_code    : op = GxB_FREXPE_FP64   ; break ;
771                     default              :
772                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
773                         return (false) ;
774                 }
775                 break ;
776 
777 
778     //--------------------------------------------------------------------------
779     // unary operators for complex types only
780     //--------------------------------------------------------------------------
781 
782             case GB_CONJ_opcode :    // z = conj (x)
783 
784                 switch (xcode)
785                 {
786                     case GB_FC32_code    : op = GxB_CONJ_FC32   ; break ;
787                     case GB_FC64_code    : op = GxB_CONJ_FC64   ; break ;
788                     default              :
789                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
790                         return (false) ;
791                 }
792                 break ;
793 
794     //--------------------------------------------------------------------------
795     // unary operators where z is real and x is complex
796     //--------------------------------------------------------------------------
797 
798             case GB_CREAL_opcode :   // z = creal (x)
799 
800                 switch (xcode)
801                 {
802                     case GB_FC32_code    : op = GxB_CREAL_FC32   ; break ;
803                     case GB_FC64_code    : op = GxB_CREAL_FC64   ; break ;
804                     default              :
805                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
806                         return (false) ;
807                 }
808                 break ;
809 
810             case GB_CIMAG_opcode :   // z = cimag (x)
811 
812                 switch (xcode)
813                 {
814                     case GB_FC32_code    : op = GxB_CIMAG_FC32   ; break ;
815                     case GB_FC64_code    : op = GxB_CIMAG_FC64   ; break ;
816                     default              :
817                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
818                         return (false) ;
819                 }
820                 break ;
821 
822             case GB_CARG_opcode :    // z = carg (x)
823 
824                 switch (xcode)
825                 {
826                     case GB_FC32_code    : op = GxB_CARG_FC32   ; break ;
827                     case GB_FC64_code    : op = GxB_CARG_FC64   ; break ;
828                     default              :
829                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
830                         return (false) ;
831                 }
832                 break ;
833 
834     //--------------------------------------------------------------------------
835     // unary operators where z is bool and x is any floating-point type
836     //--------------------------------------------------------------------------
837 
838             case GB_ISINF_opcode :   // z = isinf (x)
839 
840                 switch (xcode)
841                 {
842                     case GB_FP32_code    : op = GxB_ISINF_FP32   ; break ;
843                     case GB_FP64_code    : op = GxB_ISINF_FP64   ; break ;
844                     case GB_FC32_code    : op = GxB_ISINF_FC32   ; break ;
845                     case GB_FC64_code    : op = GxB_ISINF_FC64   ; break ;
846                     default              :
847                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
848                         return (false) ;
849                 }
850                 break ;
851 
852             case GB_ISNAN_opcode :   // z = isnan (x)
853 
854                 switch (xcode)
855                 {
856                     case GB_FP32_code    : op = GxB_ISNAN_FP32   ; break ;
857                     case GB_FP64_code    : op = GxB_ISNAN_FP64   ; break ;
858                     case GB_FC32_code    : op = GxB_ISNAN_FC32   ; break ;
859                     case GB_FC64_code    : op = GxB_ISNAN_FC64   ; break ;
860                     default              :
861                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
862                         return (false) ;
863                 }
864                 break ;
865 
866             case GB_ISFINITE_opcode: // z = isfinite (x)
867 
868                 switch (xcode)
869                 {
870                     case GB_FP32_code    : op = GxB_ISFINITE_FP32   ; break ;
871                     case GB_FP64_code    : op = GxB_ISFINITE_FP64   ; break ;
872                     case GB_FC32_code    : op = GxB_ISFINITE_FC32   ; break ;
873                     case GB_FC64_code    : op = GxB_ISFINITE_FC64   ; break ;
874                     default              :
875                         mexWarnMsgIdAndTxt ("GB:warn","unknown operator") ;
876                         return (false) ;
877                 }
878                 break ;
879 
880     //--------------------------------------------------------------------------
881     // positional ops
882     //--------------------------------------------------------------------------
883 
884             case GB_POSITIONI_opcode  : op = is64 ? GxB_POSITIONI_INT64  : GxB_POSITIONI_INT32  ; break ;
885             case GB_POSITIONI1_opcode : op = is64 ? GxB_POSITIONI1_INT64 : GxB_POSITIONI1_INT32 ; break ;
886             case GB_POSITIONJ_opcode  : op = is64 ? GxB_POSITIONJ_INT64  : GxB_POSITIONJ_INT32  ; break ;
887             case GB_POSITIONJ1_opcode : op = is64 ? GxB_POSITIONJ1_INT64 : GxB_POSITIONJ1_INT32 ; break ;
888 
889     //--------------------------------------------------------------------------
890 
891             default :
892                 mexWarnMsgIdAndTxt ("GB:warn","unknown unary operator") ;
893                 return (false) ;
894         }
895     }
896 
897     //--------------------------------------------------------------------------
898     // return result
899     //--------------------------------------------------------------------------
900 
901     // return the unary operator to the caller
902     ASSERT_UNARYOP_OK (op, "got unary op", GB0) ;
903     (*op_handle) = op ;
904     return (true) ;
905 }
906 
907