1function [Z simple] = GB_spec_accum (accum, C, T, identity)
2%GB_SPEC_ACCUM MATLAB mimic of the Z=accum(C,T) operation in GraphBLAS
3%
4% Z = GB_spec_accum (accum, C, T, identity)
5%
6% Apply accum binary operator to the input C and the intermediate result T.
7
8% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
9% SPDX-License-Identifier: Apache-2.0
10
11% get the operator; of is type(C) if type is not present in the accum op
12[opname optype ztype xtype ytype] = GB_spec_operator (accum, C.class) ;
13
14if (GB_spec_is_positional (opname))
15    error ('accum operator cannot be positional') ;
16end
17
18if (nargin < 4)
19    identity = 0 ;
20end
21
22% simple is true if the simpler accum_mask.m script will work without
23% any typecast, and with a zero identity
24simple = (identity == 0) ;
25
26% initialize the matrix Z, same size and class as C
27[nrows ncols] = size (C.matrix) ;
28Z.matrix  = GB_spec_zeros ([nrows ncols], C.class) ;
29% Z.matrix (:,:) = GB_mex_cast (identity, C.class) ;
30Z.pattern = false (nrows, ncols) ;
31Z.class = C.class ;
32
33if (isempty (opname))
34
35    % Z = T, casting into the class of C
36    p = T.pattern ;
37    Z.matrix (p) = GB_mex_cast (T.matrix (p), C.class) ;
38    Z.pattern = T.pattern ;
39
40    simple = simple && isfield (T, 'class') && isequal (T.class, C.class) ;
41
42else
43
44    % Z = accum (C,T)
45
46    % apply the operator to entries in the intersection of C and T
47    p = T.pattern & C.pattern ;
48    % first cast the entries into the class of the operator
49    c = GB_mex_cast (C.matrix (p), xtype) ;
50    t = GB_mex_cast (T.matrix (p), ytype) ;
51    z = GB_spec_op (accum, c, t) ;
52    % cast the result z from optype into the class of C
53    Z.matrix (p) = GB_mex_cast (z, C.class) ;
54
55    % copy entries in C but not in T, into the result Z, no typecasting needed
56    p = C.pattern & ~T.pattern ;
57    Z.matrix (p) = C.matrix (p) ;
58
59    % cast entries in T but not in C, into the result Z
60    p = T.pattern & ~C.pattern ;
61    Z.matrix (p) = GB_mex_cast (T.matrix (p), C.class) ;
62
63    % the pattern of Z is the union of both T and C
64    Z.pattern = C.pattern | T.pattern ;
65
66    simple = simple && ( ...
67        isequal (C.class, optype) && ...
68        isfield (T, 'class') && ...
69        isequal (T.class, optype) && ...
70        isequal (GB_spec_type (z), C.class) && ...
71        isequal (T.class, C.class)) ;
72end
73
74