1function C = GB_spec_assign (C, Mask, accum, A, I, J, descriptor, scalar) 2%GB_SPEC_ASSIGN a MATLAB mimic of GrB_assign (but not Row or Col variants) 3% 4% Usage: 5% C = GB_spec_assign (C, Mask, accum, A, I, J, descriptor, scalar) 6% 7% Computes C<Mask>(I,J) = accum(C(I,J),A), in GraphBLAS notation. 8% 9% This function does the same thing as GrB_Matrix_assign, GrB_Vector_assign, 10% GrB_Matrix_assign_TYPE, and GrB_Vector_assign_TYPE. For these uses, the Mask 11% must always be the same size as C. All of C can be affected (if C_replace is 12% true, for example). 13% 14% This function does not mimic the GrB_Row_assign and GrB_Col_assign functions 15% since they behave differently; their Mask is a single row/column, and they do 16% not affect any part of C outside that row or column. Those two functions 17% have their own GB_spec_Row_assign.m and GB_spec_Col_assign.m functions. 18 19% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved. 20% SPDX-License-Identifier: Apache-2.0 21 22%------------------------------------------------------------------------------- 23% get inputs 24%------------------------------------------------------------------------------- 25 26if (nargout > 1 || nargin ~= 8) 27 error ('usage: C = GB_spec_assign (C, Mask, accum, A, I, J, descriptor, scalar)') ; 28end 29 30% Convert inputs to dense matrices with explicit patterns and types, 31% and with where X(~X.pattern)==identity for all matrices A, B, and C. 32C = GB_spec_matrix (C) ; 33A = GB_spec_matrix (A) ; 34[C_replace Mask_comp Atrans Btrans Mask_struct] = ... 35 GB_spec_descriptor (descriptor) ; 36Mask = GB_spec_getmask (Mask, Mask_struct) ; 37 38%------------------------------------------------------------------------------- 39% do the work via a clean MATLAB interpretation of the entire GraphBLAS spec 40%------------------------------------------------------------------------------- 41 42% apply the descriptor to A 43if (Atrans) 44 A.matrix = A.matrix.' ; 45 A.pattern = A.pattern' ; 46end 47 48% expand I and J if empty 49if (ischar (I) & isempty (I)) 50 % I = '' is treated as the empty list 51 I = [ ] ; 52elseif (isempty (I) || isequal (I, ':')) 53 % I = [ ] is treated as ":" 54 nrows = size (C.matrix, 1) ; 55 I = 1:nrows ; 56end 57if (ischar (J) & isempty (J)) 58 % J = '' is treated as the empty list 59 J = [ ] ; 60elseif (isempty (J) || isequal (J, ':')) 61 % J = [ ] is treated as the ":" 62 ncols = size (C.matrix, 2) ; 63 J = 1:ncols ; 64end 65 66if (scalar) 67 % scalar expansion: remove duplicates and expand A into a matrix 68 I = unique (I) ; 69 J = unique (J) ; 70 ni = length (I) ; 71 nj = length (J) ; 72 A.matrix (1:ni, 1:nj) = A.matrix (1,1) ; 73 A.pattern (1:ni, 1:nj) = true ; 74end 75 76%------------------------------------------------------------------------------- 77% compute the submatrix in Z, using accum 78%------------------------------------------------------------------------------- 79 80% initialize Z = C 81Z.matrix = C.matrix ; 82Z.pattern = C.pattern ; 83Z.class = C.class ; 84 85% extract the C(I,J) submatrix 86S.matrix = C.matrix (I,J) ; 87S.pattern = C.pattern (I,J) ; 88S.class = C.class ; 89 90% apply the accum operator, ZIJ = accum (S, A) 91ZIJ = GB_spec_accum (accum, S, A) ; 92 93% assign the submatrix into Z 94Z.matrix (I,J) = ZIJ.matrix ; 95Z.pattern (I,J) = ZIJ.pattern ; 96 97%------------------------------------------------------------------------------- 98% apply the Mask and C_replace 99%------------------------------------------------------------------------------- 100 101% C<Mask> = Z: apply the Mask and C_replace, and return the result 102C = GB_spec_mask (C, Mask, Z, C_replace, Mask_comp, 0) ; 103 104