1 //------------------------------------------------------------------------------
2 // GB_mex_dup: copy a matrix
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 // copy and typecast a matrix
11
12 #include "GB_mex.h"
13
14 #define USAGE "C = GB_mex_dup (A, type, method, sparsity)"
15
16 #define FREE_ALL \
17 { \
18 GrB_Matrix_free_(&A) ; \
19 GrB_Matrix_free_(&C) ; \
20 GrB_Descriptor_free_(&desc) ; \
21 GB_mx_put_global (true) ; \
22 }
23
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])24 void mexFunction
25 (
26 int nargout,
27 mxArray *pargout [ ],
28 int nargin,
29 const mxArray *pargin [ ]
30 )
31 {
32
33 bool malloc_debug = GB_mx_get_global (true) ;
34 GrB_Matrix A = NULL, C = NULL ;
35 GrB_Descriptor desc = NULL ;
36
37 // check inputs
38 if (nargout > 1 || nargin < 1 || nargin > 4)
39 {
40 mexErrMsgTxt ("Usage: " USAGE) ;
41 }
42
43 #define GET_DEEP_COPY ;
44 #define FREE_DEEP_COPY ;
45
46 // get A (shallow copy)
47 A = GB_mx_mxArray_to_Matrix (pargin [0], "A input", false, true) ;
48 if (A == NULL)
49 {
50 FREE_ALL ;
51 mexErrMsgTxt ("A failed") ;
52 }
53
54 // get ctype of output matrix
55 GrB_Type ctype = GB_mx_string_to_Type (PARGIN (1), A->type) ;
56
57 // get method
58 int GET_SCALAR (2, int, method, 0) ;
59
60 // get sparsity
61 int GET_SCALAR (3, int, sparsity, GxB_DEFAULT) ;
62
63 if (ctype == A->type)
64 {
65 // copy C with the same type as A, with default sparsity
66 if (method == 0 && sparsity == GxB_DEFAULT)
67 {
68 METHOD (GrB_Matrix_dup (&C, A)) ;
69 }
70 else
71 {
72 // try another method, just for testing (see User Guide)
73
74 // C = create an exact copy of A, just like GrB_Matrix_dup
75 GrB_Type type ;
76 GrB_Index nrows, ncols ;
77
78 #undef GET_DEEP_COPY
79 #undef FREE_DEEP_COPY
80
81 #define GET_DEEP_COPY \
82 { \
83 GxB_Matrix_type (&type, A) ; \
84 GrB_Matrix_nrows (&nrows, A) ; \
85 GrB_Matrix_ncols (&ncols, A) ; \
86 GrB_Matrix_new (&C, type, nrows, ncols) ; \
87 GrB_Descriptor_new (&desc) ; \
88 if (sparsity != GxB_DEFAULT) \
89 { \
90 GxB_Matrix_Option_set (C, GxB_SPARSITY_CONTROL, sparsity) ;\
91 } \
92 GxB_Desc_set (desc, GrB_INP0, GrB_TRAN) ; \
93 }
94 #define FREE_DEEP_COPY \
95 { \
96 GrB_Matrix_free_(&C) ; \
97 GrB_Descriptor_free_(&desc) ; \
98 }
99
100 GET_DEEP_COPY ;
101
102 if (method == 1)
103 {
104 // C = A using GrB_transpose with a desc.inp0 = transpose
105 METHOD (GrB_transpose (C, NULL, NULL, A, desc)) ;
106 }
107 else
108 {
109 // C = A using GrB_assign
110 METHOD (GrB_assign (C, NULL, NULL, A,
111 GrB_ALL, nrows, GrB_ALL, ncols, NULL)) ;
112 }
113
114 #undef GET_DEEP_COPY
115 #undef FREE_DEEP_COPY
116
117 }
118 }
119 else
120 {
121 // typecast
122 if (A->type == Complex && Complex != GxB_FC64)
123 {
124 A->type = GxB_FC64 ;
125 }
126
127 // C = (ctype) A
128 GrB_Index nrows, ncols ;
129
130 #define GET_DEEP_COPY \
131 { \
132 GrB_Matrix_nrows (&nrows, A) ; \
133 GrB_Matrix_ncols (&ncols, A) ; \
134 GrB_Matrix_new (&C, ctype, nrows, ncols) ; \
135 GrB_Descriptor_new (&desc) ; \
136 if (sparsity != GxB_DEFAULT) \
137 { \
138 GxB_Matrix_Option_set (C, GxB_SPARSITY_CONTROL, sparsity) ; \
139 } \
140 GxB_Desc_set (desc, GrB_INP0, GrB_TRAN) ; \
141 }
142 #define FREE_DEEP_COPY \
143 { \
144 GrB_Matrix_free_(&C) ; \
145 GrB_Descriptor_free_(&desc) ; \
146 }
147
148 GET_DEEP_COPY ;
149
150 if (method == 1)
151 {
152 // C = A using GrB_transpose with a desc.inp0 = transpose
153 METHOD (GrB_transpose (C, NULL, NULL, A, desc)) ;
154 }
155 else
156 {
157 // C = A using GrB_assign
158 METHOD (GrB_assign (C, NULL, NULL, A,
159 GrB_ALL, nrows, GrB_ALL, ncols, NULL)) ;
160 }
161
162 #undef GET_DEEP_COPY
163 #undef FREE_DEEP_COPY
164 }
165
166 // return C to MATLAB as a struct and free the GraphBLAS C
167 pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C output", true) ;
168
169 FREE_ALL ;
170 }
171
172