diff options
Diffstat (limited to 'weave/code_blocks.py')
-rwxr-xr-x | weave/code_blocks.py | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/weave/code_blocks.py b/weave/code_blocks.py new file mode 100755 index 000000000..bf014f7a7 --- /dev/null +++ b/weave/code_blocks.py @@ -0,0 +1,135 @@ +module_header = \ +""" +// blitz must be first, or you get have issues with isnan defintion. +#include <blitz/array.h> + +#include "Python.h" +#include "Numeric/arrayobject.h" + +// Use Exception stuff from SCXX +#include "PWOBase.h" + +#include <stdio.h> +#include <math.h> +#include <complex> + +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 T> +class py_type{public: enum {code = 100};}; +class py_type<char>{public: enum {code = PyArray_CHAR};}; +class py_type<unsigned char>{public: enum { code = PyArray_UBYTE};}; +class py_type<short>{public: enum { code = PyArray_SHORT};}; +class py_type<int>{public: enum { code = PyArray_INT};}; +class py_type<long>{public: enum { code = PyArray_LONG};}; +class py_type<float>{public: enum { code = PyArray_FLOAT};}; +class py_type<double>{public: enum { code = PyArray_DOUBLE};}; +class py_type<complex<float> >{public: enum { code = PyArray_CFLOAT};}; +class py_type<complex<double> >{public: enum { code = PyArray_CDOUBLE};}; + +template<class T, int N> +static blitz::Array<T,N> py_to_blitz(PyObject* py_obj,char* name) +{ + + PyArrayObject* arr_obj = obj_to_numpy(py_obj,name,N,py_type<T>::code); + + blitz::TinyVector<int,N> shape(0); + blitz::TinyVector<int,N> 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,N>((T*) arr_obj->data,shape, + return blitz::Array<T,N>((T*) arr_obj->data,shape,strides, + blitz::neverDeleteData); +} + +template<class T> +static T py_to_scalar(PyObject* py_obj,char* name) +{ + //never used. + return (T) 0; +} +template<> +static int py_to_scalar<int>(PyObject* py_obj,char* name) +{ + return (int) PyLong_AsLong(py_obj); +} + +template<> +static long py_to_scalar<long>(PyObject* py_obj,char* name) +{ + return (long) PyLong_AsLong(py_obj); +} +template<> +static float py_to_scalar<float>(PyObject* py_obj,char* name) +{ + return (float) PyFloat_AsDouble(py_obj); +} +template<> +static double py_to_scalar<double>(PyObject* py_obj,char* name) +{ + return PyFloat_AsDouble(py_obj); +} + +// complex not checked. +template<> +static std::complex<float> py_to_scalar<std::complex<float> >(PyObject* py_obj, + char* name) +{ + return std::complex<float>((float) PyComplex_RealAsDouble(py_obj), + (float) PyComplex_RealAsDouble(py_obj)); +} +template<> +static std::complex<double> py_to_scalar<std::complex<double> >( + PyObject* py_obj,char* name) +{ + return std::complex<double>(PyComplex_RealAsDouble(py_obj), + PyComplex_RealAsDouble(py_obj)); +} +"""
\ No newline at end of file |