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