1 //------------------------------------------------------------------------------
2 // gb_export: export a GrB_Matrix as a MATLAB matrix or GraphBLAS struct
3 //------------------------------------------------------------------------------
4 
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: GPL-3.0-or-later
7 
8 //------------------------------------------------------------------------------
9 
10 // mxArray pargout [0] = gb_export (&C, kind) ; exports C as a MATLAB matrix
11 // and frees the remaining content of C.
12 
13 #include "gb_matlab.h"
14 
gb_export(GrB_Matrix * C_handle,kind_enum_t kind)15 mxArray *gb_export              // return the exported MATLAB matrix or struct
16 (
17     GrB_Matrix *C_handle,       // GrB_Matrix to export and free
18     kind_enum_t kind            // GrB, sparse, full, or matlab
19 )
20 {
21 
22     //--------------------------------------------------------------------------
23     // determine if all entries in C are present
24     //--------------------------------------------------------------------------
25 
26     GrB_Index nrows, ncols ;
27     bool is_full = false ;
28     if (kind == KIND_MATLAB || kind == KIND_FULL)
29     {
30         GrB_Index nvals ;
31         OK (GrB_Matrix_nvals (&nvals, *C_handle)) ;
32         OK (GrB_Matrix_nrows (&nrows, *C_handle)) ;
33         OK (GrB_Matrix_ncols (&ncols, *C_handle)) ;
34         is_full = ((double) nrows * (double) ncols == (double) nvals) ;
35     }
36 
37     if (kind == KIND_MATLAB)
38     {
39         // export as full if all entries present, or sparse otherwise
40         kind = (is_full) ? KIND_FULL : KIND_SPARSE ;
41     }
42 
43     //--------------------------------------------------------------------------
44     // export the matrix
45     //--------------------------------------------------------------------------
46 
47     if (kind == KIND_SPARSE)
48     {
49 
50         //----------------------------------------------------------------------
51         // export C as a MATLAB sparse matrix
52         //----------------------------------------------------------------------
53 
54         // Typecast to double, if C is integer (int8, ..., uint64)
55         return (gb_export_to_mxsparse (C_handle)) ;
56 
57     }
58     else if (kind == KIND_FULL)
59     {
60 
61         //----------------------------------------------------------------------
62         // export C as a MATLAB full matrix, adding explicit zeros if needed
63         //----------------------------------------------------------------------
64 
65         // No typecasting is needed since MATLAB supports all the same types.
66 
67         GrB_Matrix C = NULL ;
68         if (!is_full)
69         {
70             // expand C with explicit zeros so all entries are present
71             C = gb_expand_to_full (*C_handle, NULL, GxB_BY_COL, NULL) ;
72             OK (GrB_Matrix_free (C_handle)) ;
73             (*C_handle) = C ;
74             CHECK_ERROR (GB_is_shallow (*C_handle), "internal error 707")
75         }
76 
77         if (GB_is_shallow (*C_handle))
78         {
79             // C is shallow so make a deep copy
80             OK (GrB_Matrix_dup (&C, *C_handle)) ;
81             OK (GrB_Matrix_free (C_handle)) ;
82             (*C_handle) = C ;
83         }
84 
85         CHECK_ERROR (GB_is_shallow (*C_handle), "internal error 717")
86 
87         // export as a full matrix, held by column, not uniform-valued
88         void *Cx = NULL ;
89         GrB_Type ctype = NULL ;
90         GrB_Index Cx_size ;
91         OK (GxB_Matrix_export_FullC (C_handle, &ctype, &nrows, &ncols,
92             &Cx, &Cx_size, NULL, NULL)) ;
93 
94         return (gb_export_to_mxfull (&Cx, nrows, ncols, ctype)) ;
95 
96     }
97     else // kind == KIND_GRB
98     {
99 
100         //----------------------------------------------------------------------
101         // export C as a MATLAB struct containing a verbatim GrB_Matrix
102         //----------------------------------------------------------------------
103 
104         // No typecasting is needed since the MATLAB struct can hold all of the
105         // opaque content of the GrB_Matrix.
106         return (gb_export_to_mxstruct (C_handle)) ;
107     }
108 }
109 
110