NumPy (numarray) problem with C code

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Marc Schellens

    NumPy (numarray) problem with C code

    Following the NumPy documentation, I took over some C code,
    but run into an error.
    Does anybody have a suggestion?
    Thanks,
    marc


    gdlpython.cpp:2 25: `PyArray_Type' undeclared (first use this function)

    #include <python2.3/Python.h>
    // python numarray is used
    #include <python2.3/numarray/arrayobject.h>

    // ...

    BaseGDL* FromPython( PyObject* pyObj)
    {
    PyObject *object;

    // following is line 225
    if( !PyArg_ParseTup le(pyObj, "O!", &PyArray_Typ e, &object))

    // please forget the rest or have a look and tell me if that will work
    // like I expect or if there is an obvious mistake
    // its my first time to interface to python

    {
    // non-array - try other
    PyErr_Clear();
    // string
    char* s;
    if( PyArg_ParseTupl e(pyObj, "s", s))
    return new DStringGDL( string(s));
    PyErr_Clear();
    // integer
    DLong l;
    if( PyArg_ParseTupl e(pyObj, "l", &l))
    return new DLongGDL( l);
    PyErr_Clear();
    // complex
    Py_complex c;
    if( PyArg_ParseTupl e(pyObj, "D", &c))
    {
    DComplexDbl cc( c.real, c.imag);
    return new DComplexDblGDL( cc);
    }
    PyErr_Clear();
    // float
    DDouble d;
    if( PyArg_ParseTupl e(pyObj, "d", &d))
    return new DDoubleGDL( d);

    throw GDLException( "FromPython : Cannot convert python object.") ;
    }

    // array type
    PyArrayObject* array = (PyArrayObject* ) object;

    int nDim = array->nd;
    int item_type = array->descr->type_num;

    // make array contiguous
    // array = static_cast< PyArrayObject*>
    // (PyArray_Contig uousFromObject( object,
    // item_type,
    // 0,0));
    array = (PyArrayObject* ) PyArray_Contigu ousFromObject( object,
    item_type,
    0,0);
    if( array == NULL)
    throw GDLException( "FromPython : Error making array contiguous.") ;

    size_t dimArr[ MAXRANK];
    if( nDim > MAXRANK)
    {
    Warning( "FromPython : Array has more than "+MAXRANK_S TR+
    " dimensions. Extending last one.");
    size_t lastDim = array->dimensions[ MAXRANK-1];
    for( size_t i=MAXRANK; i<nDim; ++i) lastDim *= array->dimensions[ i];
    for( size_t i=0; i<MAXRANK-1; ++i)
    dimArr[ i] = array->dimensions[ i];
    dimArr[ MAXRANK-1] = lastDim;
    nDim = MAXRANK;
    }
    else
    {
    for( size_t i=0; i<nDim; ++i)
    dimArr[ i] = array->dimensions[ i];
    }

    dimension dim( dimArr, nDim);

    switch( item_type)
    {
    // case PyArray_NOTYPE: //UNDEF***
    case PyArray_UBYTE: //BYTE
    return NewFromPyArrayO bject< DByteGDL>( dim, array);
    case PyArray_SHORT: //INT
    return NewFromPyArrayO bject< DIntGDL>( dim, array);
    case PyArray_INT: //LONG
    return NewFromPyArrayO bject< DLongGDL>( dim, array);
    case PyArray_FLOAT: //FLOAT
    return NewFromPyArrayO bject< DFloatGDL>( dim, array);
    case PyArray_DOUBLE: //DOUBLE
    return NewFromPyArrayO bject< DDoubleGDL>( dim, array);
    case PyArray_CFLOAT: //COMPLEX
    return NewFromPyArrayO bject< DComplexGDL>( dim, array);
    // case PyArray_NOTYPE: //STRING***
    // case PyArray_NOTYPE: //STRUCT***
    case PyArray_CDOUBLE : //COMPLEXDBL
    return NewFromPyArrayO bject< DComplexDblGDL> ( dim, array);
    // case PyArray_NOTYPE: //PTR***
    // case PyArray_NOTYPE: //OBJECT***
    case tUInt16: //UINT*
    return NewFromPyArrayO bject< DUIntGDL>( dim, array);
    case tUInt32: //ULONG*
    return NewFromPyArrayO bject< DULongGDL>( dim, array);
    default:
    throw GDLException( "FromPython : Unknown array type.") ;
    }

    return NULL; // compiler shut-up
    }



  • David M. Cooke

    #2
    Re: NumPy (numarray) problem with C code

    At some point, Marc Schellens <m_schellens@ho tmail.com> wrote:
    [color=blue]
    > Following the NumPy documentation, I took over some C code,
    > but run into an error.
    > Does anybody have a suggestion?
    > Thanks,
    > marc
    >
    >
    > gdlpython.cpp:2 25: `PyArray_Type' undeclared (first use this function)
    >
    > #include <python2.3/Python.h>
    > // python numarray is used
    > #include <python2.3/numarray/arrayobject.h>[/color]

    I don't know how you're compiling, but you're probably better off
    using
    #include "Python.h"
    #include "numarray/arrayobject.h"

    and specifying the proper include directory. This way you're not
    hardcoded to the Python version. distutils automatically adds the
    proper directory to the compile line, for instance.

    You're using numarray, so you may want to use the numarray interface
    instead of the Numeric compability interface. Include
    "numarray/libnumarray.h" instead of "numarray/arrayobject.h"
    [color=blue]
    > // ...
    >
    > BaseGDL* FromPython( PyObject* pyObj)
    > {
    > PyObject *object;
    >
    > // following is line 225
    > if( !PyArg_ParseTup le(pyObj, "O!", &PyArray_Typ e, &object))[/color]

    There is no such thing as PyArray_Type in numarray, and actually,
    there isn't one array type. I'd check for the specific
    string/long/complex/double types first (your code below)..
    [color=blue]
    > {
    > // non-array - try other
    > PyErr_Clear();
    > // string
    > char* s;
    > if( PyArg_ParseTupl e(pyObj, "s", s))
    > return new DStringGDL( string(s));
    > PyErr_Clear();
    > // integer
    > DLong l;
    > if( PyArg_ParseTupl e(pyObj, "l", &l))
    > return new DLongGDL( l);
    > PyErr_Clear();
    > // complex
    > Py_complex c;
    > if( PyArg_ParseTupl e(pyObj, "D", &c))
    > {
    > DComplexDbl cc( c.real, c.imag);
    > return new DComplexDblGDL( cc);
    > }
    > PyErr_Clear();
    > // float
    > DDouble d;
    > if( PyArg_ParseTupl e(pyObj, "d", &d))
    > return new DDoubleGDL( d);
    >
    > throw GDLException( "FromPython : Cannot convert python object.") ;
    > }[/color]

    and use NA_InputArray() to get the array. This returns NULL if it
    can't make the argument an array. You're using the Numeric
    compatibility functions below; you might as well use the numarray
    equivalents instead.
    [color=blue]
    > // array type
    > PyArrayObject* array = (PyArrayObject* ) object;
    >
    > int nDim = array->nd;
    > int item_type = array->descr->type_num;
    >
    > // make array contiguous
    > // array = static_cast< PyArrayObject*>
    > // (PyArray_Contig uousFromObject( object,
    > // item_type,
    > // 0,0));
    > array = (PyArrayObject* ) PyArray_Contigu ousFromObject( object,
    > item_type,
    > 0,0);
    > if( array == NULL)
    > throw GDLException( "FromPython : Error making array contiguous.") ;[/color]

    Note that array will be NULL also if it's not an array; this would be
    a better way to use it.

    Replace the above with something like

    PyArrayObject* array = NA_InputArray(o bject, tAny, NUM_C_ARRAY);
    if (array == NULLL) {
    throw GDLException( "FromPython : Error making array contiguous.") ;
    }
    int item_type = array->descr->type_num;

    Double-check the numarray C API documentation as to whether you should use
    NA_InputArray or NA_IoArray.

    Haven't looked at the following carefully:[color=blue]
    > size_t dimArr[ MAXRANK];
    > if( nDim > MAXRANK)
    > {
    > Warning( "FromPython : Array has more than "+MAXRANK_S TR+
    > " dimensions. Extending last one.");
    > size_t lastDim = array->dimensions[ MAXRANK-1];
    > for( size_t i=MAXRANK; i<nDim; ++i) lastDim *= array->dimensions[ i];
    > for( size_t i=0; i<MAXRANK-1; ++i)
    > dimArr[ i] = array->dimensions[ i];
    > dimArr[ MAXRANK-1] = lastDim;
    > nDim = MAXRANK;
    > }
    > else
    > {
    > for( size_t i=0; i<nDim; ++i)
    > dimArr[ i] = array->dimensions[ i];
    > }
    >
    > dimension dim( dimArr, nDim);[/color]


    Use the numarray types instead: tUInt8, tInt8, tInt16, tFloat64, etc:
    [color=blue]
    > switch( item_type)
    > {
    > // case PyArray_NOTYPE: //UNDEF***
    > case PyArray_UBYTE: //BYTE
    > return NewFromPyArrayO bject< DByteGDL>( dim, array);
    > case PyArray_SHORT: //INT
    > return NewFromPyArrayO bject< DIntGDL>( dim, array);
    > case PyArray_INT: //LONG
    > return NewFromPyArrayO bject< DLongGDL>( dim, array);
    > case PyArray_FLOAT: //FLOAT
    > return NewFromPyArrayO bject< DFloatGDL>( dim, array);
    > case PyArray_DOUBLE: //DOUBLE
    > return NewFromPyArrayO bject< DDoubleGDL>( dim, array);
    > case PyArray_CFLOAT: //COMPLEX
    > return NewFromPyArrayO bject< DComplexGDL>( dim, array);
    > // case PyArray_NOTYPE: //STRING***
    > // case PyArray_NOTYPE: //STRUCT***
    > case PyArray_CDOUBLE : //COMPLEXDBL
    > return NewFromPyArrayO bject< DComplexDblGDL> ( dim, array);
    > // case PyArray_NOTYPE: //PTR***
    > // case PyArray_NOTYPE: //OBJECT***
    > case tUInt16: //UINT*
    > return NewFromPyArrayO bject< DUIntGDL>( dim, array);
    > case tUInt32: //ULONG*
    > return NewFromPyArrayO bject< DULongGDL>( dim, array);
    > default:
    > throw GDLException( "FromPython : Unknown array type.") ;
    > }
    >
    > return NULL; // compiler shut-up
    > }[/color]

    --
    |>|\/|<
    /--------------------------------------------------------------------------\
    |David M. Cooke
    |cookedm(at)phy sics(dot)mcmast er(dot)ca

    Comment

    • Marc Schellens

      #3
      Re: NumPy (numarray) problem with C code

      Thanks,
      I think I was using the wrong documentation.
      marc


      David M. Cooke wrote:[color=blue]
      > At some point, Marc Schellens <m_schellens@ho tmail.com> wrote:
      >
      >[color=green]
      >>Following the NumPy documentation, I took over some C code,
      >>but run into an error.
      >>Does anybody have a suggestion?
      >>Thanks,
      >>marc
      >>
      >>
      >>gdlpython.cpp :225: `PyArray_Type' undeclared (first use this function)
      >>
      >>#include <python2.3/Python.h>
      >>// python numarray is used
      >>#include <python2.3/numarray/arrayobject.h>[/color]
      >
      >
      > I don't know how you're compiling, but you're probably better off
      > using
      > #include "Python.h"
      > #include "numarray/arrayobject.h"
      >
      > and specifying the proper include directory. This way you're not
      > hardcoded to the Python version. distutils automatically adds the
      > proper directory to the compile line, for instance.
      >
      > You're using numarray, so you may want to use the numarray interface
      > instead of the Numeric compability interface. Include
      > "numarray/libnumarray.h" instead of "numarray/arrayobject.h"
      >
      >[color=green]
      >>// ...
      >>
      >>BaseGDL* FromPython( PyObject* pyObj)
      >>{
      >> PyObject *object;
      >>
      >>// following is line 225
      >> if( !PyArg_ParseTup le(pyObj, "O!", &PyArray_Typ e, &object))[/color]
      >
      >
      > There is no such thing as PyArray_Type in numarray, and actually,
      > there isn't one array type. I'd check for the specific
      > string/long/complex/double types first (your code below)..
      >
      >[color=green]
      >> {
      >> // non-array - try other
      >> PyErr_Clear();
      >> // string
      >> char* s;
      >> if( PyArg_ParseTupl e(pyObj, "s", s))
      >> return new DStringGDL( string(s));
      >> PyErr_Clear();
      >> // integer
      >> DLong l;
      >> if( PyArg_ParseTupl e(pyObj, "l", &l))
      >> return new DLongGDL( l);
      >> PyErr_Clear();
      >> // complex
      >> Py_complex c;
      >> if( PyArg_ParseTupl e(pyObj, "D", &c))
      >> {
      >> DComplexDbl cc( c.real, c.imag);
      >> return new DComplexDblGDL( cc);
      >> }
      >> PyErr_Clear();
      >> // float
      >> DDouble d;
      >> if( PyArg_ParseTupl e(pyObj, "d", &d))
      >> return new DDoubleGDL( d);
      >>
      >> throw GDLException( "FromPython : Cannot convert python object.") ;
      >> }[/color]
      >
      >
      > and use NA_InputArray() to get the array. This returns NULL if it
      > can't make the argument an array. You're using the Numeric
      > compatibility functions below; you might as well use the numarray
      > equivalents instead.
      >
      >[color=green]
      >> // array type
      >> PyArrayObject* array = (PyArrayObject* ) object;
      >>
      >> int nDim = array->nd;
      >> int item_type = array->descr->type_num;
      >>
      >> // make array contiguous
      >>// array = static_cast< PyArrayObject*>
      >>// (PyArray_Contig uousFromObject( object,
      >>// item_type,
      >>// 0,0));
      >> array = (PyArrayObject* ) PyArray_Contigu ousFromObject( object,
      >> item_type,
      >> 0,0);
      >> if( array == NULL)
      >> throw GDLException( "FromPython : Error making array contiguous.") ;[/color]
      >
      >
      > Note that array will be NULL also if it's not an array; this would be
      > a better way to use it.
      >
      > Replace the above with something like
      >
      > PyArrayObject* array = NA_InputArray(o bject, tAny, NUM_C_ARRAY);
      > if (array == NULLL) {
      > throw GDLException( "FromPython : Error making array contiguous.") ;
      > }
      > int item_type = array->descr->type_num;
      >
      > Double-check the numarray C API documentation as to whether you should use
      > NA_InputArray or NA_IoArray.
      >
      > Haven't looked at the following carefully:
      >[color=green]
      >> size_t dimArr[ MAXRANK];
      >> if( nDim > MAXRANK)
      >> {
      >> Warning( "FromPython : Array has more than "+MAXRANK_S TR+
      >> " dimensions. Extending last one.");
      >> size_t lastDim = array->dimensions[ MAXRANK-1];
      >> for( size_t i=MAXRANK; i<nDim; ++i) lastDim *= array->dimensions[ i];
      >> for( size_t i=0; i<MAXRANK-1; ++i)
      >> dimArr[ i] = array->dimensions[ i];
      >> dimArr[ MAXRANK-1] = lastDim;
      >> nDim = MAXRANK;
      >> }
      >> else
      >> {
      >> for( size_t i=0; i<nDim; ++i)
      >> dimArr[ i] = array->dimensions[ i];
      >> }
      >>
      >> dimension dim( dimArr, nDim);[/color]
      >
      >
      >
      > Use the numarray types instead: tUInt8, tInt8, tInt16, tFloat64, etc:
      >
      >[color=green]
      >> switch( item_type)
      >> {
      >> // case PyArray_NOTYPE: //UNDEF***
      >> case PyArray_UBYTE: //BYTE
      >> return NewFromPyArrayO bject< DByteGDL>( dim, array);
      >> case PyArray_SHORT: //INT
      >> return NewFromPyArrayO bject< DIntGDL>( dim, array);
      >> case PyArray_INT: //LONG
      >> return NewFromPyArrayO bject< DLongGDL>( dim, array);
      >> case PyArray_FLOAT: //FLOAT
      >> return NewFromPyArrayO bject< DFloatGDL>( dim, array);
      >> case PyArray_DOUBLE: //DOUBLE
      >> return NewFromPyArrayO bject< DDoubleGDL>( dim, array);
      >> case PyArray_CFLOAT: //COMPLEX
      >> return NewFromPyArrayO bject< DComplexGDL>( dim, array);
      >> // case PyArray_NOTYPE: //STRING***
      >> // case PyArray_NOTYPE: //STRUCT***
      >> case PyArray_CDOUBLE : //COMPLEXDBL
      >> return NewFromPyArrayO bject< DComplexDblGDL> ( dim, array);
      >> // case PyArray_NOTYPE: //PTR***
      >> // case PyArray_NOTYPE: //OBJECT***
      >> case tUInt16: //UINT*
      >> return NewFromPyArrayO bject< DUIntGDL>( dim, array);
      >> case tUInt32: //ULONG*
      >> return NewFromPyArrayO bject< DULongGDL>( dim, array);
      >> default:
      >> throw GDLException( "FromPython : Unknown array type.") ;
      >> }
      >>
      >> return NULL; // compiler shut-up
      >>}[/color]
      >
      >[/color]

      Comment

      Working...