1 //------------------------------------------------------------------------------
2 // GB_binop_flip: flip a binary multiply operator in a semiring
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2019, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7
8 //------------------------------------------------------------------------------
9
10 // Positional operators are flipped both in (first,second), but also (i,j).
11 // This function is only used for semirings, for matrix-matrix multiply.
12 // It is not used for GrB_apply or GrB_eWise*.
13
14 // TODO: rename this to GB_flip_opcode
15
16 #include "GB.h"
17 #include "GB_binop.h"
18
GB_binop_flip(GB_Opcode opcode,bool * handled)19 GB_Opcode GB_binop_flip // flipped opcode, or -1 on error
20 (
21 GB_Opcode opcode, // opcode to flip
22 bool *handled // true if opcode is handled by flipping the opcode
23 )
24 {
25
26 (*handled) = true ; // set below to false if the op is not handled
27
28 switch (opcode)
29 {
30 // swap FIRST and SECOND
31 case GB_FIRST_opcode : return (GB_SECOND_opcode) ;
32 case GB_SECOND_opcode : return (GB_FIRST_opcode) ;
33
34 // swap LT and GT
35 case GB_GT_opcode : return (GB_LT_opcode) ;
36 case GB_LT_opcode : return (GB_GT_opcode) ;
37
38 // swap LE and GE
39 case GB_GE_opcode : return (GB_LE_opcode) ;
40 case GB_LE_opcode : return (GB_GE_opcode) ;
41
42 // swap ISLT and ISGT
43 case GB_ISGT_opcode : return (GB_ISLT_opcode) ;
44 case GB_ISLT_opcode : return (GB_ISGT_opcode) ;
45
46 // swap ISLE and ISGE
47 case GB_ISGE_opcode : return (GB_ISLE_opcode) ;
48 case GB_ISLE_opcode : return (GB_ISGE_opcode) ;
49
50 // swap DIV and RDIV
51 case GB_DIV_opcode : return (GB_RDIV_opcode) ;
52 case GB_RDIV_opcode : return (GB_DIV_opcode) ;
53
54 // swap MINUS and RMINUS
55 case GB_MINUS_opcode : return (GB_RMINUS_opcode) ;
56 case GB_RMINUS_opcode : return (GB_MINUS_opcode) ;
57
58 // swap FIRSTI and SECONDJ
59 case GB_FIRSTI_opcode : return (GB_SECONDJ_opcode) ;
60 case GB_SECONDJ_opcode : return (GB_FIRSTI_opcode) ;
61
62 // swap FIRSTI1 and SECONDJ1
63 case GB_FIRSTI1_opcode : return (GB_SECONDJ1_opcode) ;
64 case GB_SECONDJ1_opcode : return (GB_FIRSTI1_opcode) ;
65
66 // swap FIRSTJ and SECONDI
67 case GB_FIRSTJ_opcode : return (GB_SECONDI_opcode) ;
68 case GB_SECONDI_opcode : return (GB_FIRSTJ_opcode) ;
69
70 // swap FIRSTJ1 and SECONDI1
71 case GB_FIRSTJ1_opcode : return (GB_SECONDI1_opcode) ;
72 case GB_SECONDI1_opcode : return (GB_FIRSTJ1_opcode) ;
73
74 // these operators are not commutative and do not have flipped ops:
75 case GB_POW_opcode :
76 case GB_BGET_opcode :
77 case GB_BSET_opcode :
78 case GB_BCLR_opcode :
79 case GB_BSHIFT_opcode :
80 case GB_ATAN2_opcode :
81 case GB_FMOD_opcode :
82 case GB_REMAINDER_opcode :
83 case GB_COPYSIGN_opcode :
84 case GB_LDEXP_opcode :
85 case GB_CMPLX_opcode :
86 case GB_USER_opcode :
87 (*handled) = false ;
88 return (opcode) ;
89
90 // these operators are commutative; they are their own flipped ops:
91 case GB_ANY_opcode :
92 case GB_PAIR_opcode :
93 case GB_MIN_opcode :
94 case GB_MAX_opcode :
95 case GB_PLUS_opcode :
96 case GB_TIMES_opcode :
97 case GB_ISEQ_opcode :
98 case GB_ISNE_opcode :
99 case GB_LOR_opcode :
100 case GB_LAND_opcode :
101 case GB_LXOR_opcode :
102 case GB_BOR_opcode :
103 case GB_BAND_opcode :
104 case GB_BXOR_opcode :
105 case GB_BXNOR_opcode :
106 case GB_EQ_opcode :
107 case GB_NE_opcode :
108 case GB_HYPOT_opcode :
109 return (opcode) ;
110
111 default:
112 // not a valid binary opcode
113 (*handled) = false ;
114 return (GB_BAD_opcode) ;
115 }
116 }
117
118