NumPy (numarray) problem with C code
Marc Schellens
m_schellens at hotmail.com
Thu Mar 11 06:15:25 EST 2004
Thanks,
I think I was using the wrong documentation.
marc
David M. Cooke wrote:
> At some point, Marc Schellens <m_schellens at hotmail.com> wrote:
>
>
>>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>
>
>
> 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"
>
>
>>// ...
>>
>>BaseGDL* FromPython( PyObject* pyObj)
>>{
>> PyObject *object;
>>
>>// following is line 225
>> if( !PyArg_ParseTuple(pyObj, "O!", &PyArray_Type, &object))
>
>
> 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)..
>
>
>> {
>> // non-array - try other
>> PyErr_Clear();
>> // string
>> char* s;
>> if( PyArg_ParseTuple(pyObj, "s", s))
>> return new DStringGDL( string(s));
>> PyErr_Clear();
>> // integer
>> DLong l;
>> if( PyArg_ParseTuple(pyObj, "l", &l))
>> return new DLongGDL( l);
>> PyErr_Clear();
>> // complex
>> Py_complex c;
>> if( PyArg_ParseTuple(pyObj, "D", &c))
>> {
>> DComplexDbl cc( c.real, c.imag);
>> return new DComplexDblGDL( cc);
>> }
>> PyErr_Clear();
>> // float
>> DDouble d;
>> if( PyArg_ParseTuple(pyObj, "d", &d))
>> return new DDoubleGDL( d);
>>
>> throw GDLException( "FromPython: Cannot convert python object.") ;
>> }
>
>
> 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.
>
>
>> // 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_ContiguousFromObject( object,
>>// item_type,
>>// 0,0));
>> array = (PyArrayObject*) PyArray_ContiguousFromObject( object,
>> item_type,
>> 0,0);
>> if( array == NULL)
>> throw GDLException( "FromPython: Error making array contiguous.") ;
>
>
> 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(object, 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:
>
>> size_t dimArr[ MAXRANK];
>> if( nDim > MAXRANK)
>> {
>> Warning( "FromPython: Array has more than "+MAXRANK_STR+
>> " 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);
>
>
>
> Use the numarray types instead: tUInt8, tInt8, tInt16, tFloat64, etc:
>
>
>> switch( item_type)
>> {
>> // case PyArray_NOTYPE: //UNDEF***
>> case PyArray_UBYTE: //BYTE
>> return NewFromPyArrayObject< DByteGDL>( dim, array);
>> case PyArray_SHORT: //INT
>> return NewFromPyArrayObject< DIntGDL>( dim, array);
>> case PyArray_INT: //LONG
>> return NewFromPyArrayObject< DLongGDL>( dim, array);
>> case PyArray_FLOAT: //FLOAT
>> return NewFromPyArrayObject< DFloatGDL>( dim, array);
>> case PyArray_DOUBLE: //DOUBLE
>> return NewFromPyArrayObject< DDoubleGDL>( dim, array);
>> case PyArray_CFLOAT: //COMPLEX
>> return NewFromPyArrayObject< DComplexGDL>( dim, array);
>> // case PyArray_NOTYPE: //STRING***
>> // case PyArray_NOTYPE: //STRUCT***
>> case PyArray_CDOUBLE: //COMPLEXDBL
>> return NewFromPyArrayObject< DComplexDblGDL>( dim, array);
>> // case PyArray_NOTYPE: //PTR***
>> // case PyArray_NOTYPE: //OBJECT***
>> case tUInt16: //UINT*
>> return NewFromPyArrayObject< DUIntGDL>( dim, array);
>> case tUInt32: //ULONG*
>> return NewFromPyArrayObject< DULongGDL>( dim, array);
>> default:
>> throw GDLException( "FromPython: Unknown array type.") ;
>> }
>>
>> return NULL; // compiler shut-up
>>}
>
>
More information about the Python-list
mailing list