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