开发者

typecasting PyArrayObject data to a C array

I want to work with my Numpy arrays in a C extension. Many examples in this case uses the structure of PyArrayObject,

array->data , array->strides[0] , array->strides[1] , ...

pointers in order to reach the data, if I wanted to reach my array in a more familiar (or tidier) way to me, with indices like

array[i][j]

how should I proceed so? Should I typecast (bool *) array->data and work with the C array I created? (my elements are bools)

My function declaration for now is (not finished, of course)

static PyObject *
xor_masking(PyObject *self, PyObject *args)
{

PyObject *input;
PyObject *mask;
PyObject *adjacency;
PyObject *state;
PyArrayObject *arr_mask;
PyArrayObject *arr_adjacency;
PyArrayObject *arr_state;
PyArrayObject *arr_next_state;

double sum;
int counter_node, n_nodes;

/*  PyArg_ParseTuple
 *  checks if from args, the pointers of type "O" can be extracted, and extracts them
 */

if (!PyArg_ParseTuple(args, "OOO:xor_masking_C", &mask, &adjacency, &state))
    return NULL;

/*
 *  The pointer returned by PyArray_ContiguousFromObject is typecasted to
 *  a PyArrayObject Pointer and array is pointed to the same address.
 */

arr_mask = (PyArrayObject *)
PyArray_ContiguousFromObject(mask, PyArray_BOOL, 2, 2);
arr_adjacency = (PyArrayObject *)
PyArray_ContiguousFromObject(adjacency, PyArray_BOOL, 2, 2);
arr_state = (PyArrayObject *)
PyArray_ContiguousFromObject(state, PyArray_BOOL, 2, 2);

if (array == NULL)
    return NULL;

int n_mask_0 = mask->dimensions[0];
int n_mask_1 = mask->dimensions[1];
int n_adjacency_0 = adjacency->dimensions[0];
int n_adjacency_1 = adjacency->dimensions[1];
int n_state_0 = state->dimensions[0];
int n_nodes = n_state_0;
/*
 * if the dimensions don't match, return NULL
 */

bool c_mask[n_nodes][n_nodes];

if (n_mask_0 != n_mask_1 || n_adjacency_0 != n_adjacency_1 ||
n_adjacency_0 != n_mask_0 || n_adjacency_0 != n_adjacency_1) {
    return NULL;
}

/*
 *    The 2D arrays are introduced as follows
 *    array[i][j] = (array->data + i*array->strides[0] + j*array->strides[1])
 */

for (counter_node = 0; i < n_mask; i++){
    *row_start = (array->data + i*array->strides[0]);
}


//Py_DECREF();

//return PyFloat_FromDouble();
}
开发者_如何转开发

Thanks!


I'm not sure if this answers your question but, to reach your NumPy data in C, you could try to create an iterator to loop over your array in C. It doesn't give you indexing you're after ([i][j]) but it covers the entire array

static PyObject *func1(PyObject *self, PyObject *args) {
    PyArrayObject *X;
    int ndX;
    npy_intp *shapeX;
    NpyIter *iter;
    NpyIter_IterNextFunc *iternext;
    PyArray_Descr *dtype;
    double **dataptr;

    PyArg_ParseTuple(args, "O!", &PyArray_Type, &X);
    ndX = PyArray_NDIM(X);
    shapeX = PyArray_SHAPE(X);
    dtype = PyArray_DescrFromType(NPY_DOUBLE);
    iter = NpyIter_New(X, NPY_ITER_READONLY, NPY_KEEPORDER, NPY_NO_CASTING, dtype);
    iternext = NpyIter_GetIterNext(iter, NULL);
    dataptr = (double **) NpyIter_GetDataPtrArray(iter);
    do {
        cout << **dataptr << endl; //Do something with the data in your array
    } while (iternext(iter));   
    NpyIter_Deallocate(iter);
    return Py_BuildValue(...);
}


I think you'll want to look at this: http://docs.scipy.org/doc/numpy/reference/c-api.array.html

In particular,

void* PyArray_GETPTR3(PyObject* obj, <npy_intp> i, <npy_intp> j, <npy_intp> k)

and friends. Those are the functions that David Heffernan would be surprised if the API didn't provide.


This should help you.

http://mail.scipy.org/pipermail/numpy-discussion/2003-November/014837.html


This is the dirtiest of all answers here, I guess, but 2 years ago, I ended up implementing this function like this:

Just adding it here for documenting it. If you are reading this, you should check out other solutions, which are better.

https://gist.github.com/mehmetalianil/6643299

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜