1function [z tol] = GB_user_op (op, x, y)
2%GB_USER_OP apply a complex binary and unary operator
3%
4% MATLAB equivalents of the GraphBLAS user-defined Complex operators.
5% See ../Demo/usercomplex.[ch] and the GB_mex_op mexFunction
6%
7% [z tol] = GB_user_op (op,x,y) returns tol true if GB_mex_op(op,x,y) is
8% allowed to have roundoff error when compared with GB_user_op(op,x,y).  tol is
9% false if the result in MATLAB and GraphBLAS should match exactly.
10%
11% No typecasting is done for user-defined operators.  x,y,z are either
12% double complex or double
13
14% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
15% SPDX-License-Identifier: Apache-2.0
16
17tol = false ;
18
19switch op
20
21    %---------------------------------------------------------------------------
22    % binary operators
23    %---------------------------------------------------------------------------
24
25    % x,y,z all complex:
26    case 'first'
27        z = x ;
28    case 'second'
29        z = y ;
30    case 'pair'
31        z = GB_spec_ones (size (x), GB_spec_type (x)) ;
32%   case 'min'
33%       z = min (x,y,'includenan') ;
34%   case 'max'
35%       z = max (x,y,'includenan') ;
36    case 'plus'
37        z = x+y ;
38    case 'minus'
39        z = x-y ;
40    case 'rminus'
41        z = y-x ;
42    case 'times'
43        z = x.*y ;
44    case 'div'
45        % MATLAB doesn't return a complex NaN (Nan+1i*Nan), but the GraphBLAS
46        % GB_mex_op mexFunction does.  So if z has any of them, replace them
47        % with a complex Nan, just to make sure the tests pass...
48        z = x./y ;
49        if (any (isnan (z)))
50            z (isnan (z)) = complex (nan,nan) ;
51        end
52        tol = true ;
53    case 'rdiv'
54        z = y./x ;
55        if (any (isnan (z)))
56            z (isnan (z)) = complex (nan,nan) ;
57        end
58        tol = true ;
59    case 'pow'
60        z = y.^x ;
61        tol = true ;
62
63    % x,y,z all complex:
64    case 'iseq'
65        z = complex (double (x == y), 0) ;
66    case 'isne'
67        z = complex (double (x ~= y), 0) ;
68    case 'isgt'
69        z = complex (double (x >  y), 0) ;
70    case 'islt'
71        z = complex (double (x <  y), 0) ;
72    case 'isge'
73        z = complex (double (x >= y), 0) ;
74    case 'isle'
75        z = complex (double (x <= y), 0) ;
76
77    % x,y,z all complex:
78    case 'or'
79        z = complex (double ((x ~= 0) | (y ~= 0)), 0) ;
80    case 'and'
81        z = complex (double ((x ~= 0) & (y ~= 0)), 0) ;
82    case 'xor'
83        z = complex (double ((x ~= 0) ~= (y ~= 0)), 0) ;
84
85    % x,y complex, z logical:
86    case 'eq'
87        z = x == y ;
88    case 'ne'
89        z = x ~= y ;
90    case 'gt'
91        z = x >  y ;
92    case 'lt'
93        z = x <  y ;
94    case 'ge'
95        z = x >= y ;
96    case 'le'
97        z = x <= y ;
98
99    % x,y double, z comlex:
100    case 'complex'
101        z = complex (x,y) ;
102
103    %---------------------------------------------------------------------------
104    % unary operators
105    %---------------------------------------------------------------------------
106
107    % x,z complex
108    case 'one'
109        z = GB_spec_ones (size (x), GB_spec_type (x))  ;
110    case 'identity'
111        z = x ;
112    case 'ainv'
113        z = -x ;
114    case 'abs'
115        z = abs (x) ;
116        tol = true ;
117    case 'minv'
118        z = 1./x ;
119        if (any (isnan (z)))
120            z (isnan (z)) = complex (nan,nan) ;
121        end
122        tol = true ;
123%   case 'not'
124%       z = complex (double (~(x ~= 0)), 0) ;
125    case 'conj'
126        z = conj (x) ;
127
128    % x complex, z real
129    case 'real'
130        z = real (x) ;
131    case 'imag'
132        z = imag (x) ;
133    case { 'angle', 'carg' }
134        z = angle (x) ;
135        tol = true ;
136
137%   case 'abs'
138%       complex (abs (x), 0) ;
139%   case 'cabs'
140%       z = abs (x) ;
141%       tol = true ;
142%   case 'complex_real'
143%       z = complex (x,0) ;
144%   case 'complex_imag'
145%       z = complex (0,x) ;
146
147    otherwise
148        error ('unrecognized complex operator')
149end
150
151