diff options
Diffstat (limited to 'scipy/base/src/arraymethods.c')
-rw-r--r-- | scipy/base/src/arraymethods.c | 115 |
1 files changed, 88 insertions, 27 deletions
diff --git a/scipy/base/src/arraymethods.c b/scipy/base/src/arraymethods.c index dc7b479ad..f8553f280 100644 --- a/scipy/base/src/arraymethods.c +++ b/scipy/base/src/arraymethods.c @@ -249,76 +249,138 @@ array_swapaxes(PyArrayObject *self, PyObject *args) return PyArray_SwapAxes(self, axis1, axis2); } -static char doc_getfield[] = "m.field(type, offset) returns a field "\ +static int array_type_set(PyArrayObject *, PyObject *); + +static char doc_getfield[] = "m.getfield(dtype, offset) returns a field "\ " of the given array as a certain type. A field is a view of "\ " the array's data with each itemsize determined by the given type"\ " and the offset into the current array."; static PyObject * -PyArray_GetField(PyArrayObject *self, PyArray_Typecode *type, - int offset) +PyArray_GetField(PyArrayObject *self, PyObject *dtype, int offset) { PyObject *ret=NULL; + PyArray_Typecode typecode = {PyArray_NOTYPE, 0, 0}; + int tupletype = 0; + + if (PyTuple_Check(dtype)) { + PyArray_Dims dim = {NULL, -1}; + if (PyTuple_GET_SIZE(dtype) != 2) { + PyErr_SetString(PyExc_TypeError, + "tuple for data-type must be length 2"); + return NULL; + } + if (PyArray_TypecodeConverter(PyTuple_GET_ITEM(dtype,0), + &typecode) < 0) return NULL; + if (PyArray_IntpConverter(PyTuple_GET_ITEM(dtype,1), + &dim) < 0) return NULL; + tupletype = 1; + typecode.itemsize = typecode.itemsize * \ + PyArray_MultiplyList(dim.ptr, dim.len); + typecode.type_num = PyArray_VOID; + PyDimMem_FREE(dim.ptr); + } + else { + if (PyArray_TypecodeConverter(dtype, &typecode) < 0) + return NULL; + } + - if (offset < 0 || (offset + type->itemsize) > self->itemsize) { + if (offset < 0 || (offset + typecode.itemsize) > self->itemsize) { PyErr_Format(PyExc_ValueError, "Need 0 <= offset <= %d for requested type " \ "but received offset = %d", - self->itemsize-type->itemsize, offset); + self->itemsize-typecode.itemsize, offset); return NULL; } ret = PyArray_New(self->ob_type, self->nd, self->dimensions, - type->type_num, self->strides, + typecode.type_num, self->strides, self->data + offset, - type->itemsize, self->flags, (PyObject *)self); + typecode.itemsize, self->flags, (PyObject *)self); if (ret == NULL) return NULL; Py_INCREF(self); ((PyArrayObject *)ret)->base = (PyObject *)self; - PyArray_UpdateFlags((PyArrayObject *)ret, UPDATE_ALL_FLAGS); - return ret; + + if (tupletype && (array_type_set((PyArrayObject *)ret, dtype) < 0)) { + Py_DECREF(ret); return NULL; + } + else { + PyArray_UpdateFlags((PyArrayObject *)ret, UPDATE_ALL_FLAGS); + } + return ret; } static PyObject * array_getfield(PyArrayObject *self, PyObject *args, PyObject *kwds) { - PyArray_Typecode typecode = {PyArray_NOTYPE, 0, 0}; + PyObject *dtype; + int offset = 0; static char *kwlist[] = {"dtype", "offset", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|i", kwlist, - PyArray_TypecodeConverter, - &typecode, &offset)) return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i", kwlist, + &dtype, &offset)) return NULL; - return _ARET(PyArray_GetField(self, &typecode, offset)); + return _ARET(PyArray_GetField(self, dtype, offset)); } -static char doc_setfield[] = "m.field(type, offset, val) places val into "\ +static char doc_setfield[] = "m.setfield(dtype, offset, val) places val into "\ " field of the given array defined by the type and offset."; static int -PyArray_SetField(PyArrayObject *self, PyArray_Typecode *type, +PyArray_SetField(PyArrayObject *self, PyObject *dtype, int offset, PyObject *val) { + PyArray_Typecode typecode = {PyArray_NOTYPE, 0, 0}; PyObject *ret=NULL; int retval = 0; + int tupletype=0; + + if (PyTuple_Check(dtype)) { + PyArray_Dims dim = {NULL, -1}; + if (PyTuple_GET_SIZE(dtype) != 2) { + PyErr_SetString(PyExc_TypeError, + "tuple for data-type must be length 2"); + return -1; + } + if (PyArray_TypecodeConverter(PyTuple_GET_ITEM(dtype,0), + &typecode) < 0) return -1; + if (PyArray_IntpConverter(PyTuple_GET_ITEM(dtype,1), + &dim) < 0) return -1; + tupletype = 1; + typecode.itemsize = typecode.itemsize * \ + PyArray_MultiplyList(dim.ptr, dim.len); + typecode.type_num = PyArray_VOID; + PyDimMem_FREE(dim.ptr); + } + else { + if (PyArray_TypecodeConverter(dtype, &typecode) < 0) + return -1; + } - if (offset < 0 || (offset + type->itemsize) > self->itemsize) { + + if (offset < 0 || (offset + typecode.itemsize) > self->itemsize) { PyErr_Format(PyExc_ValueError, "Need 0 <= offset <= %d for requested type " \ "but received offset = %d", - self->itemsize-type->itemsize, offset); + self->itemsize-typecode.itemsize, offset); return -1; } ret = PyArray_New(self->ob_type, self->nd, self->dimensions, - type->type_num, self->strides, + typecode.type_num, self->strides, self->data + offset, - type->itemsize, self->flags, (PyObject *)self); + typecode.itemsize, self->flags, (PyObject *)self); if (ret == NULL) return -1; Py_INCREF(self); ((PyArrayObject *)ret)->base = (PyObject *)self; - PyArray_UpdateFlags((PyArrayObject *)ret, UPDATE_ALL_FLAGS); - + + if (tupletype && (array_type_set((PyArrayObject *)ret, dtype) < 0)) { + Py_DECREF(ret); return -1; + } + else { + PyArray_UpdateFlags((PyArrayObject *)ret, UPDATE_ALL_FLAGS); + } retval = PyArray_CopyObject((PyArrayObject *)ret, val); Py_DECREF(ret); return retval; @@ -327,17 +389,16 @@ PyArray_SetField(PyArrayObject *self, PyArray_Typecode *type, static PyObject * array_setfield(PyArrayObject *self, PyObject *args, PyObject *kwds) { - PyArray_Typecode typecode = {PyArray_NOTYPE, 0, 0}; + PyObject *dtype; int offset = 0; PyObject *value; static char *kwlist[] = {"value", "dtype", "offset", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&|i", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|i", kwlist, &value, - PyArray_TypecodeConverter, - &typecode, &offset)) return NULL; + &dtype, &offset)) return NULL; - if (PyArray_SetField(self, &typecode, offset, value) < 0) + if (PyArray_SetField(self, dtype, offset, value) < 0) return NULL; Py_INCREF(Py_None); return Py_None; |