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