module_header = \ """ // blitz must be first, or you get have issues with isnan defintion. #include #include "Python.h" #include "Numeric/arrayobject.h" // Use Exception stuff from SCXX #include "PWOBase.h" #include #include #include static PyArrayObject* obj_to_numpy(PyObject* py_obj, char* name, int Ndims, int numeric_type ) { PyArrayObject* arr_obj = NULL; // Make sure input is an array. if (!PyArray_Check(py_obj)) throw PWException(PyExc_TypeError, "Input array *name* must be an array."); arr_obj = (PyArrayObject*) py_obj; // Make sure input has correct numeric type. if (arr_obj->descr->type_num != numeric_type) { // This should be more explicit: // Put the desired and actual type in the message. // printf("%d,%d",arr_obj->descr->type_num,numeric_type); throw PWException(PyExc_TypeError, "Input array *name* is the wrong numeric type."); } // Make sure input has correct rank (defined as number of dimensions). // Currently, all arrays must have the same shape. // Broadcasting is not supported. // ... if (arr_obj->nd != Ndims) { // This should be more explicit: // Put the desired and actual dimensionality in message. throw PWException(PyExc_TypeError, "Input array *name* has wrong number of dimensions."); } // check the size of arrays. Acutally, the size of the "views" really // needs checking -- not the arrays. // ... // Any need to deal with INC/DEC REFs? Py_INCREF(py_obj); return arr_obj; } // simple meta-program templates to specify python typecodes // for each of the numeric types. template class py_type{public: enum {code = 100};}; class py_type{public: enum {code = PyArray_CHAR};}; class py_type{public: enum { code = PyArray_UBYTE};}; class py_type{public: enum { code = PyArray_SHORT};}; class py_type{public: enum { code = PyArray_INT};}; class py_type{public: enum { code = PyArray_LONG};}; class py_type{public: enum { code = PyArray_FLOAT};}; class py_type{public: enum { code = PyArray_DOUBLE};}; class py_type >{public: enum { code = PyArray_CFLOAT};}; class py_type >{public: enum { code = PyArray_CDOUBLE};}; template static blitz::Array py_to_blitz(PyObject* py_obj,char* name) { PyArrayObject* arr_obj = obj_to_numpy(py_obj,name,N,py_type::code); blitz::TinyVector shape(0); blitz::TinyVector strides(0); int stride_acc = 1; //for (int i = N-1; i >=0; i--) for (int i = 0; i < N; i++) { shape[i] = arr_obj->dimensions[i]; strides[i] = arr_obj->strides[i]/sizeof(T); } //return blitz::Array((T*) arr_obj->data,shape, return blitz::Array((T*) arr_obj->data,shape,strides, blitz::neverDeleteData); } template static T py_to_scalar(PyObject* py_obj,char* name) { //never used. return (T) 0; } template<> static int py_to_scalar(PyObject* py_obj,char* name) { return (int) PyLong_AsLong(py_obj); } template<> static long py_to_scalar(PyObject* py_obj,char* name) { return (long) PyLong_AsLong(py_obj); } template<> static float py_to_scalar(PyObject* py_obj,char* name) { return (float) PyFloat_AsDouble(py_obj); } template<> static double py_to_scalar(PyObject* py_obj,char* name) { return PyFloat_AsDouble(py_obj); } // complex not checked. template<> static std::complex py_to_scalar >(PyObject* py_obj, char* name) { return std::complex((float) PyComplex_RealAsDouble(py_obj), (float) PyComplex_RealAsDouble(py_obj)); } template<> static std::complex py_to_scalar >( PyObject* py_obj,char* name) { return std::complex(PyComplex_RealAsDouble(py_obj), PyComplex_RealAsDouble(py_obj)); } """