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