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