1 //------------------------------------------------------------------------------
2 // GB_ops_template.h: define the unary and binary functions and operators
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 // This file is #include'd many times in GB.h to define the unary and binary
11 // functions.
12 
13 #define GB_UNOP_STRUCT(op,xtype) \
14     GB_PUBLIC struct GB_UnaryOp_opaque GB_OPAQUE (GB_EVAL3 (op, _, xtype)) ;
15 
16 #define GB_BINOP_STRUCT(op,xtype) \
17     GB_PUBLIC struct GB_BinaryOp_opaque GB_OPAQUE (GB_EVAL3 (op, _, xtype)) ;
18 
19 //------------------------------------------------------------------------------
20 // z = one (x)
21 //------------------------------------------------------------------------------
22 
23 GB_UNOP_STRUCT (ONE,GB_XTYPE) ;
GB_FUNC(ONE)24 inline void GB_FUNC (ONE) (GB_TYPE *z, const GB_TYPE *x)
25 {
26     #if defined ( GB_FLOAT_COMPLEX )
27     (*z) = GxB_CMPLXF (1,0) ;
28     #elif defined ( GB_DOUBLE_COMPLEX )
29     (*z) = GxB_CMPLX (1,0) ;
30     #else
31     (*z) = ((GB_TYPE) 1) ;
32     #endif
33 }
34 
35 //------------------------------------------------------------------------------
36 // z = identity (x)
37 //------------------------------------------------------------------------------
38 
39 GB_UNOP_STRUCT (IDENTITY, GB_XTYPE) ;
GB_FUNC(IDENTITY)40 inline void GB_FUNC (IDENTITY) (GB_TYPE *z, const GB_TYPE *x)
41 {
42     (*z) = (*x) ;
43 }
44 
45 //------------------------------------------------------------------------------
46 // z = ainv (x)
47 //------------------------------------------------------------------------------
48 
49 GB_UNOP_STRUCT (AINV, GB_XTYPE) ;
GB_FUNC(AINV)50 inline void GB_FUNC (AINV) (GB_TYPE *z, const GB_TYPE *x)
51 {
52     #if defined ( GB_FLOAT_COMPLEX )
53         (*z) = GB_FC32_ainv (*x) ;
54     #elif defined ( GB_DOUBLE_COMPLEX )
55         (*z) = GB_FC64_ainv (*x) ;
56     #elif defined ( GB_BOOLEAN )
57         (*z) = (*x) ;
58     #else
59         // integer (signed or unsigned).  unsigned int remains unsigned.
60         (*z) = -(*x) ;
61     #endif
62 }
63 
64 //------------------------------------------------------------------------------
65 // z = minv (x)
66 //------------------------------------------------------------------------------
67 
68 GB_UNOP_STRUCT (MINV, GB_XTYPE) ;
GB_FUNC(MINV)69 inline void GB_FUNC (MINV) (GB_TYPE *z, const GB_TYPE *x)
70 {
71     #if defined ( GB_BOOLEAN )
72         (*z) = true ;
73     #elif defined ( GB_SIGNED_INT )
74         (*z) = GB_IMINV_SIGNED ((*x), GB_BITS) ;
75     #elif defined ( GB_UNSIGNED_INT )
76         (*z) = GB_IMINV_UNSIGNED ((*x), GB_BITS) ;
77     #elif defined ( GB_FLOAT )
78         (*z) = 1 / (*x) ;
79     #elif defined ( GB_DOUBLE )
80         (*z) = 1 / (*x) ;
81     #elif defined ( GB_FLOAT_COMPLEX )
82         (*z) = GB_FC32_minv (*x) ;
83     #elif defined ( GB_DOUBLE_COMPLEX )
84         (*z) = GB_FC64_minv (*x) ;
85     #endif
86 }
87 
88 //------------------------------------------------------------------------------
89 // z = abs (x)
90 //------------------------------------------------------------------------------
91 
92 GB_UNOP_STRUCT (ABS, GB_XTYPE) ;
93 
94 #if defined ( GB_REAL )
95 
96     // GrB_ABS_* for non-complex types
GB_FUNC(ABS)97     inline void GB_FUNC (ABS) (GB_TYPE *z, const GB_TYPE *x)
98     {
99         #if defined ( GB_BOOLEAN )
100             (*z) = (*x) ;
101         #elif defined ( GB_SIGNED_INT )
102             (*z) = GB_IABS ((*x)) ;
103         #elif defined ( GB_UNSIGNED_INT )
104             (*z) = (*x) ;
105         #elif defined ( GB_FLOAT )
106             (*z) = fabsf (*x) ;
107         #elif defined ( GB_DOUBLE )
108             (*z) = fabs (*x) ;
109         #endif
110     }
111 
112 #else
113 
114     // GxB_ABS_FC* for complex types
115     #if defined ( GB_FLOAT_COMPLEX )
GB_FUNC(ABS)116         inline void GB_FUNC (ABS) (float *z, const GB_TYPE *x)
117         {
118             (*z) = cabsf (*x) ;
119         }
120     #else
GB_FUNC(ABS)121         inline void GB_FUNC (ABS) (double *z, const GB_TYPE *x)
122         {
123             (*z) = cabs (*x) ;
124         }
125     #endif
126 
127 #endif
128 
129 //------------------------------------------------------------------------------
130 // z = lnot (x), for real types only
131 //------------------------------------------------------------------------------
132 
133 #if defined ( GB_REAL )
134 
135     GB_UNOP_STRUCT (LNOT, GB_XTYPE) ;
GB_FUNC(LNOT)136     inline void GB_FUNC (LNOT) (GB_TYPE *z, const GB_TYPE *x)
137     {
138         #if defined ( GB_BOOLEAN )
139             (*z) = ! (*x) ;
140         #else
141             (*z) = ! ((*x) != 0) ;
142         #endif
143     }
144 
145 #endif
146 
147 //------------------------------------------------------------------------------
148 // z = bnot (x), bitwise complement, for integer types only
149 //------------------------------------------------------------------------------
150 
151 #if defined ( GB_SIGNED_INT ) || defined ( GB_UNSIGNED_INT )
152 
153     GB_UNOP_STRUCT (BNOT, GB_XTYPE) ;
GB_FUNC(BNOT)154     inline void GB_FUNC (BNOT) (GB_TYPE *z, const GB_TYPE *x)
155     {
156         (*z) = ~ (*x) ;
157     }
158 
159 #endif
160 
161 //------------------------------------------------------------------------------
162 // z = frexpx (x) and z = frexpe (x)
163 //------------------------------------------------------------------------------
164 
165 #if defined ( GB_FLOAT )
166 
167     GB_UNOP_STRUCT (FREXPX, GB_XTYPE) ;
GB_FUNC(FREXPX)168     inline void GB_FUNC (FREXPX) (float *z, const float *x)
169     {
170         (*z) = GB_frexpxf (*x) ;
171     }
172 
173     GB_UNOP_STRUCT (FREXPE, GB_XTYPE) ;
GB_FUNC(FREXPE)174     inline void GB_FUNC (FREXPE) (float *z, const float *x)
175     {
176         (*z) = GB_frexpef (*x) ;
177     }
178 
179 #elif defined ( GB_DOUBLE )
180 
181     GB_UNOP_STRUCT (FREXPX, GB_XTYPE) ;
GB_FUNC(FREXPX)182     inline void GB_FUNC (FREXPX) (double *z, const double *x)
183     {
184         (*z) = GB_frexpx (*x) ;
185     }
186 
187     GB_UNOP_STRUCT (FREXPE, GB_XTYPE) ;
GB_FUNC(FREXPE)188     inline void GB_FUNC (FREXPE) (double *z, const double *x)
189     {
190         (*z) = GB_frexpe (*x) ;
191     }
192 
193 #endif
194 
195 //------------------------------------------------------------------------------
196 // unary operators for floating-point types
197 //------------------------------------------------------------------------------
198 
199 // For these operators, the input and output types are the same.
200 
201 #undef  GB_OP
202 #define GB_OP(op,func)                                          \
203     GB_UNOP_STRUCT (op, GB_XTYPE) ;                             \
204     inline void GB_FUNC (op) (GB_TYPE *z, const GB_TYPE *x)     \
205     {                                                           \
206         (*z) = func (*x) ;                                      \
207     }
208 
209 #if defined ( GB_FLOAT )
210 
211     //--------------------------------------------------------------------------
212     // float
213     //--------------------------------------------------------------------------
214 
GB_OP(SQRT,sqrtf)215     GB_OP (SQRT  , sqrtf   )
216     GB_OP (LOG   , logf    )
217     GB_OP (EXP   , expf    )
218 
219     GB_OP (SIN   , sinf    )
220     GB_OP (COS   , cosf    )
221     GB_OP (TAN   , tanf    )
222 
223     GB_OP (ASIN  , asinf   )
224     GB_OP (ACOS  , acosf   )
225     GB_OP (ATAN  , atanf   )
226 
227     GB_OP (SINH  , sinhf   )
228     GB_OP (COSH  , coshf   )
229     GB_OP (TANH  , tanhf   )
230 
231     GB_OP (ASINH , asinhf  )
232     GB_OP (ACOSH , acoshf  )
233     GB_OP (ATANH , atanhf  )
234 
235     GB_OP (SIGNUM, GB_signumf )
236     GB_OP (CEIL  , ceilf   )
237     GB_OP (FLOOR , floorf  )
238     GB_OP (ROUND , roundf  )
239     GB_OP (TRUNC , truncf  )
240 
241     GB_OP (EXP2  , exp2f   )
242     GB_OP (EXPM1 , expm1f  )
243     GB_OP (LOG10 , log10f  )
244     GB_OP (LOG1P , log1pf  )
245     GB_OP (LOG2  , log2f   )
246 
247     // real only
248     GB_OP (LGAMMA, lgammaf )
249     GB_OP (TGAMMA, tgammaf )
250     GB_OP (ERF   , erff    )
251     GB_OP (ERFC  , erfcf   )
252 
253 #elif defined ( GB_DOUBLE )
254 
255     //--------------------------------------------------------------------------
256     // double
257     //--------------------------------------------------------------------------
258 
259     GB_OP (SQRT  , sqrt    )
260     GB_OP (LOG   , log     )
261     GB_OP (EXP   , exp     )
262 
263     GB_OP (SIN   , sin     )
264     GB_OP (COS   , cos     )
265     GB_OP (TAN   , tan     )
266 
267     GB_OP (ASIN  , asin    )
268     GB_OP (ACOS  , acos    )
269     GB_OP (ATAN  , atan    )
270 
271     GB_OP (SINH  , sinh    )
272     GB_OP (COSH  , cosh    )
273     GB_OP (TANH  , tanh    )
274 
275     GB_OP (ASINH , asinh   )
276     GB_OP (ACOSH , acosh   )
277     GB_OP (ATANH , atanh   )
278 
279     GB_OP (SIGNUM, GB_signum )
280     GB_OP (CEIL  , ceil    )
281     GB_OP (FLOOR , floor   )
282     GB_OP (ROUND , round   )
283     GB_OP (TRUNC , trunc   )
284 
285     GB_OP (EXP2  , exp2    )
286     GB_OP (EXPM1 , expm1   )
287     GB_OP (LOG10 , log10   )
288     GB_OP (LOG1P , log1p   )
289     GB_OP (LOG2  , log2    )
290 
291     // real only
292     GB_OP (LGAMMA, lgamma )
293     GB_OP (TGAMMA, tgamma )
294     GB_OP (ERF   , erf    )
295     GB_OP (ERFC  , erfc   )
296 
297 #elif defined ( GB_FLOAT_COMPLEX )
298 
299     //--------------------------------------------------------------------------
300     // float complex
301     //--------------------------------------------------------------------------
302 
303     GB_OP (SQRT  , csqrtf   )
304     GB_OP (LOG   , clogf    )
305     GB_OP (EXP   , cexpf    )
306 
307     GB_OP (SIN   , csinf    )
308     GB_OP (COS   , ccosf    )
309     GB_OP (TAN   , ctanf    )
310 
311     GB_OP (ASIN  , casinf   )
312     GB_OP (ACOS  , cacosf   )
313     GB_OP (ATAN  , catanf   )
314 
315     GB_OP (SINH  , csinhf   )
316     GB_OP (COSH  , ccoshf   )
317     GB_OP (TANH  , ctanhf   )
318 
319     GB_OP (ASINH , casinhf  )
320     GB_OP (ACOSH , cacoshf  )
321     GB_OP (ATANH , catanhf  )
322 
323     GB_OP (SIGNUM, GB_csignumf )
324     GB_OP (CEIL  , GB_cceilf   )
325     GB_OP (FLOOR , GB_cfloorf  )
326     GB_OP (ROUND , GB_croundf  )
327     GB_OP (TRUNC , GB_ctruncf  )
328 
329     GB_OP (EXP2  , GB_cexp2f   )
330     GB_OP (EXPM1 , GB_cexpm1f  )
331     GB_OP (LOG10 , GB_clog10f  )
332     GB_OP (LOG1P , GB_clog1pf  )
333     GB_OP (LOG2  , GB_clog2f   )
334 
335     // complex only
336     GB_OP (CONJ  , conjf       )
337 
338 #elif defined ( GB_DOUBLE_COMPLEX )
339 
340     //--------------------------------------------------------------------------
341     // double complex
342     //--------------------------------------------------------------------------
343 
344     GB_OP (SQRT  , csqrt    )
345     GB_OP (LOG   , clog     )
346     GB_OP (EXP   , cexp     )
347 
348     GB_OP (SIN   , csin     )
349     GB_OP (COS   , ccos     )
350     GB_OP (TAN   , ctan     )
351 
352     GB_OP (ASIN  , casin    )
353     GB_OP (ACOS  , cacos    )
354     GB_OP (ATAN  , catan    )
355 
356     GB_OP (SINH  , csinh    )
357     GB_OP (COSH  , ccosh    )
358     GB_OP (TANH  , ctanh    )
359 
360     GB_OP (ASINH , casinh   )
361     GB_OP (ACOSH , cacosh   )
362     GB_OP (ATANH , catanh   )
363 
364     GB_OP (SIGNUM, GB_csignum  )
365     GB_OP (CEIL  , GB_cceil    )
366     GB_OP (FLOOR , GB_cfloor   )
367     GB_OP (ROUND , GB_cround   )
368     GB_OP (TRUNC , GB_ctrunc   )
369 
370     GB_OP (EXP2  , GB_cexp2    )
371     GB_OP (EXPM1 , GB_cexpm1   )
372     GB_OP (LOG10 , GB_clog10   )
373     GB_OP (LOG1P , GB_clog1p   )
374     GB_OP (LOG2  , GB_clog2    )
375 
376     // complex only
377     GB_OP (CONJ  , conj        )
378 
379 #endif
380 
381 //------------------------------------------------------------------------------
382 // unary operators z=f(x) where z and x have different types
383 //------------------------------------------------------------------------------
384 
385 // x is float, double, float complex, or double complex
386 
387 #undef  GB_OP
388 #define GB_OP(op,expression,z_t,x_t)                        \
389     GB_UNOP_STRUCT(op, GB_XTYPE) ;                          \
390     inline void GB_FUNC (op) (z_t *z, const x_t *x)         \
391     {                                                       \
392         (*z) = expression ;                                 \
393     }
394 
395 #if defined ( GB_FLOAT )
396 
397     GB_OP (ISINF    , (isinf (*x))    , bool, float)
398     GB_OP (ISNAN    , (isnan (*x))    , bool, float)
399     GB_OP (ISFINITE , (isfinite (*x)) , bool, float)
400 
401 #elif defined ( GB_DOUBLE )
402 
403     GB_OP (ISINF    , (isinf (*x))    , bool, double)
404     GB_OP (ISNAN    , (isnan (*x))    , bool, double)
405     GB_OP (ISFINITE , (isfinite (*x)) , bool, double)
406 
407 #elif defined ( GB_FLOAT_COMPLEX )
408 
409     GB_OP (ISINF    , GB_cisinff (*x)   , bool, GxB_FC32_t)
410     GB_OP (ISNAN    , GB_cisnanf (*x)   , bool, GxB_FC32_t)
411     GB_OP (ISFINITE , GB_cisfinitef (*x), bool, GxB_FC32_t)
412 
413     // complex only
414     GB_OP (CREAL , crealf (*x), float, GxB_FC32_t)
415     GB_OP (CIMAG , cimagf (*x), float, GxB_FC32_t)
416     GB_OP (CARG  , cargf  (*x), float, GxB_FC32_t)
417 
418 #elif defined ( GB_DOUBLE_COMPLEX )
419 
420     GB_OP (ISINF    , GB_cisinf (*x)    , bool, GxB_FC64_t)
421     GB_OP (ISNAN    , GB_cisnan  (*x)   , bool, GxB_FC64_t)
422     GB_OP (ISFINITE , GB_cisfinite (*x) , bool, GxB_FC64_t)
423 
424     // complex only
425     GB_OP (CREAL , creal (*x), double, GxB_FC64_t)
426     GB_OP (CIMAG , cimag (*x), double, GxB_FC64_t)
427     GB_OP (CARG  , carg  (*x), double, GxB_FC64_t)
428 
429 #endif
430 
431 //------------------------------------------------------------------------------
432 // binary functions z=f(x,y) where x,y,z have the same type, for all types
433 //------------------------------------------------------------------------------
434 
435 // first, second, pair, any, plus, minus, rminus, times, div, rdiv, pow
436 
437 #define GB_Z_X_Y_ARGS GB_TYPE *z, const GB_TYPE *x, const GB_TYPE *y
438 
439 inline void GB_FUNC (FIRST) (GB_Z_X_Y_ARGS)
440 {
441     (*z) = (*x) ;
442 }
443 
GB_FUNC(SECOND)444 inline void GB_FUNC (SECOND) (GB_Z_X_Y_ARGS)
445 {
446     (*z) = (*y) ;
447 }
448 
GB_FUNC(PAIR)449 inline void GB_FUNC (PAIR) (GB_Z_X_Y_ARGS)
450 {
451     #if defined ( GB_FLOAT_COMPLEX )
452         (*z) = GxB_CMPLXF (1, 0) ;
453     #elif defined ( GB_DOUBLE_COMPLEX )
454         (*z) = GxB_CMPLX (1, 0) ;
455     #else
456         (*z) = 1 ;
457     #endif
458 }
459 
GB_FUNC(ANY)460 inline void GB_FUNC (ANY) (GB_Z_X_Y_ARGS)      // same as SECOND
461 {
462     (*z) = (*y) ;
463 }
464 
GB_FUNC(PLUS)465 inline void GB_FUNC (PLUS) (GB_Z_X_Y_ARGS)
466 {
467     #if defined ( GB_FLOAT_COMPLEX )
468         (*z) = GB_FC32_add (*x,*y) ;
469     #elif defined ( GB_DOUBLE_COMPLEX )
470         (*z) = GB_FC64_add (*x,*y) ;
471     #else
472         (*z) = (*x) + (*y) ;
473     #endif
474 }
475 
GB_FUNC(MINUS)476 inline void GB_FUNC (MINUS) (GB_Z_X_Y_ARGS)
477 {
478     #if defined ( GB_FLOAT_COMPLEX )
479         (*z) = GB_FC32_minus (*x,*y) ;
480     #elif defined ( GB_DOUBLE_COMPLEX )
481         (*z) = GB_FC64_minus (*x,*y) ;
482     #else
483         (*z) = (*x) - (*y) ;
484     #endif
485 }
486 
GB_FUNC(RMINUS)487 inline void GB_FUNC (RMINUS) (GB_Z_X_Y_ARGS)
488 {
489     #if defined ( GB_FLOAT_COMPLEX )
490         (*z) = GB_FC32_minus (*y,*x) ;
491     #elif defined ( GB_DOUBLE_COMPLEX )
492         (*z) = GB_FC64_minus (*y,*x) ;
493     #else
494         (*z) = (*y) - (*x) ;
495     #endif
496 }
497 
GB_FUNC(TIMES)498 inline void GB_FUNC (TIMES) (GB_Z_X_Y_ARGS)
499 {
500     #if defined ( GB_FLOAT_COMPLEX )
501         (*z) = GB_FC32_mul (*x,*y) ;
502     #elif defined ( GB_DOUBLE_COMPLEX )
503         (*z) = GB_FC64_mul (*x,*y) ;
504     #else
505         (*z) = (*x) * (*y) ;
506     #endif
507 }
508 
GB_FUNC(DIV)509 inline void GB_FUNC (DIV) (GB_Z_X_Y_ARGS)
510 {
511     #if defined ( GB_BOOLEAN )
512         // boolean div (== first)
513         (*z) = (*x) ;
514     #elif defined ( GB_SIGNED_INT )
515         (*z) = GB_IDIV_SIGNED ((*x), (*y), GB_BITS) ;
516     #elif defined ( GB_UNSIGNED_INT )
517         (*z) = GB_IDIV_UNSIGNED ((*x), (*y), GB_BITS) ;
518     #elif defined ( GB_FLOAT ) || defined ( GB_DOUBLE )
519         (*z) = (*x) / (*y) ;
520     #elif defined ( GB_FLOAT_COMPLEX )
521         (*z) = GB_FC32_div (*x, *y) ;
522     #elif defined ( GB_DOUBLE_COMPLEX )
523         (*z) = GB_FC64_div (*x, *y) ;
524     #endif
525 }
526 
GB_FUNC(RDIV)527 inline void GB_FUNC (RDIV) (GB_Z_X_Y_ARGS)
528 {
529     #if defined ( GB_BOOLEAN )
530         // boolean rdiv (== second)
531         (*z) = (*y) ;
532     #elif defined ( GB_SIGNED_INT )
533         (*z) = GB_IDIV_SIGNED ((*y), (*x), GB_BITS) ;
534     #elif defined ( GB_UNSIGNED_INT )
535         (*z) = GB_IDIV_UNSIGNED ((*y), (*x), GB_BITS) ;
536     #elif defined ( GB_FLOAT ) || defined ( GB_DOUBLE )
537         (*z) = (*y) / (*x) ;
538     #elif defined ( GB_FLOAT_COMPLEX )
539         (*z) = GB_FC32_div (*y, *x) ;
540     #elif defined ( GB_DOUBLE_COMPLEX )
541         (*z) = GB_FC64_div (*y, *x) ;
542     #endif
543 }
544 
545 // z = pow (x,y)
GB_FUNC(POW)546 inline void GB_FUNC (POW) (GB_Z_X_Y_ARGS)
547 {
548     #if defined ( GB_BOOLEAN )
549         (*z) = (*x) || (!(*y)) ;
550     #elif defined ( GB_SIGNED_INT )
551         #if ( GB_BITS == 8)
552             (*z) = GB_pow_int8 ((*x), (*y)) ;
553         #elif ( GB_BITS == 16)
554             (*z) = GB_pow_int16 ((*x), (*y)) ;
555         #elif ( GB_BITS == 32)
556             (*z) = GB_pow_int32 ((*x), (*y)) ;
557         #elif ( GB_BITS == 64)
558             (*z) = GB_pow_int64 ((*x), (*y)) ;
559         #endif
560     #elif defined ( GB_UNSIGNED_INT )
561         #if ( GB_BITS == 8)
562             (*z) = GB_pow_uint8 ((*x), (*y)) ;
563         #elif ( GB_BITS == 16)
564             (*z) = GB_pow_uint16 ((*x), (*y)) ;
565         #elif ( GB_BITS == 32)
566             (*z) = GB_pow_uint32 ((*x), (*y)) ;
567         #elif ( GB_BITS == 64)
568             (*z) = GB_pow_uint64 ((*x), (*y)) ;
569         #endif
570     #elif defined ( GB_FLOAT )
571         (*z) = GB_powf ((*x), (*y)) ;
572     #elif defined ( GB_DOUBLE )
573         (*z) = GB_pow ((*x), (*y)) ;
574     #elif defined ( GB_FLOAT_COMPLEX )
575         (*z) = GB_cpowf ((*x), (*y)) ;
576     #elif defined ( GB_DOUBLE_COMPLEX )
577         (*z) = GB_cpow ((*x), (*y)) ;
578     #endif
579 }
580 
581 GB_BINOP_STRUCT (FIRST, GB_XTYPE) ;
582 GB_BINOP_STRUCT (SECOND, GB_XTYPE) ;
583 GB_BINOP_STRUCT (PAIR, GB_XTYPE) ;
584 GB_BINOP_STRUCT (ANY, GB_XTYPE) ;
585 GB_BINOP_STRUCT (PLUS, GB_XTYPE) ;
586 GB_BINOP_STRUCT (MINUS, GB_XTYPE) ;
587 GB_BINOP_STRUCT (RMINUS, GB_XTYPE) ;
588 GB_BINOP_STRUCT (TIMES, GB_XTYPE) ;
589 GB_BINOP_STRUCT (DIV, GB_XTYPE) ;
590 GB_BINOP_STRUCT (RDIV, GB_XTYPE) ;
591 GB_BINOP_STRUCT (POW, GB_XTYPE) ;
592 
593 //------------------------------------------------------------------------------
594 // binary operators for real types only
595 //------------------------------------------------------------------------------
596 
597 // min and max: real only, not complex
598 #if defined ( GB_REAL )
599 
600     GB_BINOP_STRUCT (MIN, GB_XTYPE) ;
GB_FUNC(MIN)601     inline void GB_FUNC (MIN) (GB_Z_X_Y_ARGS)
602     {
603         #if defined ( GB_FLOAT )
604             (*z) = fminf ((*x), (*y)) ;
605         #elif defined ( GB_DOUBLE )
606             (*z) = fmin ((*x), (*y)) ;
607         #else
608             (*z) = GB_IMIN ((*x), (*y)) ;
609         #endif
610     }
611 
612     GB_BINOP_STRUCT (MAX, GB_XTYPE) ;
GB_FUNC(MAX)613     inline void GB_FUNC (MAX) (GB_Z_X_Y_ARGS)
614     {
615         #if defined ( GB_FLOAT )
616             (*z) = fmaxf ((*x), (*y)) ;
617         #elif defined ( GB_DOUBLE )
618             (*z) = fmax ((*x), (*y)) ;
619         #else
620             (*z) = GB_IMAX ((*x), (*y)) ;
621         #endif
622     }
623 
624 #endif
625 
626 //------------------------------------------------------------------------------
627 // binary operators for integer types only
628 //------------------------------------------------------------------------------
629 
630 #if defined ( GB_SIGNED_INT ) || defined ( GB_UNSIGNED_INT )
631 
632     GB_BINOP_STRUCT (BOR, GB_XTYPE) ;
633     GB_BINOP_STRUCT (BAND, GB_XTYPE) ;
634     GB_BINOP_STRUCT (BXOR, GB_XTYPE) ;
635     GB_BINOP_STRUCT (BXNOR, GB_XTYPE) ;
636 
GB_FUNC(BOR)637     inline void GB_FUNC (BOR  ) (GB_Z_X_Y_ARGS) { (*z) = (*x) | (*y) ; }
GB_FUNC(BAND)638     inline void GB_FUNC (BAND ) (GB_Z_X_Y_ARGS) { (*z) = (*x) & (*y) ; }
GB_FUNC(BXOR)639     inline void GB_FUNC (BXOR ) (GB_Z_X_Y_ARGS) { (*z) = (*x) ^ (*y) ; }
GB_FUNC(BXNOR)640     inline void GB_FUNC (BXNOR) (GB_Z_X_Y_ARGS) { (*z) = ~((*x) ^ (*y)) ; }
641 
642     GB_BINOP_STRUCT (BGET, GB_XTYPE) ;
643     GB_BINOP_STRUCT (BSET, GB_XTYPE) ;
644     GB_BINOP_STRUCT (BCLR, GB_XTYPE) ;
645     GB_BINOP_STRUCT (BSHIFT, GB_XTYPE) ;
646 
GB_FUNC(BGET)647     inline void GB_FUNC (BGET) (GB_Z_X_Y_ARGS)
648     {
649         // bitget (x,y) returns a single bit from x, as 0 or 1, whose position
650         // is given by y.  y = 1 is the least significant bit, and y = GB_BITS
651         // (64 for uint64) is the most significant bit. If y is outside this
652         // range, the result is zero.
653         GB_TYPE k = (*y) ;
654 
655         #if defined ( GB_SIGNED_INT )
656 
657             #if ( GB_BITS == 8)
658                 (*z) = GB_BITGET ((*x), k, int8_t,   8) ;
659             #elif ( GB_BITS == 16)
660                 (*z) = GB_BITGET ((*x), k, int16_t, 16) ;
661             #elif ( GB_BITS == 32)
662                 (*z) = GB_BITGET ((*x), k, int32_t, 32) ;
663             #elif ( GB_BITS == 64)
664                 (*z) = GB_BITGET ((*x), k, int64_t, 64) ;
665             #endif
666 
667         #elif defined ( GB_UNSIGNED_INT )
668 
669             #if ( GB_BITS == 8)
670                 (*z) = GB_BITGET ((*x), k, uint8_t,   8) ;
671             #elif ( GB_BITS == 16)
672                 (*z) = GB_BITGET ((*x), k, uint16_t, 16) ;
673             #elif ( GB_BITS == 32)
674                 (*z) = GB_BITGET ((*x), k, uint32_t, 32) ;
675             #elif ( GB_BITS == 64)
676                 (*z) = GB_BITGET ((*x), k, uint64_t, 64) ;
677             #endif
678 
679         #endif
680     }
681 
GB_FUNC(BSET)682     inline void GB_FUNC (BSET) (GB_Z_X_Y_ARGS)
683     {
684         // bitset (x,y) returns x modified by setting a bit from x to 1, whose
685         // position is given by y.  If y is in the range 1 to GB_BITS, then y
686         // gives the position of the bit to set.  If y is outside the range 1
687         // to GB_BITS, then z = x is returned, unmodified.
688         GB_TYPE k = (*y) ;
689 
690         #if defined ( GB_SIGNED_INT )
691 
692             #if ( GB_BITS == 8)
693                 (*z) = GB_BITSET ((*x), k, int8_t,   8) ;
694             #elif ( GB_BITS == 16)
695                 (*z) = GB_BITSET ((*x), k, int16_t, 16) ;
696             #elif ( GB_BITS == 32)
697                 (*z) = GB_BITSET ((*x), k, int32_t, 32) ;
698             #elif ( GB_BITS == 64)
699                 (*z) = GB_BITSET ((*x), k, int64_t, 64) ;
700             #endif
701 
702         #elif defined ( GB_UNSIGNED_INT )
703 
704             #if ( GB_BITS == 8)
705                 (*z) = GB_BITSET ((*x), k, uint8_t,   8) ;
706             #elif ( GB_BITS == 16)
707                 (*z) = GB_BITSET ((*x), k, uint16_t, 16) ;
708             #elif ( GB_BITS == 32)
709                 (*z) = GB_BITSET ((*x), k, uint32_t, 32) ;
710             #elif ( GB_BITS == 64)
711                 (*z) = GB_BITSET ((*x), k, uint64_t, 64) ;
712             #endif
713 
714         #endif
715     }
716 
GB_FUNC(BCLR)717     inline void GB_FUNC (BCLR) (GB_Z_X_Y_ARGS)
718     {
719         // bitclr (x,y) returns x modified by setting a bit from x to 0, whose
720         // position is given by y.  If y is in the range 1 to GB_BITS, then y
721         // gives the position of the bit to clear.  If y is outside the range 1
722         // to GB_BITS, then z = x is returned, unmodified.
723         GB_TYPE k = (*y) ;
724 
725         #if defined ( GB_SIGNED_INT )
726 
727             #if ( GB_BITS == 8)
728                 (*z) = GB_BITCLR ((*x), k, int8_t,   8) ;
729             #elif ( GB_BITS == 16)
730                 (*z) = GB_BITCLR ((*x), k, int16_t, 16) ;
731             #elif ( GB_BITS == 32)
732                 (*z) = GB_BITCLR ((*x), k, int32_t, 32) ;
733             #elif ( GB_BITS == 64)
734                 (*z) = GB_BITCLR ((*x), k, int64_t, 64) ;
735             #endif
736 
737         #elif defined ( GB_UNSIGNED_INT )
738 
739             #if ( GB_BITS == 8)
740                 (*z) = GB_BITCLR ((*x), k, uint8_t,   8) ;
741             #elif ( GB_BITS == 16)
742                 (*z) = GB_BITCLR ((*x), k, uint16_t, 16) ;
743             #elif ( GB_BITS == 32)
744                 (*z) = GB_BITCLR ((*x), k, uint32_t, 32) ;
745             #elif ( GB_BITS == 64)
746                 (*z) = GB_BITCLR ((*x), k, uint64_t, 64) ;
747             #endif
748 
749         #endif
750     }
751 
752 
753     // z = bitshift (x,y)
GB_FUNC(BSHIFT)754     inline void GB_FUNC (BSHIFT) (GB_TYPE *z, const GB_TYPE *x, const int8_t *y)
755     {
756         // bitshift (x,k) shifts x to the left by k bits if k > 0, and the
757         // right by -k bits if k < 0.
758         int8_t k = (int8_t) (*y) ;
759 
760         #if defined ( GB_SIGNED_INT )
761 
762             #if ( GB_BITS == 8)
763                 (*z) = GB_bitshift_int8 ((*x), k) ;
764             #elif ( GB_BITS == 16)
765                 (*z) = GB_bitshift_int16 ((*x), k) ;
766             #elif ( GB_BITS == 32)
767                 (*z) = GB_bitshift_int32 ((*x), k) ;
768             #elif ( GB_BITS == 64)
769                 (*z) = GB_bitshift_int64 ((*x), k) ;
770             #endif
771 
772         #elif defined ( GB_UNSIGNED_INT )
773 
774             #if ( GB_BITS == 8)
775                 (*z) = GB_bitshift_uint8 ((*x), k) ;
776             #elif ( GB_BITS == 16)
777                 (*z) = GB_bitshift_uint16 ((*x), k) ;
778             #elif ( GB_BITS == 32)
779                 (*z) = GB_bitshift_uint32 ((*x), k) ;
780             #elif ( GB_BITS == 64)
781                 (*z) = GB_bitshift_uint64 ((*x), k) ;
782             #endif
783 
784         #endif
785     }
786 
787 #endif
788 
789 //------------------------------------------------------------------------------
790 // binary operators for real floating-point inputs only
791 //------------------------------------------------------------------------------
792 
793 #if defined ( GB_FLOAT )
794 
GB_FUNC(ATAN2)795     inline void GB_FUNC (ATAN2) (GB_Z_X_Y_ARGS) { (*z) = atan2f ((*x),(*y)) ; }
GB_FUNC(HYPOT)796     inline void GB_FUNC (HYPOT) (GB_Z_X_Y_ARGS) { (*z) = hypotf ((*x),(*y)) ; }
GB_FUNC(FMOD)797     inline void GB_FUNC (FMOD)  (GB_Z_X_Y_ARGS) { (*z) = fmodf  ((*x),(*y)) ; }
798 
GB_FUNC(REMAINDER)799     inline void GB_FUNC (REMAINDER) (GB_Z_X_Y_ARGS)
800     {
801         (*z) = remainderf ((*x),(*y)) ;
802     }
GB_FUNC(COPYSIGN)803     inline void GB_FUNC (COPYSIGN) (GB_Z_X_Y_ARGS)
804     {
805         (*z) = copysignf ((*x),(*y)) ;
806     }
GB_FUNC(LDEXP)807     inline void GB_FUNC (LDEXP) (GB_Z_X_Y_ARGS)
808     {
809         (*z) = ldexpf ((*x), (int) truncf (*y)) ;
810     }
GB_FUNC(CMPLX)811     inline void GB_FUNC (CMPLX) (GxB_FC32_t *z, const float *x, const float *y)
812     {
813         (*z) = GxB_CMPLXF ((*x),(*y)) ;
814     }
815 
816 #elif defined ( GB_DOUBLE )
817 
GB_FUNC(ATAN2)818     inline void GB_FUNC (ATAN2) (GB_Z_X_Y_ARGS) { (*z) = atan2 ((*x),(*y)) ; }
GB_FUNC(HYPOT)819     inline void GB_FUNC (HYPOT) (GB_Z_X_Y_ARGS) { (*z) = hypot ((*x),(*y)) ; }
GB_FUNC(FMOD)820     inline void GB_FUNC (FMOD)  (GB_Z_X_Y_ARGS) { (*z) = fmod  ((*x),(*y)) ; }
821 
GB_FUNC(REMAINDER)822     inline void GB_FUNC (REMAINDER) (GB_Z_X_Y_ARGS)
823     {
824         (*z) = remainder ((*x),(*y)) ;
825     }
GB_FUNC(COPYSIGN)826     inline void GB_FUNC (COPYSIGN) (GB_Z_X_Y_ARGS)
827     {
828         (*z) = copysign ((*x),(*y)) ;
829     }
GB_FUNC(LDEXP)830     inline void GB_FUNC (LDEXP) (GB_Z_X_Y_ARGS)
831     {
832         (*z) = ldexp ((*x), (int) trunc (*y)) ;
833     }
GB_FUNC(CMPLX)834     inline void GB_FUNC (CMPLX) (GxB_FC64_t *z,
835         const double *x, const double *y)
836     {
837         (*z) = GxB_CMPLX ((*x),(*y)) ;
838     }
839 
840 #endif
841 
842 #if defined (GB_FLOAT) || defined (GB_DOUBLE)
843 
844     GB_BINOP_STRUCT (ATAN2, GB_XTYPE) ;
845     GB_BINOP_STRUCT (HYPOT, GB_XTYPE) ;
846     GB_BINOP_STRUCT (FMOD, GB_XTYPE) ;
847     GB_BINOP_STRUCT (REMAINDER, GB_XTYPE) ;
848     GB_BINOP_STRUCT (COPYSIGN, GB_XTYPE) ;
849     GB_BINOP_STRUCT (LDEXP, GB_XTYPE) ;
850     GB_BINOP_STRUCT (CMPLX, GB_XTYPE) ;
851 
852 #endif
853 
854 //------------------------------------------------------------------------------
855 // 6 binary comparison functions z=f(x,y), where x,y,z have the same type
856 //------------------------------------------------------------------------------
857 
858 // iseq and isne: all 13 types, including complex types.
859 // isgt, islt, isge, isle: 11 real types only.
860 
861 GB_BINOP_STRUCT (ISEQ, GB_XTYPE) ;
GB_FUNC(ISEQ)862 inline void GB_FUNC (ISEQ) (GB_Z_X_Y_ARGS)
863 {
864     #if defined ( GB_FLOAT_COMPLEX )
865     (*z) = GB_FC32_iseq (*x, *y) ;
866     #elif defined ( GB_DOUBLE_COMPLEX )
867     (*z) = GB_FC64_iseq (*x, *y) ;
868     #else
869     (*z) = (GB_TYPE) ((*x) == (*y)) ;
870     #endif
871 }
872 
873 GB_BINOP_STRUCT (ISNE, GB_XTYPE) ;
GB_FUNC(ISNE)874 inline void GB_FUNC (ISNE) (GB_Z_X_Y_ARGS)
875 {
876     #if defined ( GB_FLOAT_COMPLEX )
877     (*z) = GB_FC32_isne (*x, *y) ;
878     #elif defined ( GB_DOUBLE_COMPLEX )
879     (*z) = GB_FC64_isne (*x, *y) ;
880     #else
881     (*z) = (GB_TYPE) ((*x) != (*y)) ;
882     #endif
883 }
884 
885 #if defined ( GB_REAL )
886 
GB_FUNC(ISGT)887     inline void GB_FUNC (ISGT) (GB_Z_X_Y_ARGS)
888     {
889         (*z) = (GB_TYPE) ((*x) >  (*y)) ;
890     }
GB_FUNC(ISLT)891     inline void GB_FUNC (ISLT) (GB_Z_X_Y_ARGS)
892     {
893         (*z) = (GB_TYPE) ((*x) <  (*y)) ;
894     }
GB_FUNC(ISGE)895     inline void GB_FUNC (ISGE) (GB_Z_X_Y_ARGS)
896     {
897         (*z) = (GB_TYPE) ((*x) >= (*y)) ;
898     }
GB_FUNC(ISLE)899     inline void GB_FUNC (ISLE) (GB_Z_X_Y_ARGS)
900     {
901         (*z) = (GB_TYPE) ((*x) <= (*y)) ;
902     }
903 
904     GB_BINOP_STRUCT (ISGT, GB_XTYPE) ;
905     GB_BINOP_STRUCT (ISLT, GB_XTYPE) ;
906     GB_BINOP_STRUCT (ISGE, GB_XTYPE) ;
907     GB_BINOP_STRUCT (ISLE, GB_XTYPE) ;
908 
909 #endif
910 
911 //------------------------------------------------------------------------------
912 // 3 boolean binary functions z=f(x,y), all x,y,z the same type, real types only
913 //------------------------------------------------------------------------------
914 
915 #if defined ( GB_REAL )
916 
917     #if defined ( GB_BOOLEAN )
918 
GB_FUNC(LOR)919         inline void GB_FUNC (LOR)  (GB_Z_X_Y_ARGS) { (*z) = ((*x) || (*y)) ; }
GB_FUNC(LAND)920         inline void GB_FUNC (LAND) (GB_Z_X_Y_ARGS) { (*z) = ((*x) && (*y)) ; }
GB_FUNC(LXOR)921         inline void GB_FUNC (LXOR) (GB_Z_X_Y_ARGS) { (*z) = ((*x) != (*y)) ; }
922 
923     #else
924 
925         // The inputs are of type T but are then implicitly converted to boolean
926         // The output z is of type T, either 1 or 0 in that type.
GB_FUNC(LOR)927         inline void GB_FUNC (LOR)  (GB_Z_X_Y_ARGS)
928         {
929             (*z) = (GB_TYPE) (((*x) != 0) || ((*y) != 0)) ;
930         }
931 
GB_FUNC(LAND)932         inline void GB_FUNC (LAND) (GB_Z_X_Y_ARGS)
933         {
934             (*z) = (GB_TYPE) (((*x) != 0) && ((*y) != 0)) ;
935         }
936 
GB_FUNC(LXOR)937         inline void GB_FUNC (LXOR) (GB_Z_X_Y_ARGS)
938         {
939             (*z) = (GB_TYPE) (((*x) != 0) != ((*y) != 0)) ;
940         }
941 
942     #endif
943 
944     GB_BINOP_STRUCT (LOR, GB_XTYPE) ;
945     GB_BINOP_STRUCT (LAND, GB_XTYPE) ;
946     GB_BINOP_STRUCT (LXOR, GB_XTYPE) ;
947 
948 #endif
949 
950 #undef GB_Z_X_Y_ARGS
951 
952 //------------------------------------------------------------------------------
953 // 6 binary functions z=f(x,y), returning bool
954 //------------------------------------------------------------------------------
955 
956 // eq, ne: for all 13 types
957 // gt, lt, ge, le: for 11 real types, not complex
958 
959 #define GB_Zbool_X_Y_ARGS bool *z, const GB_TYPE *x, const GB_TYPE *y
960 
961 GB_BINOP_STRUCT (EQ, GB_XTYPE) ;
GB_FUNC(EQ)962 inline void GB_FUNC (EQ) (GB_Zbool_X_Y_ARGS)
963 {
964     #if defined ( GB_FLOAT_COMPLEX )
965     (*z) = GB_FC32_eq (*x, *y) ;
966     #elif defined ( GB_DOUBLE_COMPLEX )
967     (*z) = GB_FC64_eq (*x, *y) ;
968     #else
969     (*z) = ((*x) == (*y)) ;
970     #endif
971 }
972 
973 GB_BINOP_STRUCT (NE, GB_XTYPE) ;
GB_FUNC(NE)974 inline void GB_FUNC (NE) (GB_Zbool_X_Y_ARGS)
975 {
976     #if defined ( GB_FLOAT_COMPLEX )
977     (*z) = GB_FC32_ne (*x, *y) ;
978     #elif defined ( GB_DOUBLE_COMPLEX )
979     (*z) = GB_FC64_ne (*x, *y) ;
980     #else
981     (*z) = ((*x) != (*y)) ;
982     #endif
983 }
984 
985 #if !defined ( GB_COMPLEX )
986 
GB_FUNC(GT)987     inline void GB_FUNC (GT) (GB_Zbool_X_Y_ARGS) { (*z) = ((*x) >  (*y)) ; }
GB_FUNC(LT)988     inline void GB_FUNC (LT) (GB_Zbool_X_Y_ARGS) { (*z) = ((*x) <  (*y)) ; }
GB_FUNC(GE)989     inline void GB_FUNC (GE) (GB_Zbool_X_Y_ARGS) { (*z) = ((*x) >= (*y)) ; }
GB_FUNC(LE)990     inline void GB_FUNC (LE) (GB_Zbool_X_Y_ARGS) { (*z) = ((*x) <= (*y)) ; }
991 
992     GB_BINOP_STRUCT (GT, GB_XTYPE) ;
993     GB_BINOP_STRUCT (LT, GB_XTYPE) ;
994     GB_BINOP_STRUCT (GE, GB_XTYPE) ;
995     GB_BINOP_STRUCT (LE, GB_XTYPE) ;
996 
997 #endif
998 
999 #undef GB_Zbool_X_Y_ARGS
1000 
1001 //------------------------------------------------------------------------------
1002 // clear macros for next use of this file
1003 //------------------------------------------------------------------------------
1004 
1005 #undef GB_TYPE
1006 #undef GB_XTYPE
1007 #undef GB_OP
1008 #undef GB_BOOLEAN
1009 #undef GB_FLOATING_POINT
1010 #undef GB_UNSIGNED_INT
1011 #undef GB_SIGNED_INT
1012 #undef GB_BITS
1013 #undef GB_REAL
1014 #undef GB_DOUBLE
1015 #undef GB_FLOAT
1016 #undef GB_DOUBLE_COMPLEX
1017 #undef GB_FLOAT_COMPLEX
1018 #undef GB_COMPLEX
1019 #undef GB_UNOP_STRUCT
1020 #undef GB_BINOP_STRUCT
1021 
1022