1function c = GB_spec_reduce_to_scalar (cin, accum, reduce, A) 2%GB_SPEC_REDUCE_TO_SCALAR a MATLAB mimic of GrB_reduce (to scalar) 3% 4% Usage: 5% c = GB_spec_reduce_to_scalar (cin, accum, reduce, A) 6% 7% Reduces a matrix or vector to a scalar 8% 9% cin is a dense scalar 10 11% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved. 12% SPDX-License-Identifier: Apache-2.0 13 14%------------------------------------------------------------------------------- 15% get inputs 16%------------------------------------------------------------------------------- 17 18if (nargout > 1 || nargin ~= 4) 19 error ('usage: c = GB_spec_Matrix_reduce (cin, accum, reduce, A)') ; 20end 21 22if (isstruct (cin) || issparse (cin) || ~isscalar (cin)) 23 error ('cin must be a dense scalar') ; 24end 25 26cin_type = GB_spec_type (cin) ; 27 28% get the type of A 29if (isstruct (A)) 30 atype = A.class ; 31else 32 atype = GB_spec_type (A) ; 33end 34 35% get the reduce operator. default type is the type of A 36[reduce_op reduce_optype zt xt yt] = GB_spec_operator (reduce, atype) ; 37assert (isequal (zt, xt)) ; 38assert (isequal (zt, yt)) ; 39 40if (GB_spec_is_positional (reduce_op)) 41 error ('reduce operator cannot be positional') ; 42end 43 44% get the identity 45identity = GB_spec_identity (reduce_op, reduce_optype) ; 46if (isempty (identity)) 47 identity = 0 ; 48end 49 50% get the input matrix 51A = GB_spec_matrix (A, identity) ; 52 53% get the accumulator and its types for z = accum(x,y) 54[accum_op accum_optype ztype xtype ytype ] = GB_spec_operator (accum, cin_type) ; 55 56if (GB_spec_is_positional (accum_op)) 57 error ('accum operator cannot be positional') ; 58end 59 60%------------------------------------------------------------------------------- 61% do the work via a clean MATLAB interpretation of the entire GraphBLAS spec 62%------------------------------------------------------------------------------- 63 64% cast A to the type of the reduce operator, but only entries in the pattern 65 66t = identity ; 67if (nnz (A.pattern) > 0) 68 X = GB_mex_cast (A.matrix (A.pattern), reduce_optype) ; 69 for k = 1:length (X) 70 t = GB_spec_op (reduce, t, X (k)) ; 71 end 72end 73 74% apply the accumulator. no mask. t is a dense matrix so this is 75% different than GB_spec_accum. 76if (isempty (accum_op)) 77 c = GB_mex_cast (t, cin_type) ; 78else 79 % c = cin "+" t, but typecast all the arguments 80 t = GB_mex_cast (t, xtype) ; % cast t to accum xtype 81 cin = GB_mex_cast (cin, ytype) ; % cast cin to accum ytype 82 z = GB_spec_op (accum, cin, t) ; % z = accum (cin,t) 83 c = GB_mex_cast (z, cin_type) ; % cast z to type of cin 84end 85 86