1 //------------------------------------------------------------------------------
2 // GraphBLAS/Demo/Source/usercomplex.c: complex numbers as a user-defined type
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 "GraphBLAS.h"
11 #undef GB_PUBLIC
12 #define GB_LIBRARY
13 #include "graphblas_demos.h"
14
15 #if defined __INTEL_COMPILER
16 #pragma warning (disable: 58 167 144 161 177 181 186 188 589 593 869 981 1418 1419 1572 1599 2259 2282 2557 2547 3280 )
17 #elif defined __GNUC__
18 #pragma GCC diagnostic ignored "-Wunused-parameter"
19 #if !defined ( __cplusplus )
20 #pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
21 #endif
22 #endif
23
24 GrB_BinaryOp Complex_first = NULL, Complex_second = NULL, Complex_min = NULL,
25 Complex_max = NULL, Complex_plus = NULL, Complex_minus = NULL,
26 Complex_times = NULL, Complex_div = NULL, Complex_rminus = NULL,
27 Complex_rdiv = NULL, Complex_pair = NULL ;
28
29 GrB_BinaryOp Complex_iseq = NULL, Complex_isne = NULL,
30 Complex_isgt = NULL, Complex_islt = NULL,
31 Complex_isge = NULL, Complex_isle = NULL ;
32
33 GrB_BinaryOp Complex_or = NULL, Complex_and = NULL, Complex_xor = NULL ;
34
35 GrB_BinaryOp Complex_eq = NULL, Complex_ne = NULL,
36 Complex_gt = NULL, Complex_lt = NULL,
37 Complex_ge = NULL, Complex_le = NULL ;
38
39 GrB_BinaryOp Complex_complex = NULL ;
40
41 GrB_UnaryOp Complex_identity = NULL, Complex_ainv = NULL, Complex_minv = NULL,
42 Complex_not = NULL, Complex_conj = NULL,
43 Complex_one = NULL, Complex_abs = NULL ;
44
45 GrB_UnaryOp Complex_real = NULL, Complex_imag = NULL,
46 Complex_cabs = NULL, Complex_angle = NULL ;
47
48 GrB_UnaryOp Complex_complex_real = NULL, Complex_complex_imag = NULL ;
49
50 GrB_Type Complex = NULL ;
51 GrB_Monoid Complex_plus_monoid = NULL, Complex_times_monoid = NULL ;
52 GrB_Semiring Complex_plus_times = NULL ;
53
54 #define ONE GxB_CMPLX(1,0)
55 #define ZERO GxB_CMPLX(0,0)
56 #define C GxB_FC64_t
57
58 #define X *x
59 #define Y *y
60 #define Z *z
61
62 #define T ONE
63 #define F ZERO
64 #define BOOL(X) (creal (X) != 0 || cimag (X) != 0)
65
66 //------------------------------------------------------------------------------
67 // binary functions, z=f(x,y), where CxC -> C
68 //------------------------------------------------------------------------------
69
70 #if GxB_STDC_VERSION >= 201112L
complex_first(C Z,const C X,const C Y)71 GB_PUBLIC void complex_first (C Z, const C X, const C Y) { Z = X ; }
complex_second(C Z,const C X,const C Y)72 GB_PUBLIC void complex_second (C Z, const C X, const C Y) { Z = Y ; }
complex_pair(C Z,const C X,const C Y)73 GB_PUBLIC void complex_pair (C Z, const C X, const C Y) { Z = ONE ; }
complex_plus(C Z,const C X,const C Y)74 GB_PUBLIC void complex_plus (C Z, const C X, const C Y) { Z = X + Y ; }
complex_minus(C Z,const C X,const C Y)75 GB_PUBLIC void complex_minus (C Z, const C X, const C Y) { Z = X - Y ; }
complex_rminus(C Z,const C X,const C Y)76 GB_PUBLIC void complex_rminus (C Z, const C X, const C Y) { Z = Y - X ; }
complex_times(C Z,const C X,const C Y)77 GB_PUBLIC void complex_times (C Z, const C X, const C Y) { Z = X * Y ; }
complex_div(C Z,const C X,const C Y)78 GB_PUBLIC void complex_div (C Z, const C X, const C Y) { Z = X / Y ; }
complex_rdiv(C Z,const C X,const C Y)79 GB_PUBLIC void complex_rdiv (C Z, const C X, const C Y) { Z = Y / X ; }
80 #endif
81
82 GB_PUBLIC
complex_min(C Z,const C X,const C Y)83 void complex_min (C Z, const C X, const C Y)
84 {
85 // min (x,y): complex number with smallest magnitude. If tied, select the
86 // one with the smallest phase angle (same as MATLAB definition).
87 // No special cases for NaNs.
88 double absx = cabs (X) ;
89 double absy = cabs (Y) ;
90 if (absx < absy)
91 {
92 Z = X ;
93 }
94 else if (absx > absy)
95 {
96 Z = Y ;
97 }
98 else
99 {
100 if (carg (X) < carg (Y))
101 {
102 Z = X ;
103 }
104 else
105 {
106 Z = Y ;
107 }
108 }
109 }
110
111 GB_PUBLIC
complex_max(C Z,const C X,const C Y)112 void complex_max (C Z, const C X, const C Y)
113 {
114 // max (x,y): complex number with largest magnitude. If tied, select the
115 // one with the largest phase angle (same as MATLAB definition).
116 // No special cases for NaNs.
117 double absx = cabs (X) ;
118 double absy = cabs (Y) ;
119 if (absx > absy)
120 {
121 Z = X ;
122 }
123 else if (absx < absy)
124 {
125 Z = Y ;
126 }
127 else
128 {
129 if (carg (X) > carg (Y))
130 {
131 Z = X ;
132 }
133 else
134 {
135 Z = Y ;
136 }
137 }
138 }
139
140 //------------------------------------------------------------------------------
141 // 6 binary functions, z=f(x,y), where CxC -> C ; (1,0) = true, (0,0) = false
142 //------------------------------------------------------------------------------
143
144 // inequality operators follow the MATLAB convention
145
146 #if GxB_STDC_VERSION >= 201112L
147 GB_PUBLIC
complex_iseq(C Z,const C X,const C Y)148 void complex_iseq (C Z, const C X, const C Y)
149 {
150 Z = (creal (X) == creal (Y) && cimag (X) == cimag (Y)) ? T : F ;
151 }
152
153 GB_PUBLIC
complex_isne(C Z,const C X,const C Y)154 void complex_isne (C Z, const C X, const C Y)
155 {
156 Z = (creal (X) != creal (Y) || cimag (X) != cimag (Y)) ? T : F ;
157 }
158 #endif
159
160 GB_PUBLIC
complex_isgt(C Z,const C X,const C Y)161 void complex_isgt (C Z, const C X, const C Y)
162 {
163 Z = (creal (X) > creal (Y)) ? T : F ;
164 }
165
166 GB_PUBLIC
complex_islt(C Z,const C X,const C Y)167 void complex_islt (C Z, const C X, const C Y)
168 {
169 Z = (creal (X) < creal (Y)) ? T : F ;
170 }
171 GB_PUBLIC
complex_isge(C Z,const C X,const C Y)172 void complex_isge (C Z, const C X, const C Y)
173 {
174 Z = (creal (X) >= creal (Y)) ? T : F ;
175 }
176 GB_PUBLIC
complex_isle(C Z,const C X,const C Y)177 void complex_isle (C Z, const C X, const C Y)
178 {
179 Z = (creal (X) <= creal (Y)) ? T : F ;
180 }
181
182 //------------------------------------------------------------------------------
183 // binary boolean functions, z=f(x,y), where CxC -> C
184 //------------------------------------------------------------------------------
185
186 GB_PUBLIC
complex_or(C Z,const C X,const C Y)187 void complex_or (C Z, const C X, const C Y)
188 {
189 Z = (BOOL (X) || BOOL (Y)) ? T : F ;
190 }
191
192 GB_PUBLIC
complex_and(C Z,const C X,const C Y)193 void complex_and (C Z, const C X, const C Y)
194 {
195 Z = (BOOL (X) && BOOL (Y)) ? T : F ;
196 }
197
198 GB_PUBLIC
complex_xor(C Z,const C X,const C Y)199 void complex_xor (C Z, const C X, const C Y)
200 {
201 Z = (BOOL (X) != BOOL (Y)) ? T : F ;
202 }
203
204 //------------------------------------------------------------------------------
205 // 6 binary functions, z=f(x,y), where CxC -> bool
206 //------------------------------------------------------------------------------
207
208 // inequality operators follow the MATLAB convention
209
210 #if GxB_STDC_VERSION >= 201112L
211 GB_PUBLIC
complex_eq(bool Z,const C X,const C Y)212 void complex_eq (bool Z, const C X, const C Y)
213 {
214 Z = (creal (X) == creal (Y) && cimag (X) == cimag (Y)) ;
215 }
216
217 GB_PUBLIC
complex_ne(bool Z,const C X,const C Y)218 void complex_ne (bool Z, const C X, const C Y)
219 {
220 Z = (creal (X) != creal (Y) || cimag (X) != cimag (Y)) ;
221 }
222 #endif
223
224 GB_PUBLIC
complex_gt(bool Z,const C X,const C Y)225 void complex_gt (bool Z, const C X, const C Y)
226 {
227 Z = (creal (X) > creal (Y)) ;
228 }
229
230 GB_PUBLIC
complex_lt(bool Z,const C X,const C Y)231 void complex_lt (bool Z, const C X, const C Y)
232 {
233 Z = (creal (X) < creal (Y)) ;
234 }
235
236 GB_PUBLIC
complex_ge(bool Z,const C X,const C Y)237 void complex_ge (bool Z, const C X, const C Y)
238 {
239 Z = (creal (X) >= creal (Y)) ;
240 }
241
242 GB_PUBLIC
complex_le(bool Z,const C X,const C Y)243 void complex_le (bool Z, const C X, const C Y)
244 {
245 Z = (creal (X) <= creal (Y)) ;
246 }
247
248 //------------------------------------------------------------------------------
249 // binary functions, z=f(x,y), where double x double -> complex
250 //------------------------------------------------------------------------------
251
252 #if GxB_STDC_VERSION >= 201112L
253 GB_PUBLIC
complex_complex(C Z,const double X,const double Y)254 void complex_complex (C Z, const double X, const double Y)
255 {
256 Z = GxB_CMPLX (X,Y) ;
257 }
258 #endif
259
260 //------------------------------------------------------------------------------
261 // unary functions, z=f(x) where C -> C
262 //------------------------------------------------------------------------------
263
264 #if GxB_STDC_VERSION >= 201112L
265 GB_PUBLIC
complex_one(C Z,const C X)266 void complex_one (C Z, const C X) { Z = ONE ; }
267 GB_PUBLIC
complex_identity(C Z,const C X)268 void complex_identity (C Z, const C X) { Z = X ; }
269 GB_PUBLIC
complex_ainv(C Z,const C X)270 void complex_ainv (C Z, const C X) { Z = -X ; }
271 GB_PUBLIC
complex_minv(C Z,const C X)272 void complex_minv (C Z, const C X) { Z = 1. / X ; }
273 GB_PUBLIC
complex_conj(C Z,const C X)274 void complex_conj (C Z, const C X) { Z = conj (X) ; }
275 #endif
276
277 GB_PUBLIC
complex_abs(C Z,const C X)278 void complex_abs (C Z, const C X) { Z = GxB_CMPLX (cabs (X), 0) ; }
279 GB_PUBLIC
complex_not(C Z,const C X)280 void complex_not (C Z, const C X) { Z = BOOL (X) ? F : T ; }
281
282 //------------------------------------------------------------------------------
283 // unary functions, z=f(x) where C -> double
284 //------------------------------------------------------------------------------
285
286 #if GxB_STDC_VERSION >= 201112L
287 GB_PUBLIC
complex_real(double Z,const C X)288 void complex_real (double Z, const C X) { Z = creal (X) ; }
289 GB_PUBLIC
complex_imag(double Z,const C X)290 void complex_imag (double Z, const C X) { Z = cimag (X) ; }
291 GB_PUBLIC
complex_cabs(double Z,const C X)292 void complex_cabs (double Z, const C X) { Z = cabs (X) ; }
293 GB_PUBLIC
complex_angle(double Z,const C X)294 void complex_angle (double Z, const C X) { Z = carg (X) ; }
295 #endif
296
297 //------------------------------------------------------------------------------
298 // unary functions, z=f(x) where double -> C
299 //------------------------------------------------------------------------------
300
301 GB_PUBLIC
complex_complex_real(C Z,const double X)302 void complex_complex_real (C Z, const double X) { Z = GxB_CMPLX (X, 0) ; }
303 GB_PUBLIC
complex_complex_imag(C Z,const double X)304 void complex_complex_imag (C Z, const double X) { Z = GxB_CMPLX (0, X) ; }
305
306 //------------------------------------------------------------------------------
307 // macro to check if a method fails
308 //------------------------------------------------------------------------------
309
310 #undef OK
311 #define OK(method) \
312 info = method ; \
313 if (info != GrB_SUCCESS) \
314 { \
315 Complex_finalize ( ) ; \
316 return (info) ; \
317 }
318
319 //------------------------------------------------------------------------------
320 // Complex_init: create the complex type, operators, monoids, and semiring
321 //------------------------------------------------------------------------------
322
323 #undef C
324 #undef D
325 #define C Complex
326 #define D GrB_FP64
327
328 #define U (GxB_unary_function)
329 #define B (GxB_binary_function)
330
331 GB_PUBLIC
Complex_init(bool builtin_complex)332 GrB_Info Complex_init (bool builtin_complex)
333 {
334
335 GrB_Info info ;
336
337 #if GxB_STDC_VERSION < 201112L
338 // the Complex type requires the ANSI C11 "double complex" type
339 builtin_complex = true ;
340 #endif
341
342 //--------------------------------------------------------------------------
343 // create the Complex type, or set to GxB_FC64
344 //--------------------------------------------------------------------------
345
346 if (builtin_complex)
347 {
348 // use the built-in type
349 Complex = GxB_FC64 ;
350 }
351 else
352 {
353 // create the user-defined type
354 #if GxB_STDC_VERSION >= 201112L
355 OK (GrB_Type_new (&Complex, sizeof (GxB_FC64_t))) ;
356 #endif
357 }
358
359 //--------------------------------------------------------------------------
360 // create the Complex binary operators, CxC->C
361 //--------------------------------------------------------------------------
362
363 if (builtin_complex)
364 {
365 // use the built-in versions
366 Complex_first = GxB_FIRST_FC64 ;
367 Complex_second = GxB_SECOND_FC64 ;
368 Complex_pair = GxB_PAIR_FC64 ;
369 Complex_plus = GxB_PLUS_FC64 ;
370 Complex_minus = GxB_MINUS_FC64 ;
371 Complex_rminus = GxB_RMINUS_FC64 ;
372 Complex_times = GxB_TIMES_FC64 ;
373 Complex_div = GxB_DIV_FC64 ;
374 Complex_rdiv = GxB_RDIV_FC64 ;
375 }
376 else
377 {
378 // create user-defined versions
379 #if GxB_STDC_VERSION >= 201112L
380 OK (GrB_BinaryOp_new (&Complex_first , B complex_first , C, C, C)) ;
381 OK (GrB_BinaryOp_new (&Complex_second , B complex_second , C, C, C)) ;
382 OK (GrB_BinaryOp_new (&Complex_pair , B complex_pair , C, C, C)) ;
383 OK (GrB_BinaryOp_new (&Complex_plus , B complex_plus , C, C, C)) ;
384 OK (GrB_BinaryOp_new (&Complex_minus , B complex_minus , C, C, C)) ;
385 OK (GrB_BinaryOp_new (&Complex_rminus , B complex_rminus , C, C, C)) ;
386 OK (GrB_BinaryOp_new (&Complex_times , B complex_times , C, C, C)) ;
387 OK (GrB_BinaryOp_new (&Complex_div , B complex_div , C, C, C)) ;
388 OK (GrB_BinaryOp_new (&Complex_rdiv , B complex_rdiv , C, C, C)) ;
389 #endif
390 }
391
392 // these are not built-in
393 OK (GrB_BinaryOp_new (&Complex_min , B complex_min , C, C, C)) ;
394 OK (GrB_BinaryOp_new (&Complex_max , B complex_max , C, C, C)) ;
395
396 //--------------------------------------------------------------------------
397 // create the Complex binary comparison operators, CxC -> C
398 //--------------------------------------------------------------------------
399
400 if (builtin_complex)
401 {
402 // use the built-in versions
403 Complex_iseq = GxB_ISEQ_FC64 ;
404 Complex_isne = GxB_ISNE_FC64 ;
405 }
406 else
407 {
408 // create user-defined versions
409 #if GxB_STDC_VERSION >= 201112L
410 OK (GrB_BinaryOp_new (&Complex_iseq , B complex_iseq , C, C, C)) ;
411 OK (GrB_BinaryOp_new (&Complex_isne , B complex_isne , C, C, C)) ;
412 #endif
413 }
414
415 // these are not built-in
416 OK (GrB_BinaryOp_new (&Complex_isgt , B complex_isgt , C, C, C)) ;
417 OK (GrB_BinaryOp_new (&Complex_islt , B complex_islt , C, C, C)) ;
418 OK (GrB_BinaryOp_new (&Complex_isge , B complex_isge , C, C, C)) ;
419 OK (GrB_BinaryOp_new (&Complex_isle , B complex_isle , C, C, C)) ;
420
421 //--------------------------------------------------------------------------
422 // create the Complex boolean operators, CxC -> C
423 //--------------------------------------------------------------------------
424
425 // these are not built-in
426 OK (GrB_BinaryOp_new (&Complex_or , B complex_or , C, C, C)) ;
427 OK (GrB_BinaryOp_new (&Complex_and , B complex_and , C, C, C)) ;
428 OK (GrB_BinaryOp_new (&Complex_xor , B complex_xor , C, C, C)) ;
429
430 //--------------------------------------------------------------------------
431 // create the Complex binary operators, CxC -> bool
432 //--------------------------------------------------------------------------
433
434 if (builtin_complex)
435 {
436 // use the built-in versions
437 Complex_eq = GxB_EQ_FC64 ;
438 Complex_ne = GxB_NE_FC64 ;
439 }
440 else
441 {
442 // create user-defined versions
443 #if GxB_STDC_VERSION >= 201112L
444 OK (GrB_BinaryOp_new (&Complex_eq , B complex_eq , GrB_BOOL, C, C)) ;
445 OK (GrB_BinaryOp_new (&Complex_ne , B complex_ne , GrB_BOOL, C, C)) ;
446 #endif
447 }
448
449 // these are not built-in
450 OK (GrB_BinaryOp_new (&Complex_gt , B complex_gt , GrB_BOOL, C, C)) ;
451 OK (GrB_BinaryOp_new (&Complex_lt , B complex_lt , GrB_BOOL, C, C)) ;
452 OK (GrB_BinaryOp_new (&Complex_ge , B complex_ge , GrB_BOOL, C, C)) ;
453 OK (GrB_BinaryOp_new (&Complex_le , B complex_le , GrB_BOOL, C, C)) ;
454
455 //--------------------------------------------------------------------------
456 // create the Complex binary operator, double x double -> C
457 //--------------------------------------------------------------------------
458
459 if (builtin_complex)
460 {
461 // use the built-in versions
462 Complex_complex = GxB_CMPLX_FP64 ;
463 }
464 else
465 {
466 // create user-defined versions
467 #if GxB_STDC_VERSION >= 201112L
468 OK (GrB_BinaryOp_new (&Complex_complex, B complex_complex, C, D, D)) ;
469 #endif
470 }
471
472 //--------------------------------------------------------------------------
473 // create the Complex unary operators, C->C
474 //--------------------------------------------------------------------------
475
476 if (builtin_complex)
477 {
478 // use the built-in versions
479 Complex_one = GxB_ONE_FC64 ;
480 Complex_identity = GxB_IDENTITY_FC64 ;
481 Complex_ainv = GxB_AINV_FC64 ;
482 Complex_minv = GxB_MINV_FC64 ;
483 Complex_conj = GxB_CONJ_FC64 ;
484 }
485 else
486 {
487 // create user-defined versions
488 #if GxB_STDC_VERSION >= 201112L
489 OK (GrB_UnaryOp_new (&Complex_one , U complex_one , C, C)) ;
490 OK (GrB_UnaryOp_new (&Complex_identity, U complex_identity, C, C)) ;
491 OK (GrB_UnaryOp_new (&Complex_ainv , U complex_ainv , C, C)) ;
492 OK (GrB_UnaryOp_new (&Complex_minv , U complex_minv , C, C)) ;
493 OK (GrB_UnaryOp_new (&Complex_conj , U complex_conj , C, C)) ;
494 #endif
495 }
496
497 // these are not built-in
498 OK (GrB_UnaryOp_new (&Complex_abs , U complex_abs , C, C)) ;
499 OK (GrB_UnaryOp_new (&Complex_not , U complex_not , C, C)) ;
500
501 //--------------------------------------------------------------------------
502 // create the unary functions, C -> double
503 //--------------------------------------------------------------------------
504
505 if (builtin_complex)
506 {
507 // use the built-in versions
508 Complex_real = GxB_CREAL_FC64 ;
509 Complex_imag = GxB_CIMAG_FC64 ;
510 Complex_cabs = GxB_ABS_FC64 ;
511 Complex_angle = GxB_CARG_FC64 ;
512 }
513 else
514 {
515 // create user-defined versions
516 #if GxB_STDC_VERSION >= 201112L
517 OK (GrB_UnaryOp_new (&Complex_real , U complex_real , D, C)) ;
518 OK (GrB_UnaryOp_new (&Complex_imag , U complex_imag , D, C)) ;
519 OK (GrB_UnaryOp_new (&Complex_cabs , U complex_cabs , D, C)) ;
520 OK (GrB_UnaryOp_new (&Complex_angle , U complex_angle , D, C)) ;
521 #endif
522 }
523
524 //--------------------------------------------------------------------------
525 // create the unary functions, double -> C
526 //--------------------------------------------------------------------------
527
528 // these are not built-in
529 OK (GrB_UnaryOp_new (&Complex_complex_real, U complex_complex_real, C, D)) ;
530 OK (GrB_UnaryOp_new (&Complex_complex_imag, U complex_complex_imag, C, D)) ;
531
532 //--------------------------------------------------------------------------
533 // create the Complex monoids
534 //--------------------------------------------------------------------------
535
536 if (builtin_complex)
537 {
538 // use the built-in versions
539 Complex_plus_monoid = GxB_PLUS_FC64_MONOID ;
540 Complex_times_monoid = GxB_TIMES_FC64_MONOID ;
541 }
542 else
543 {
544 // create user-defined versions
545 #if GxB_STDC_VERSION >= 201112L
546 double complex C_1 = ONE ;
547 double complex C_0 = ZERO ;
548 OK (GrB_Monoid_new_UDT (&Complex_plus_monoid, Complex_plus, &C_0)) ;
549 OK (GrB_Monoid_new_UDT (&Complex_times_monoid, Complex_times, &C_1)) ;
550 #endif
551 }
552
553 //----------------------------------------------------------------------
554 // create the Complex plus-times semiring
555 //----------------------------------------------------------------------
556
557 if (builtin_complex)
558 {
559 // use the built-in versions
560 Complex_plus_times = GxB_PLUS_TIMES_FC64 ;
561 }
562 else
563 {
564 // more could be created, but this suffices for testing GraphBLAS
565 OK (GrB_Semiring_new (&Complex_plus_times, Complex_plus_monoid,
566 Complex_times)) ;
567 }
568
569 return (GrB_SUCCESS) ;
570 }
571
572
573 //------------------------------------------------------------------------------
574 // Complex_finalize: free all complex types, operators, monoids, and semiring
575 //------------------------------------------------------------------------------
576
577 // These may be built-in types and operators. They are safe to free; the
578 // GrB_*_free functions silently do nothing if asked to free bulit-in objects.
579
580 GB_PUBLIC
Complex_finalize()581 GrB_Info Complex_finalize ( )
582 {
583
584 //--------------------------------------------------------------------------
585 // free the Complex plus-times semiring
586 //--------------------------------------------------------------------------
587
588 GrB_Semiring_free (&Complex_plus_times) ;
589
590 //--------------------------------------------------------------------------
591 // free the Complex monoids
592 //--------------------------------------------------------------------------
593
594 GrB_Monoid_free (&Complex_plus_monoid ) ;
595 GrB_Monoid_free (&Complex_times_monoid) ;
596
597 //--------------------------------------------------------------------------
598 // free the Complex binary operators, CxC->C
599 //--------------------------------------------------------------------------
600
601 GrB_BinaryOp_free (&Complex_first ) ;
602 GrB_BinaryOp_free (&Complex_second) ;
603 GrB_BinaryOp_free (&Complex_pair ) ;
604 GrB_BinaryOp_free (&Complex_min ) ;
605 GrB_BinaryOp_free (&Complex_max ) ;
606 GrB_BinaryOp_free (&Complex_plus ) ;
607 GrB_BinaryOp_free (&Complex_minus ) ;
608 GrB_BinaryOp_free (&Complex_rminus) ;
609 GrB_BinaryOp_free (&Complex_times ) ;
610 GrB_BinaryOp_free (&Complex_div ) ;
611 GrB_BinaryOp_free (&Complex_rdiv ) ;
612
613 GrB_BinaryOp_free (&Complex_iseq) ;
614 GrB_BinaryOp_free (&Complex_isne) ;
615 GrB_BinaryOp_free (&Complex_isgt) ;
616 GrB_BinaryOp_free (&Complex_islt) ;
617 GrB_BinaryOp_free (&Complex_isge) ;
618 GrB_BinaryOp_free (&Complex_isle) ;
619
620 GrB_BinaryOp_free (&Complex_or) ;
621 GrB_BinaryOp_free (&Complex_and) ;
622 GrB_BinaryOp_free (&Complex_xor) ;
623
624 //--------------------------------------------------------------------------
625 // free the Complex binary operators, CxC -> bool
626 //--------------------------------------------------------------------------
627
628 GrB_BinaryOp_free (&Complex_eq) ;
629 GrB_BinaryOp_free (&Complex_ne) ;
630 GrB_BinaryOp_free (&Complex_gt) ;
631 GrB_BinaryOp_free (&Complex_lt) ;
632 GrB_BinaryOp_free (&Complex_ge) ;
633 GrB_BinaryOp_free (&Complex_le) ;
634
635 //--------------------------------------------------------------------------
636 // free the Complex binary operator, double x double -> complex
637 //--------------------------------------------------------------------------
638
639 GrB_BinaryOp_free (&Complex_complex) ;
640
641 //--------------------------------------------------------------------------
642 // free the Complex unary operators, C->C
643 //--------------------------------------------------------------------------
644
645 GrB_UnaryOp_free (&Complex_one ) ;
646 GrB_UnaryOp_free (&Complex_identity) ;
647 GrB_UnaryOp_free (&Complex_ainv ) ;
648 GrB_UnaryOp_free (&Complex_abs ) ;
649 GrB_UnaryOp_free (&Complex_minv ) ;
650 GrB_UnaryOp_free (&Complex_not ) ;
651 GrB_UnaryOp_free (&Complex_conj ) ;
652
653 //--------------------------------------------------------------------------
654 // free the unary functions, C -> double
655 //--------------------------------------------------------------------------
656
657 GrB_UnaryOp_free (&Complex_real ) ;
658 GrB_UnaryOp_free (&Complex_imag ) ;
659 GrB_UnaryOp_free (&Complex_cabs ) ;
660 GrB_UnaryOp_free (&Complex_angle) ;
661
662 //--------------------------------------------------------------------------
663 // free the unary functions, double -> C
664 //--------------------------------------------------------------------------
665
666 GrB_UnaryOp_free (&Complex_complex_real) ;
667 GrB_UnaryOp_free (&Complex_complex_imag) ;
668
669 //--------------------------------------------------------------------------
670 // free the Complex type
671 //--------------------------------------------------------------------------
672
673 GrB_Type_free (&Complex) ;
674
675 return (GrB_SUCCESS) ;
676 }
677
678