Binary Operators

Binary operators are defined on three domains $D_1 \times D_2 \rightarrow D_3$. However, the vast majority of binary operators are defined on a single domain.

BinaryOps are in almost every GraphBLAS operation. They are the primary op argument for emul, eadd, and apply. BinaryOps which are also monoids may be used in reduce. And every GraphBLAS operation which takes an accum keyword argument accepts a BinaryOp.

In almost all cases you should pass Julia functions, which will be mapped to built-in operators, or used to create a new user-defined operator.

julia> using SuiteSparseGraphBLAS
julia> x = GBMatrix([[1,2] [3,4]])2x2 GraphBLAS int64_t matrix, full by col 4 entries, memory: 288 bytes (1,1) 1 (2,1) 2 (1,2) 3 (2,2) 4
julia> x .+ x2x2 GraphBLAS int64_t matrix, full by row 4 entries, memory: 288 bytes (1,1) 2 (1,2) 6 (2,1) 4 (2,2) 8
julia> eadd(x, x, +)2x2 GraphBLAS int64_t matrix, full by row 4 entries, memory: 288 bytes (1,1) 2 (1,2) 6 (2,1) 4 (2,2) 8
julia> x .^ x2x2 GraphBLAS int64_t matrix, full by row 4 entries, memory: 288 bytes (1,1) 1 (1,2) 27 (2,1) 4 (2,2) 256
julia> emul(x, x, ^)2x2 GraphBLAS int64_t matrix, full by row 4 entries, memory: 288 bytes (1,1) 1 (1,2) 27 (2,1) 4 (2,2) 256
julia> x2 = Float64.(x)2x2 GraphBLAS double matrix, full by col 4 entries, memory: 288 bytes (1,1) 1 (2,1) 2 (1,2) 3 (2,2) 4
julia> eadd!(x2, x, x, +; accum=/)2x2 GraphBLAS double matrix, full by col 4 entries, memory: 288 bytes (1,1) 0.5 (2,1) 0.5 (1,2) 0.5 (2,2) 0.5

Internally functions are lowered like this:

julia> using SuiteSparseGraphBLAS
julia> typedop = binaryop(+, Int64, Int64)SuiteSparseGraphBLAS.TypedBinaryOperator{typeof(+), Int64, Int64, Int64}(true, true, "GrB_PLUS_INT64", Ptr{SuiteSparseGraphBLAS.LibGraphBLAS.GB_BinaryOp_opaque} @0x00007f2fa5c2b5c0, +, nothing)
julia> eadd(GBVector([1,2]), GBVector([3,4]), typedop)2x1 GraphBLAS int64_t matrix, full by col 2 entries, memory: 272 bytes (1,1) 4 (2,1) 6

Built-Ins

All built-in binary operators can be found below:

Julia FunctionGraphBLAS NameNotes
firstFIRSTfirst(x, y) = x
secondSECONDsecond(x, y) = y
anyANYany(x, y) = 1 if x or y are stored values
pairPAIRany(x, y) = 1 if x and y are stored values
+PLUS
-MINUS
rminusRMINUS
*TIMES
/DIV
\RDIV
^POW
iseqISEQiseq(x::T, y::T) = T(x == y)
isneISNEisne(x::T, y::T) = T(x != y)
minMIN
maxMAX
isgtISGTisgt(x::T, y::T) = T(x > y)
isltISLTislt(x::T, y::T) = T(x < y)
isgeISGEisge(x::T, y::T) = T(x >= y)
isleISLEisle(x::T, y::T) = T(x <= y)
LOR
LAND
lxorLXOR
==EQ
!=NE
>GT
<LT
>=GE
<=LE
xnorLXNOR
atanATAN2
hypotHYPOT
fmodFMOD
remREMAINDER
ldexpLDEXP
copysignCOPYSIGN
complexCMPLX
|BOR
&BAND
BXOR
bgetBGET
bsetBSET
bclrBCLR
>>BSHIFT
firsti0FIRSTIfirsti0(A[i,j], B[k,l]) = i - 1
firstiFIRSTI1firsti(A[i,j], B[k,l]) = i
firstj0FIRSTJfirstj0(A[i,j], B[k,l]) = j - 1
firstjFIRSTJ1firstj(A[i,j], B[k,l]) = j
secondi0SECONDIsecondi0(A[i,j], B[k,l]) = k - 1
secondiSECONDI1secondi(A[i,j], B[k,l]) = k
secondj0SECONDJsecondj0(A[i,j], B[k,l]) = l - 1
secondjSECONDJ1secondj(A[i,j], B[k,l]) = l