1 //------------------------------------------------------------------------------
2 // GB_mex_Vector_extractElement: MATLAB interface for x = v(i)
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 #include "GB_mex.h"
11 
12 #define USAGE "y = GB_mex_Vector_extractElement (v, I, xtype)"
13 
14 #define FREE_ALL                                        \
15 {                                                       \
16     GrB_Vector_free_(&v) ;                              \
17     GB_mx_put_global (true) ;                           \
18 }
19 
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])20 void mexFunction
21 (
22     int nargout,
23     mxArray *pargout [ ],
24     int nargin,
25     const mxArray *pargin [ ]
26 )
27 {
28 
29     bool malloc_debug = GB_mx_get_global (true) ;
30     GrB_Vector v = NULL ;
31     GB_void *Y = NULL ;
32     GrB_Index *I = NULL, ni = 0, I_range [3] ;
33     bool is_list ;
34 
35     // check inputs
36     if (nargout > 1 || nargin < 2 || nargin > 3)
37     {
38         mexErrMsgTxt ("Usage: " USAGE) ;
39     }
40 
41     #define GET_DEEP_COPY ;
42     #define FREE_DEEP_COPY ;
43 
44     // get v (shallow copy)
45     v = GB_mx_mxArray_to_Vector (pargin [0], "v input", false, true) ;
46     if (v == NULL)
47     {
48         FREE_ALL ;
49         mexErrMsgTxt ("v failed") ;
50     }
51 
52     // get I
53     if (!GB_mx_mxArray_to_indices (&I, pargin [1], &ni, I_range, &is_list))
54     {
55         FREE_ALL ;
56         mexErrMsgTxt ("I failed") ;
57     }
58     if (!is_list)
59     {
60         mexErrMsgTxt ("I must be a list") ;
61     }
62 
63     // get xtype
64     GrB_Type xtype = GB_mx_string_to_Type (PARGIN (2), v->type) ;
65 
66     // create output x
67     pargout [0] = GB_mx_create_full (ni, 1, xtype) ;
68     Y = mxGetData (pargout [0]) ;
69 
70     size_t s = 2 * sizeof (double) ;
71 
72     // x = v (i)
73     switch (xtype->code)
74     {
75         case GB_BOOL_code   :
76 
77             for (int64_t k = 0 ; k < ni ; k++)
78             {
79                 bool *X = (bool *) Y ;
80                 METHOD (GrB_Vector_extractElement_BOOL_(&X [k], v, I [k])) ;
81             }
82             break ;
83 
84         case GB_INT8_code   :
85 
86             for (int64_t k = 0 ; k < ni ; k++)
87             {
88                 int8_t *X = (int8_t *) Y ;
89                 METHOD (GrB_Vector_extractElement_INT8_(&X [k], v, I [k])) ;
90             }
91             break ;
92 
93         case GB_UINT8_code  :
94 
95             for (int64_t k = 0 ; k < ni ; k++)
96             {
97                 uint8_t *X = (uint8_t *) Y ;
98                 METHOD (GrB_Vector_extractElement_UINT8_(&X [k], v, I [k])) ;
99             }
100             break ;
101 
102         case GB_INT16_code  :
103 
104             for (int64_t k = 0 ; k < ni ; k++)
105             {
106                 int16_t *X = (int16_t *) Y ;
107                 METHOD (GrB_Vector_extractElement_INT16_(&X [k], v, I [k])) ;
108             }
109             break ;
110 
111         case GB_UINT16_code :
112 
113             for (int64_t k = 0 ; k < ni ; k++)
114             {
115                 uint16_t *X = (uint16_t *) Y ;
116                 METHOD (GrB_Vector_extractElement_UINT16_(&X [k], v, I [k])) ;
117             }
118             break ;
119 
120         case GB_INT32_code  :
121 
122             for (int64_t k = 0 ; k < ni ; k++)
123             {
124                 int32_t *X = (int32_t *) Y ;
125                 METHOD (GrB_Vector_extractElement_INT32_(&X [k], v, I [k])) ;
126             }
127             break ;
128 
129         case GB_UINT32_code :
130 
131             for (int64_t k = 0 ; k < ni ; k++)
132             {
133                 uint32_t *X = (uint32_t *) Y ;
134                 METHOD (GrB_Vector_extractElement_UINT32_(&X [k], v, I [k])) ;
135             }
136             break ;
137 
138         case GB_INT64_code  :
139 
140             for (int64_t k = 0 ; k < ni ; k++)
141             {
142                 int64_t *X = (int64_t *) Y ;
143                 METHOD (GrB_Vector_extractElement_INT64_(&X [k], v, I [k])) ;
144             }
145             break ;
146 
147         case GB_UINT64_code :
148 
149             for (int64_t k = 0 ; k < ni ; k++)
150             {
151                 uint64_t *X = (uint64_t *) Y ;
152                 METHOD (GrB_Vector_extractElement_UINT64_(&X [k], v, I [k])) ;
153             }
154             break ;
155 
156         case GB_FP32_code   :
157 
158             for (int64_t k = 0 ; k < ni ; k++)
159             {
160                 float *X = (float *) Y ;
161                 METHOD (GrB_Vector_extractElement_FP32_(&X [k], v, I [k])) ;
162             }
163             break ;
164 
165         case GB_FP64_code   :
166 
167             for (int64_t k = 0 ; k < ni ; k++)
168             {
169                 double *X = (double *) Y ;
170                 METHOD (GrB_Vector_extractElement_FP64_(&X [k], v, I [k])) ;
171             }
172             break;
173 
174         case GB_FC32_code   :
175 
176             for (int64_t k = 0 ; k < ni ; k++)
177             {
178                 GxB_FC32_t *X = (void *) Y ;
179                 METHOD (GxB_Vector_extractElement_FC32_(&X [k], v, I [k])) ;
180             }
181             break;
182 
183         case GB_FC64_code   :
184 
185             for (int64_t k = 0 ; k < ni ; k++)
186             {
187                 GxB_FC64_t *X = (void *) Y ;
188                 METHOD (GxB_Vector_extractElement_FC64_(&X [k], v, I [k])) ;
189             }
190             break;
191 
192         case GB_UDT_code   :
193 
194             // user-defined Complex
195             for (int64_t k = 0 ; k < ni ; k++)
196             {
197                 GxB_FC64_t *X = (void *) Y ;
198                 METHOD (GrB_Vector_extractElement_UDT (&X [k], v, I [k])) ;
199             }
200             break;
201 
202         default              : FREE_ALL ; mexErrMsgTxt ("unsupported type") ;
203     }
204 
205     FREE_ALL ;
206 }
207 
208