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