1 //------------------------------------------------------------------------------
2 // GB_mex_Matrix_extractElement: MATLAB interface for x = A(i,j)
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7
8 //------------------------------------------------------------------------------
9
10 // x = A (i,j), where i and j are zero-based. If i and j arrays, then
11 // x (k) = A (i (k), j (k)) is done for all k.
12
13 // I and J and zero-based
14
15 #include "GB_mex.h"
16
17 #define USAGE "x = GB_mex_Matrix_extractElement (A, I, J, xtype)"
18
19 #define FREE_ALL \
20 { \
21 GrB_Matrix_free_(&A) ; \
22 GB_mx_put_global (true) ; \
23 }
24
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])25 void mexFunction
26 (
27 int nargout,
28 mxArray *pargout [ ],
29 int nargin,
30 const mxArray *pargin [ ]
31 )
32 {
33
34 bool malloc_debug = GB_mx_get_global (true) ;
35 GrB_Matrix A = NULL ;
36 GB_void *Y = NULL ;
37 GrB_Index *I = NULL, ni = 0, I_range [3] ;
38 GrB_Index *J = NULL, nj = 0, J_range [3] ;
39 bool is_list ;
40
41 // check inputs
42 if (nargout > 1 || nargin < 3 || nargin > 4)
43 {
44 mexErrMsgTxt ("Usage: " USAGE) ;
45 }
46
47 #define GET_DEEP_COPY ;
48 #define FREE_DEEP_COPY ;
49
50 // get A (shallow copy)
51 A = GB_mx_mxArray_to_Matrix (pargin [0], "A input", false, true) ;
52 if (A == NULL)
53 {
54 FREE_ALL ;
55 mexErrMsgTxt ("A failed") ;
56 }
57
58 // get I
59 if (!GB_mx_mxArray_to_indices (&I, pargin [1], &ni, I_range, &is_list))
60 {
61 FREE_ALL ;
62 mexErrMsgTxt ("I failed") ;
63 }
64 if (!is_list)
65 {
66 mexErrMsgTxt ("I is invalid; must be a list") ;
67 }
68
69 // get J
70 if (!GB_mx_mxArray_to_indices (&J, pargin [2], &nj, J_range, &is_list))
71 {
72 FREE_ALL ;
73 mexErrMsgTxt ("J failed") ;
74 }
75 if (!is_list)
76 {
77 mexErrMsgTxt ("J is invalid; must be a list") ;
78 }
79
80 if (ni != nj)
81 {
82 FREE_ALL ;
83 mexErrMsgTxt ("I and J must be the same size") ;
84 }
85
86 // create Y
87 GrB_Type xtype = GB_mx_string_to_Type (PARGIN (3), A->type) ;
88 pargout [0] = GB_mx_create_full (ni, 1, xtype) ;
89 Y = mxGetData (pargout [0]) ;
90
91 size_t s = 2 * sizeof (double) ;
92
93 GrB_Index nrows, ncols ;
94 GrB_Matrix_nrows (&nrows, A) ;
95 GrB_Matrix_ncols (&ncols, A) ;
96 bool is_scalar = GB_SCALAR_OK (A) ;
97
98 // x = A (i,j)
99 switch (xtype->code)
100 {
101 case GB_BOOL_code :
102
103 for (int64_t k = 0 ; k < ni ; k++)
104 {
105 bool *X = (bool *) Y ;
106 if (is_scalar)
107 {
108 METHOD (GxB_Scalar_extractElement_BOOL_(&X [k], A)) ;
109 }
110 else
111 {
112 METHOD (GrB_Matrix_extractElement_BOOL_(&X [k], A, I [k], J [k])) ;
113 }
114 }
115 break ;
116
117 case GB_INT8_code :
118
119 for (int64_t k = 0 ; k < ni ; k++)
120 {
121 int8_t *X = (int8_t *) Y ;
122 if (is_scalar)
123 {
124 METHOD (GxB_Scalar_extractElement_INT8_(&X [k], A)) ;
125 }
126 else
127 {
128 METHOD (GrB_Matrix_extractElement_INT8_(&X [k], A, I [k], J [k])) ;
129 }
130 }
131 break ;
132
133 case GB_UINT8_code :
134
135 for (int64_t k = 0 ; k < ni ; k++)
136 {
137 uint8_t *X = (uint8_t *) Y ;
138 if (is_scalar)
139 {
140 METHOD (GxB_Scalar_extractElement_UINT8_(&X [k], A)) ;
141 }
142 else
143 {
144 METHOD (GrB_Matrix_extractElement_UINT8_(&X [k], A, I [k], J [k])) ;
145 }
146 }
147 break ;
148
149 case GB_INT16_code :
150
151 for (int64_t k = 0 ; k < ni ; k++)
152 {
153 int16_t *X = (int16_t *) Y ;
154 if (is_scalar)
155 {
156 METHOD (GxB_Scalar_extractElement_INT16_(&X [k], A)) ;
157 }
158 else
159 {
160 METHOD (GrB_Matrix_extractElement_INT16_(&X [k], A, I [k], J [k])) ;
161 }
162 }
163 break ;
164
165 case GB_UINT16_code :
166
167 for (int64_t k = 0 ; k < ni ; k++)
168 {
169 uint16_t *X = (uint16_t *) Y ;
170 if (is_scalar)
171 {
172 METHOD (GxB_Scalar_extractElement_UINT16_(&X [k], A)) ;
173 }
174 else
175 {
176 METHOD (GrB_Matrix_extractElement_UINT16_(&X [k], A, I [k], J [k])) ;
177 }
178 }
179 break ;
180
181 case GB_INT32_code :
182
183 for (int64_t k = 0 ; k < ni ; k++)
184 {
185 int32_t *X = (int32_t *) Y ;
186 if (is_scalar)
187 {
188 METHOD (GxB_Scalar_extractElement_INT32_(&X [k], A)) ;
189 }
190 else
191 {
192 METHOD (GrB_Matrix_extractElement_INT32_(&X [k], A, I [k], J [k])) ;
193 }
194 }
195 break ;
196
197 case GB_UINT32_code :
198
199 for (int64_t k = 0 ; k < ni ; k++)
200 {
201 uint32_t *X = (uint32_t *) Y ;
202 if (is_scalar)
203 {
204 METHOD (GxB_Scalar_extractElement_UINT32_(&X [k], A)) ;
205 }
206 else
207 {
208 METHOD (GrB_Matrix_extractElement_UINT32_(&X [k], A, I [k], J [k])) ;
209 }
210 }
211 break ;
212
213 case GB_INT64_code :
214
215 for (int64_t k = 0 ; k < ni ; k++)
216 {
217 int64_t *X = (int64_t *) Y ;
218 if (is_scalar)
219 {
220 METHOD (GxB_Scalar_extractElement_INT64_(&X [k], A)) ;
221 }
222 else
223 {
224 METHOD (GrB_Matrix_extractElement_INT64_(&X [k], A, I [k], J [k])) ;
225 }
226 }
227 break ;
228
229 case GB_UINT64_code :
230
231 for (int64_t k = 0 ; k < ni ; k++)
232 {
233 uint64_t *X = (uint64_t *) Y ;
234 if (is_scalar)
235 {
236 METHOD (GxB_Scalar_extractElement_UINT64_(&X [k], A)) ;
237 }
238 else
239 {
240 METHOD (GrB_Matrix_extractElement_UINT64_(&X [k], A, I [k], J [k])) ;
241 }
242 }
243 break ;
244
245 case GB_FP32_code :
246
247 for (int64_t k = 0 ; k < ni ; k++)
248 {
249 float *X = (float *) Y ;
250 if (is_scalar)
251 {
252 METHOD (GxB_Scalar_extractElement_FP32_(&X [k], A)) ;
253 }
254 else
255 {
256 METHOD (GrB_Matrix_extractElement_FP32_(&X [k], A, I [k], J [k])) ;
257 }
258 }
259 break ;
260
261 case GB_FP64_code :
262
263 for (int64_t k = 0 ; k < ni ; k++)
264 {
265 double *X = (double *) Y ;
266 if (is_scalar)
267 {
268 METHOD (GxB_Scalar_extractElement_FP64_(&X [k], A)) ;
269 }
270 else
271 {
272 METHOD (GrB_Matrix_extractElement_FP64_(&X [k], A, I [k], J [k])) ;
273 }
274 }
275 break;
276
277 case GB_FC32_code :
278
279 for (int64_t k = 0 ; k < ni ; k++)
280 {
281 GxB_FC32_t *X = (void *) Y ;
282 if (is_scalar)
283 {
284 METHOD (GxB_Scalar_extractElement_FC32_(&X [k], A)) ;
285 }
286 else
287 {
288 METHOD (GxB_Matrix_extractElement_FC32_(&X [k], A, I [k], J [k])) ;
289 }
290 }
291 break;
292
293 case GB_FC64_code :
294
295 for (int64_t k = 0 ; k < ni ; k++)
296 {
297 GxB_FC64_t *X = (void *) Y ;
298 if (is_scalar)
299 {
300 METHOD (GxB_Scalar_extractElement_FC64_(&X [k], A)) ;
301 }
302 else
303 {
304 METHOD (GxB_Matrix_extractElement_FC64_(&X [k], A, I [k], J [k])) ;
305 }
306 }
307 break;
308
309 case GB_UDT_code :
310
311 // user-defined Complex
312 for (int64_t k = 0 ; k < ni ; k++)
313 {
314 GxB_FC64_t *X = (void *) Y ;
315 if (is_scalar)
316 {
317 METHOD (GxB_Scalar_extractElement_UDT (&X [k], A)) ;
318 }
319 else
320 {
321 METHOD (GrB_Matrix_extractElement_UDT (&X [k], A, I [k], J [k])) ;
322 }
323 }
324 break;
325
326 default :
327
328 FREE_ALL ;
329 mexErrMsgTxt ("unsupported type") ;
330 }
331
332 FREE_ALL ;
333
334 }
335
336