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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With