1 //------------------------------------------------------------------------------
2 // gbeadd: sparse matrix addition
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: GPL-3.0-or-later
7
8 //------------------------------------------------------------------------------
9
10 // gbeadd is an interface to GrB_Matrix_eWiseAdd_BinaryOp.
11 // Note that gbeadd and gbemult are nearly identical mexFunctions.
12
13 // Usage:
14
15 // C = gbeadd (binop, A, B)
16 // C = gbeadd (binop, A, B, desc)
17 // C = gbeadd (Cin, accum, binop, A, B, desc)
18 // C = gbeadd (Cin, M, binop, A, B, desc)
19 // C = gbeadd (Cin, M, accum, binop, A, B, desc)
20
21 // If Cin is not present then it is implicitly a matrix with no entries, of the
22 // right size (which depends on A, B, and the descriptor).
23
24 #include "gb_matlab.h"
25
26 #define USAGE "usage: C = GrB.eadd (Cin, M, accum, binop, A, B, desc)"
27
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])28 void mexFunction
29 (
30 int nargout,
31 mxArray *pargout [ ],
32 int nargin,
33 const mxArray *pargin [ ]
34 )
35 {
36
37 //--------------------------------------------------------------------------
38 // check inputs
39 //--------------------------------------------------------------------------
40
41 gb_usage (nargin >= 3 && nargin <= 7 && nargout <= 2, USAGE) ;
42
43 //--------------------------------------------------------------------------
44 // find the arguments
45 //--------------------------------------------------------------------------
46
47 mxArray *Matrix [4], *String [2], *Cell [2] ;
48 base_enum_t base ;
49 kind_enum_t kind ;
50 GxB_Format_Value fmt ;
51 int nmatrices, nstrings, ncells, sparsity ;
52 GrB_Descriptor desc ;
53 gb_get_mxargs (nargin, pargin, USAGE, Matrix, &nmatrices, String, &nstrings,
54 Cell, &ncells, &desc, &base, &kind, &fmt, &sparsity) ;
55
56 CHECK_ERROR (nmatrices < 2 || nstrings < 1 || ncells > 0, USAGE) ;
57
58 //--------------------------------------------------------------------------
59 // get the matrices
60 //--------------------------------------------------------------------------
61
62 GrB_Type atype, btype, ctype = NULL ;
63 GrB_Matrix C = NULL, M = NULL, A, B ;
64
65 if (nmatrices == 2)
66 {
67 A = gb_get_shallow (Matrix [0]) ;
68 B = gb_get_shallow (Matrix [1]) ;
69 }
70 else if (nmatrices == 3)
71 {
72 C = gb_get_deep (Matrix [0]) ;
73 A = gb_get_shallow (Matrix [1]) ;
74 B = gb_get_shallow (Matrix [2]) ;
75 }
76 else // if (nmatrices == 4)
77 {
78 C = gb_get_deep (Matrix [0]) ;
79 M = gb_get_shallow (Matrix [1]) ;
80 A = gb_get_shallow (Matrix [2]) ;
81 B = gb_get_shallow (Matrix [3]) ;
82 }
83
84 OK (GxB_Matrix_type (&atype, A)) ;
85 OK (GxB_Matrix_type (&btype, B)) ;
86 if (C != NULL)
87 {
88 OK (GxB_Matrix_type (&ctype, C)) ;
89 }
90
91 //--------------------------------------------------------------------------
92 // get the operators
93 //--------------------------------------------------------------------------
94
95 GrB_BinaryOp accum = NULL, op = NULL ;
96
97 if (nstrings == 1)
98 {
99 op = gb_mxstring_to_binop (String [0], atype, btype) ;
100 }
101 else
102 {
103 // if accum appears, then Cin must also appear
104 CHECK_ERROR (C == NULL, USAGE) ;
105 accum = gb_mxstring_to_binop (String [0], ctype, ctype) ;
106 op = gb_mxstring_to_binop (String [1], atype, btype) ;
107 }
108
109 //--------------------------------------------------------------------------
110 // construct C if not present on input
111 //--------------------------------------------------------------------------
112
113 // If C is NULL, then it is not present on input.
114 // Construct C of the right size and type.
115
116 if (C == NULL)
117 {
118 // get the descriptor contents to determine if A is transposed
119 GrB_Desc_Value in0 ;
120 OK (GxB_Desc_get (desc, GrB_INP0, &in0)) ;
121 bool A_transpose = (in0 == GrB_TRAN) ;
122
123 // get the size of A
124 GrB_Index anrows, ancols ;
125 OK (GrB_Matrix_nrows (&anrows, A)) ;
126 OK (GrB_Matrix_ncols (&ancols, A)) ;
127
128 // determine the size of C
129 GrB_Index cnrows = (A_transpose) ? ancols : anrows ;
130 GrB_Index cncols = (A_transpose) ? anrows : ancols ;
131
132 // use the ztype of the op as the type of C
133 OK (GxB_BinaryOp_ztype (&ctype, op)) ;
134
135 // create the matrix C and set its format and sparsity
136 fmt = gb_get_format (cnrows, cncols, A, B, fmt) ;
137 sparsity = gb_get_sparsity (A, B, sparsity) ;
138 C = gb_new (ctype, cnrows, cncols, fmt, sparsity) ;
139 }
140
141 //--------------------------------------------------------------------------
142 // compute C<M> += A+B
143 //--------------------------------------------------------------------------
144
145 OK1 (C, GrB_Matrix_eWiseAdd_BinaryOp (C, M, accum, op, A, B, desc)) ;
146
147 //--------------------------------------------------------------------------
148 // free shallow copies
149 //--------------------------------------------------------------------------
150
151 OK (GrB_Matrix_free (&M)) ;
152 OK (GrB_Matrix_free (&A)) ;
153 OK (GrB_Matrix_free (&B)) ;
154 OK (GrB_Descriptor_free (&desc)) ;
155
156 //--------------------------------------------------------------------------
157 // export the output matrix C back to MATLAB
158 //--------------------------------------------------------------------------
159
160 pargout [0] = gb_export (&C, kind) ;
161 pargout [1] = mxCreateDoubleScalar (kind) ;
162 GB_WRAPUP ;
163 }
164
165