File: GB_mx_mxArray_to_indices.c

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (159 lines) | stat: -rw-r--r-- 5,093 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//------------------------------------------------------------------------------
// GB_mx_mxArray_to_indices: get a list of indices
//------------------------------------------------------------------------------

// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2025, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//------------------------------------------------------------------------------

// Get a list of indices from a MATLAB array or struct with I.begin, or
// a MATLAB struct holding a GraphBLAS GrB_Vector.

#include "GB_mex.h"

bool GB_mx_mxArray_to_indices       // true if successful, false otherwise
(
    // input:
    const mxArray *I_builtin,       // built-in mxArray to get
    // output:
    uint64_t **I_handle,            // index array
    uint64_t *ni,                   // length of I, or special
    uint64_t Icolon [3],            // for all but GB_LIST
    bool *I_is_list,                // true if GB_LIST
    GrB_Vector *I_vector            // non-NULL if found
)
{

    (*I_handle) = NULL ;
    if (I_vector != NULL)
    {
        (*I_vector) = NULL ;
    }

    mxArray *X ;
    uint64_t *I ;

    if (I_builtin == NULL || mxIsEmpty (I_builtin))
    {

        //----------------------------------------------------------------------
        // I is NULL or empty; treat as ":"
        //----------------------------------------------------------------------

        I = (uint64_t *) GrB_ALL ;       // like the ":" in C=A(:,j)
        (*ni) = 0 ;
        (*I_handle) = I ;
        (*I_is_list) = false ;
        // Icolon not used

    }
    else if (mxIsStruct (I_builtin) &&
        mxGetFieldNumber (I_builtin, "begin") >= 0)
    {

        //----------------------------------------------------------------------
        // I is a struct with I.begin
        //----------------------------------------------------------------------

        // a struct with 3 integers: I.begin, I.inc, I.end
        (*I_is_list) = false ;

        // look for I.begin (required)
        int fieldnumber = mxGetFieldNumber (I_builtin, "begin") ;
        if (fieldnumber < 0)
        {
            mexWarnMsgIdAndTxt ("GB:warn","I.begin missing") ;
            return (false) ;
        }
        X = mxGetFieldByNumber (I_builtin, 0, fieldnumber) ;
        Icolon [GxB_BEGIN] = (int64_t) mxGetScalar (X) ;

        // look for I.end (required)
        fieldnumber = mxGetFieldNumber (I_builtin, "end") ;
        if (fieldnumber < 0)
        {
            mexWarnMsgIdAndTxt ("GB:warn","I.end missing") ;
            return (false) ;
        }
        mxArray *X ;
        X = mxGetFieldByNumber (I_builtin, 0, fieldnumber) ;
        Icolon [GxB_END] = (int64_t) mxGetScalar (X) ;

        // look for I.inc (optional)
        fieldnumber = mxGetFieldNumber (I_builtin, "inc") ;
        if (fieldnumber < 0)
        {
            (*ni) = GxB_RANGE ;
            Icolon [GxB_INC] = 1 ;
        }
        else
        {
            X = mxGetFieldByNumber (I_builtin, 0, fieldnumber) ;
            int64_t iinc = (int64_t) mxGetScalar (X) ;
            if (iinc == 0)
            {
                // this can be either a stride, or backwards.  Either 
                // one works the same, but try a mixture, just for testing.
                (*ni) = (Icolon [GxB_BEGIN] % 2) ?
                    GxB_STRIDE : GxB_BACKWARDS ;
                Icolon [GxB_INC] = 0 ;
            }
            else if (iinc > 0)
            {
                (*ni) = GxB_STRIDE ;
                Icolon [GxB_INC] = iinc ;
            }
            else
            {
                // GraphBLAS must be given the magnitude of the stride
                (*ni) = GxB_BACKWARDS ;
                Icolon [GxB_INC] = -iinc ;
            }
        }
        (*I_handle) = Icolon ;

    }
    else if (mxIsClass (I_builtin, "uint64") && I_vector == NULL)
    {

        //----------------------------------------------------------------------
        // I is a built-in array of type uint64
        //----------------------------------------------------------------------

        (*I_is_list) = true ;
        I = mxGetData (I_builtin) ;
        (*ni) = (uint64_t) mxGetNumberOfElements (I_builtin) ;
        (*I_handle) = I ;

    }
    else if (I_vector != NULL)
    {

        //----------------------------------------------------------------------
        // I could be a GrB_Vector held as a struct or MATLAB matrix
        //----------------------------------------------------------------------

        (*I_vector) = GB_mx_mxArray_to_Vector (I_builtin, "I_vector",
            true, true) ;
        if ((*I_vector) == NULL)
        {
            mexWarnMsgIdAndTxt ("GB:warn", "indices invalid") ;
            return (false) ;
        }

    }
    else
    {

        //----------------------------------------------------------------------
        // I not recognized
        //----------------------------------------------------------------------

        mexWarnMsgIdAndTxt ("GB:warn", "indices invalid") ;
        return (false) ;
    }

    return (true) ;
}