Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling numpy function from C-code

I'm trying to move some MatLab code with Mex extensions into Python with numpy and scipy libraries. Using this wonderful tutorial http://www.scipy.org/Cookbook/C_Extensions/NumPy_arrays, I quite quickly adopt C-functions for calling from the Python. But some C-functions call MatLab functions, so I have to substitute this code by calling numpy and scipy functions from C-code.

I've tried to do something like this Extending and Embedding the Python Interpreter. However, I faced the problem: how to pass array into the function argument. Moreover this long way to find function in module and then build tuple for arguments doesn't seems very elegant.

So, how to call sum function in numpy module from C-code, for example?

I'll appreciate for any ideas or links. Ruben

P.S. Here an example:

    PyObject *feedback(PyObject *self, PyObject *args){
    PyArrayObject *Vecin;
    double mp=0,ret;
    if( !PyArg_ParseTuple(args,"O!d",&PyArray_Type,&Vecin,&mp)
      ||  Vecin == NULL ) return NULL;
    /* make python string with module name */
    PyObject *pName = PyString_FromString("numpy");
    if( pName == NULL){
        fprintf(stderr,"Couldn\'t setup string %s\n","numpy");
        return NULL;
    }
    /* import module */
    PyObject *pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    if( pModule == NULL){
        fprintf(stderr,"Couldn\'t find module %s\n","numpy");
        return NULL;
    }
    /* get module dict */
    PyObject *dic = PyModule_GetDict(pModule);
    if( dic == NULL){
        fprintf(stderr,"Couldn\'t find dic in module %s\n","numpy");
        return NULL;
    }
    /* find function */
    PyObject *pFunction = PyDict_GetItemString(dic, "sum");
    Py_DECREF(dic);
    if( pFunction == NULL){
        fprintf(stderr,"Couldn\'t find function  %s in dic\n","sum");
        return NULL;
    }
    Py_DECREF(pModule);
    /* create typle for new function argument */
    PyObject *inarg = PyTuple_New(1);
    if( inarg == NULL){
        fprintf(stderr,"Cannot convert to Build in Value\n");
        return NULL;
    }
    /* set one input paramter */
    PyTuple_SetItem(inarg, 0, (PyObject*)Vecin);
    /* call sunction from module and get result*/
    PyObject *value = PyObject_CallObject(pFunction, inarg);
    if( value == NULL){
        fprintf(stderr,"Function return NULL pointer\n");
        return NULL;
    }
    Py_DECREF(pFunction);
    if( !PyArg_ParseTuple(value,"d",&ret) ) return NULL;
    return Py_BuildValue("d",ret*mp);
}

Result of

>>print mymod.FeedBack(np.array([1.,2.,3.,4.,5.]),2)


Traceback (most recent call last):
  File "mymodtest.py", line 10, in <module>
    print mymod.FeedBack(np.array([1.,2.,3.,4.,5.]),2)
SystemError: new style getargs format but argument is not a tuple
Segmentation fault
like image 537
rth Avatar asked Nov 03 '22 23:11

rth


1 Answers

The NumPy C API has PyArray_Sum:

PyObject *sum = PyArray_Sum(arr, NPY_MAXDIMS, PyArray_DESCR(arr)->type_num, NULL);
like image 92
ecatmur Avatar answered Nov 12 '22 21:11

ecatmur