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) ;
}
|