1function C = gb_union_op (op, A, B)
2%GB_SPARSE_BINOP apply a binary operator to two sparse matrices.
3% The pattern of C is the set union of A and B.  A and B must first be
4% expanded to include explicit zeros in the set union of A and B.  For
5% example, with A < B for two matrices A and B:
6%
7%     in A        in B        A(i,j) < B (i,j)    true or false
8%     not in A    in B        0 < B(i,j)          true or false
9%     in A        not in B    A(i,j) < 0          true or false
10%     not in A    not in B    0 < 0               false, not in C
11%
12% A and B are expanded to the set union of A and B, with explicit zeros,
13% and then the op is applied via GrB.emult.  Unlike the built-in
14% GraphBLAS GrB.eadd and GrB.emult, both of which apply the operator
15% only to the set intersection, this function applies the operator to the
16% set union of A and B.
17%
18% The inputs are MATLAB matrices or GraphBLAS structs.  The output
19% is a GraphBLAS struct.
20%
21% See also GrB/lt, GrB/min, GrB/max, GrB/ne, GrB/pow2, GrB/atan2,
22% GrB/bitset, GrB/complex.
23
24% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
25% SPDX-License-Identifier: GPL-3.0-or-later
26
27% FUTURE: this is slower than it could be.
28% affects: lt, gt, min(A,B), max(A,B), minus, ne, pow2, atan2, bitset, complex,
29% hypot, and bitshift.
30%
31% This would be faster if a variant to GrB_eWiseAdd would be added, which takes
32% 2 scalar values (one for A and one for B), and applies the binary operator on
33% the union of A and B.
34%
35% The following operations could use this feature:
36%
37%   lt, gt, min, max, ne, pow2, atan2, bitset: (0, 0)
38%   bitshift: (0, (int8) 0)
39%   minus: (0, 0), using the '-' operator instead of A+(-B)
40%   complex: (0, 0)
41%   hypot: (0, 0), uses abs (gb_eadd (...))
42%
43% Suppose the variant is GrB_eWiseUnion (... A, ascalar, B, bscalar).
44% If a scalar is NULL, it would be treated as eWiseAdd, with
45% f(aij,NULL) = aij (the 'first' operator), and f(NULL,bij)=bij,
46% the 'second' operator.  So if both are passed in as NULL,
47% GrB_eWiseUnion (... A, NULL, B, NULL, ...) is identical to
48% GrB_eWiseAdd (... A, B...).
49
50type = gboptype (gbtype (A), gbtype (B)) ;
51
52% A0 = expand A by padding it with zeros from the pattern of B
53A0 = gbeadd (['1st.' type], A, gb_expand (0, B, type)) ;
54
55% B0 = expand B by padding it with zeros from the pattern of A
56B0 = gbeadd (['1st.' type], B, gb_expand (0, A, type)) ;
57
58% A0 and B0 now have the same pattern, so gbemult can be used:
59C = gbemult (A0, op, B0) ;
60
61