5

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
5
  • does it help you: stackoverflow.com/a/15670672/1031417 ? Commented Apr 18, 2013 at 3:41
  • @0x90 probably not. I don't use any wrapper or pretranslators, from python to c, because original code in mex extensions is a c-code. Commented Apr 18, 2013 at 3:48
  • Is using Cython an option? It has special support for NumPy and it's much easier to work with than the Python C API. Commented Apr 18, 2013 at 15:18
  • @larsmans. I know, thank you! The problem is in c-code which was written for MatLab as mex module. I'd like to keep this code intact. Commented Apr 18, 2013 at 15:54
  • @rth: you can wrap C code with Cython. Commented Apr 18, 2013 at 17:34

1 Answer 1

2

The NumPy C API has PyArray_Sum:

PyObject *sum = PyArray_Sum(arr, NPY_MAXDIMS, PyArray_DESCR(arr)->type_num, NULL);
Sign up to request clarification or add additional context in comments.

6 Comments

It is nice, thank you. But sum-function just an example. What about all other function in numpy and scipy? Do they all have C API? It really puzzles me, how to form input argument tuple for numpy/scipy functions with arrays.
@rth you form the input argument tuple as you would any other Python function, or just use PyObject_CallFunctionObjArgs.
@eatmur I've changed in my example above from PyObject *value = PyObject_CallObject(pFunction, inarg); to PyObject *value = PyObject_CallFunctionObjArgs(pFunction, Vecin,NULL); and it returns SystemError: new style getargs format but argument is not a tuple Segmentation fault
@rth are you expecting the function to return a tuple?
@rth also, which call is failing?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.