1 //------------------------------------------------------------------------------
2 // GB_mex_Matrix_extract: MATLAB interface for C<Mask> = accum (C,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 "C = GB_mex_Matrix_extract (C, Mask, accum, A, I, J, desc)"
13 
14 #define FREE_ALL                        \
15 {                                       \
16     GrB_Matrix_free_(&C) ;              \
17     GrB_Matrix_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_Matrix C = NULL ;
34     GrB_Matrix 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 C (make a deep copy)
48     #define GET_DEEP_COPY \
49     C = GB_mx_mxArray_to_Matrix (pargin [0], "C input", true, true) ;
50     #define FREE_DEEP_COPY GrB_Matrix_free_(&C) ;
51     GET_DEEP_COPY ;
52     if (C == NULL)
53     {
54         FREE_ALL ;
55         mexErrMsgTxt ("C failed") ;
56     }
57 
58     // get Mask (shallow copy)
59     Mask = GB_mx_mxArray_to_Matrix (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         && (C->type == Complex || A->type == Complex) ;
77     GrB_BinaryOp accum ;
78     if (!GB_mx_mxArray_to_BinaryOp (&accum, pargin [2], "accum",
79         C->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     // get desc
100     if (!GB_mx_mxArray_to_Descriptor (&desc, PARGIN (6), "desc"))
101     {
102         FREE_ALL ;
103         mexErrMsgTxt ("desc failed") ;
104     }
105 
106     // C<Mask> = accum (C,A(I,J))
107     METHOD (GrB_Matrix_extract_(C, Mask, accum, A, I, ni, J, nj, desc)) ;
108 
109     // return C to MATLAB as a struct and free the GraphBLAS C
110     pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C output", true) ;
111 
112     FREE_ALL ;
113 }
114 
115