NumPy (numarray) problem with C code

Marc Schellens m_schellens at hotmail.com
Thu Mar 11 12:15:25 CET 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