1 //------------------------------------------------------------------------------
2 // GB_mex_expand: C<M,struct> = scalar
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 #include "matrix.h"
12
13 #define USAGE "C = GB_mex_expand (M, scalar)"
14
15 #define FREE_ALL \
16 { \
17 GrB_Matrix_free_(&M) ; \
18 GrB_Matrix_free_(&C) ; \
19 GB_mx_put_global (true) ; \
20 }
21
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])22 void mexFunction
23 (
24 int nargout,
25 mxArray *pargout [ ],
26 int nargin,
27 const mxArray *pargin [ ]
28 )
29 {
30
31 GrB_Info info ;
32 bool malloc_debug = GB_mx_get_global (true) ;
33 GrB_Matrix C = NULL, M = NULL ;
34
35 if (nargin != 2 || nargout > 1)
36 {
37 mexErrMsgTxt ("Usage: " USAGE) ;
38 }
39
40 // get M (shallow copy)
41 M = GB_mx_mxArray_to_Matrix (pargin [0], "M", false, false) ;
42 if (M == NULL && !mxIsEmpty (pargin [0]))
43 {
44 FREE_ALL ;
45 mexErrMsgTxt ("M failed") ;
46 }
47
48 GrB_Index nrows, ncols ;
49 GrB_Matrix_nrows (&nrows, M) ;
50 GrB_Matrix_ncols (&ncols, M) ;
51
52 // get scalar
53 if (!mxIsScalar (pargin [1]))
54 {
55 FREE_ALL ;
56 mexErrMsgTxt ("scalar failed") ;
57 }
58
59 // C<M,struct> = scalar
60 if (mxIsSparse (pargin [1]))
61 {
62 mexErrMsgTxt ("scalar must not be sparse") ;
63 }
64
65 GrB_Type ctype = GB_mx_Type (pargin [1]) ;
66 GrB_Matrix_new (&C, ctype, nrows, ncols) ;
67
68 if (ctype == Complex && Complex != GxB_FC64)
69 {
70 // user-defined complex case
71 GxB_FC64_t *scalar = mxGetComplexDoubles (pargin [1]) ;
72 info = GxB_Matrix_subassign_UDT_(C, M, NULL, (void *) scalar,
73 GrB_ALL, nrows, GrB_ALL, ncols, GrB_DESC_RS) ;
74 if (info != GrB_SUCCESS)
75 {
76 mexErrMsgTxt ("GxB_Matrix_subassign_[complex] failed") ;
77 }
78 }
79 else
80 {
81 // built-in GraphBLAS types
82
83 #define CREATE(suffix,c_type) \
84 { \
85 c_type *scalar = (c_type *) mxGetData (pargin [1]) ; \
86 GxB_Matrix_subassign ## suffix (C, M, NULL, *scalar, \
87 GrB_ALL, nrows, GrB_ALL, ncols, GrB_DESC_RS) ; \
88 } \
89 break ;
90
91 switch (ctype->code)
92 {
93 case GB_BOOL_code : CREATE (_BOOL, bool ) ;
94 case GB_INT8_code : CREATE (_INT8, int8_t ) ;
95 case GB_INT16_code : CREATE (_INT16, int16_t ) ;
96 case GB_INT32_code : CREATE (_INT32, int32_t ) ;
97 case GB_INT64_code : CREATE (_INT64, int64_t ) ;
98 case GB_UINT8_code : CREATE (_UINT8, uint8_t ) ;
99 case GB_UINT16_code : CREATE (_UINT16, uint16_t ) ;
100 case GB_UINT32_code : CREATE (_UINT32, uint32_t ) ;
101 case GB_UINT64_code : CREATE (_UINT32, uint64_t ) ;
102 case GB_FP32_code : CREATE (_FP32, float ) ;
103 case GB_FP64_code : CREATE (_FP64, double ) ;
104 case GB_FC32_code : CREATE (_FC32, GxB_FC32_t) ;
105 case GB_FC64_code : CREATE (_FC64, GxB_FC64_t) ;
106 default: mexErrMsgTxt ("scalar type not supported") ;
107 }
108 }
109
110 // return result to MATLAB
111 pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C result", true) ;
112 FREE_ALL ;
113 }
114
115