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