1 //------------------------------------------------------------------------------
2 // GB_mex_Col_extract: MATLAB interface for w<mask> = accum (w,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 #include "GB_mex.h"
11 
12 #define USAGE "w = GB_mex_Col_extract (w, mask, accum, A, I, j, desc)"
13 
14 #define FREE_ALL                        \
15 {                                       \
16     GrB_Vector_free_(&w) ;              \
17     GrB_Vector_free_(&mask) ;           \
18     GrB_Matrix_free_(&A) ;              \
19     GrB_Descriptor_free_(&desc) ;       \
20     GB_mx_put_global (true) ;           \
21 }
22 
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])23 void mexFunction
24 (
25     int nargout,
26     mxArray *pargout [ ],
27     int nargin,
28     const mxArray *pargin [ ]
29 )
30 {
31 
32     bool malloc_debug = GB_mx_get_global (true) ;
33     GrB_Vector w = NULL ;
34     GrB_Vector mask = NULL ;
35     GrB_Matrix A = NULL ;
36     GrB_Descriptor desc = NULL ;
37     GrB_Index *I = NULL, ni = 0, I_range [3] ;
38     GrB_Index *J = NULL, nj = 0, J_range [3] ;
39     bool ignore ;
40 
41     // check inputs
42     if (nargout > 1 || nargin < 6 || nargin > 7)
43     {
44         mexErrMsgTxt ("Usage: " USAGE) ;
45     }
46 
47     // get w (make a deep copy)
48     #define GET_DEEP_COPY \
49     w = GB_mx_mxArray_to_Vector (pargin [0], "w input", true, true) ;
50     #define FREE_DEEP_COPY GrB_Vector_free_(&w) ;
51     GET_DEEP_COPY ;
52     if (w == NULL)
53     {
54         FREE_ALL ;
55         mexErrMsgTxt ("w failed") ;
56     }
57 
58     // get mask (shallow copy)
59     mask = GB_mx_mxArray_to_Vector (pargin [1], "mask", false, false) ;
60     if (mask == NULL && !mxIsEmpty (pargin [1]))
61     {
62         FREE_ALL ;
63         mexErrMsgTxt ("mask failed") ;
64     }
65 
66     // get A (shallow copy)
67     A = GB_mx_mxArray_to_Matrix (pargin [3], "A input", false, true) ;
68     if (A == NULL)
69     {
70         FREE_ALL ;
71         mexErrMsgTxt ("A failed") ;
72     }
73 
74     // get accum, if present
75     bool user_complex = (Complex != GxB_FC64)
76         && (w->type == Complex || A->type == Complex) ;
77     GrB_BinaryOp accum ;
78     if (!GB_mx_mxArray_to_BinaryOp (&accum, pargin [2], "accum",
79         w->type, user_complex))
80     {
81         FREE_ALL ;
82         mexErrMsgTxt ("accum failed") ;
83     }
84 
85     // get I
86     if (!GB_mx_mxArray_to_indices (&I, pargin [4], &ni, I_range, &ignore))
87     {
88         FREE_ALL ;
89         mexErrMsgTxt ("I failed") ;
90     }
91 
92     // get J
93     if (!GB_mx_mxArray_to_indices (&J, pargin [5], &nj, J_range, &ignore))
94     {
95         FREE_ALL ;
96         mexErrMsgTxt ("J failed") ;
97     }
98 
99     if (nj != 1)
100     {
101         FREE_ALL ;
102         mexErrMsgTxt ("j must be a scalar") ;
103     }
104 
105     GrB_Index j = J [0] ;
106 
107     // get desc
108     if (!GB_mx_mxArray_to_Descriptor (&desc, PARGIN (6), "desc"))
109     {
110         FREE_ALL ;
111         mexErrMsgTxt ("desc failed") ;
112     }
113 
114     // w<mask> = accum (w,A(I,j))
115     METHOD (GrB_Col_extract_(w, mask, accum, A, I, ni, j, desc)) ;
116 
117     // return w to MATLAB as a struct and free the GraphBLAS C
118     pargout [0] = GB_mx_Vector_to_mxArray (&w, "w output", true) ;
119 
120     FREE_ALL ;
121 }
122 
123