1 //------------------------------------------------------------------------------
2 // GB_mx_mxArray_to_indices
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 // Get a list of indices from MATLAB
11
12 #include "GB_mex.h"
13
GB_mx_mxArray_to_indices(GrB_Index ** handle,const mxArray * I_matlab,GrB_Index * ni,GrB_Index Icolon[3],bool * I_is_list)14 bool GB_mx_mxArray_to_indices // true if successful, false otherwise
15 (
16 GrB_Index **handle, // index array returned
17 const mxArray *I_matlab, // MATLAB mxArray to get
18 GrB_Index *ni, // length of I, or special
19 GrB_Index Icolon [3], // for all but GB_LIST
20 bool *I_is_list // true if GB_LIST
21 )
22 {
23
24 (*handle) = NULL ;
25
26 mxArray *X ;
27 GrB_Index *I ;
28
29 if (I_matlab == NULL || mxIsEmpty (I_matlab))
30 {
31 I = (GrB_Index *) GrB_ALL ; // like the ":" in C=A(:,j)
32 (*ni) = 0 ;
33 (*handle) = I ;
34 (*I_is_list) = false ;
35 // Icolon not used
36 }
37 else
38 {
39 if (mxIsStruct (I_matlab))
40 {
41 // a struct with 3 integers: I.begin, I.inc, I.end
42 (*I_is_list) = false ;
43
44 // look for I.begin (required)
45 int fieldnumber = mxGetFieldNumber (I_matlab, "begin") ;
46 if (fieldnumber < 0)
47 {
48 mexWarnMsgIdAndTxt ("GB:warn","I.begin missing") ;
49 return (false) ;
50 }
51 X = mxGetFieldByNumber (I_matlab, 0, fieldnumber) ;
52 Icolon [GxB_BEGIN] = (int64_t) mxGetScalar (X) ;
53
54 // look for I.end (required)
55 fieldnumber = mxGetFieldNumber (I_matlab, "end") ;
56 if (fieldnumber < 0)
57 {
58 mexWarnMsgIdAndTxt ("GB:warn","I.end missing") ;
59 return (false) ;
60 }
61 mxArray *X ;
62 X = mxGetFieldByNumber (I_matlab, 0, fieldnumber) ;
63 Icolon [GxB_END] = (int64_t) mxGetScalar (X) ;
64
65 // look for I.inc (optional)
66 fieldnumber = mxGetFieldNumber (I_matlab, "inc") ;
67 if (fieldnumber < 0)
68 {
69 (*ni) = GxB_RANGE ;
70 Icolon [GxB_INC] = 1 ;
71 }
72 else
73 {
74 //
75 X = mxGetFieldByNumber (I_matlab, 0, fieldnumber) ;
76 int64_t iinc = (int64_t) mxGetScalar (X) ;
77 if (iinc == 0)
78 {
79 // this can be either a stride, or backwards. Either
80 // one works the same, but try a mixture, just for testing.
81 (*ni) = (Icolon [GxB_BEGIN] % 2) ?
82 GxB_STRIDE : GxB_BACKWARDS ;
83 Icolon [GxB_INC] = 0 ;
84 }
85 else if (iinc > 0)
86 {
87 (*ni) = GxB_STRIDE ;
88 Icolon [GxB_INC] = iinc ;
89 }
90 else
91 {
92 // GraphBLAS must be given the magnitude of the stride
93 (*ni) = GxB_BACKWARDS ;
94 Icolon [GxB_INC] = -iinc ;
95 }
96 }
97 (*handle) = Icolon ;
98
99 }
100 else
101 {
102 if (!mxIsClass (I_matlab, "uint64"))
103 {
104 mexWarnMsgIdAndTxt ("GB:warn","indices must be uint64") ;
105 return (false) ;
106 }
107
108 (*I_is_list) = true ;
109 I = mxGetData (I_matlab) ;
110 (*ni) = (uint64_t) mxGetNumberOfElements (I_matlab) ;
111 (*handle) = I ;
112 }
113 }
114
115 return (true) ;
116 }
117
118