summaryrefslogtreecommitdiff
path: root/numpy/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core/src')
-rw-r--r--numpy/core/src/arraygetset.c882
-rw-r--r--numpy/core/src/arraygetset.h6
-rw-r--r--numpy/core/src/arraynumber.c807
-rw-r--r--numpy/core/src/arraynumber.h19
-rw-r--r--numpy/core/src/arrayobject.c1674
-rw-r--r--numpy/core/src/arrayobject.h4
6 files changed, 1718 insertions, 1674 deletions
diff --git a/numpy/core/src/arraygetset.c b/numpy/core/src/arraygetset.c
new file mode 100644
index 000000000..2d69f29ba
--- /dev/null
+++ b/numpy/core/src/arraygetset.c
@@ -0,0 +1,882 @@
+/* Array Descr Object */
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include "structmember.h"
+
+#define _MULTIARRAYMODULE
+#define NPY_NO_PREFIX
+#include "numpy/arrayobject.h"
+
+#include "arrayobject.h"
+#include "arraydescr.h"
+#include "arraygetset.h"
+
+/******************* array attribute get and set routines ******************/
+
+static PyObject *
+array_ndim_get(PyArrayObject *self)
+{
+ return PyInt_FromLong(self->nd);
+}
+
+static PyObject *
+array_flags_get(PyArrayObject *self)
+{
+ return PyArray_NewFlagsObject((PyObject *)self);
+}
+
+static PyObject *
+array_shape_get(PyArrayObject *self)
+{
+ return PyArray_IntTupleFromIntp(self->nd, self->dimensions);
+}
+
+
+static int
+array_shape_set(PyArrayObject *self, PyObject *val)
+{
+ int nd;
+ PyObject *ret;
+
+ /* Assumes C-order */
+ ret = PyArray_Reshape(self, val);
+ if (ret == NULL) {
+ return -1;
+ }
+ if (PyArray_DATA(ret) != PyArray_DATA(self)) {
+ Py_DECREF(ret);
+ PyErr_SetString(PyExc_AttributeError,
+ "incompatible shape for a non-contiguous "\
+ "array");
+ return -1;
+ }
+
+ /* Free old dimensions and strides */
+ PyDimMem_FREE(self->dimensions);
+ nd = PyArray_NDIM(ret);
+ self->nd = nd;
+ if (nd > 0) {
+ /* create new dimensions and strides */
+ self->dimensions = PyDimMem_NEW(2*nd);
+ if (self->dimensions == NULL) {
+ Py_DECREF(ret);
+ PyErr_SetString(PyExc_MemoryError,"");
+ return -1;
+ }
+ self->strides = self->dimensions + nd;
+ memcpy(self->dimensions, PyArray_DIMS(ret), nd*sizeof(intp));
+ memcpy(self->strides, PyArray_STRIDES(ret), nd*sizeof(intp));
+ }
+ else {
+ self->dimensions = NULL;
+ self->strides = NULL;
+ }
+ Py_DECREF(ret);
+ PyArray_UpdateFlags(self, CONTIGUOUS | FORTRAN);
+ return 0;
+}
+
+
+static PyObject *
+array_strides_get(PyArrayObject *self)
+{
+ return PyArray_IntTupleFromIntp(self->nd, self->strides);
+}
+
+static int
+array_strides_set(PyArrayObject *self, PyObject *obj)
+{
+ PyArray_Dims newstrides = {NULL, 0};
+ PyArrayObject *new;
+ intp numbytes = 0;
+ intp offset = 0;
+ Py_ssize_t buf_len;
+ char *buf;
+
+ if (!PyArray_IntpConverter(obj, &newstrides) ||
+ newstrides.ptr == NULL) {
+ PyErr_SetString(PyExc_TypeError, "invalid strides");
+ return -1;
+ }
+ if (newstrides.len != self->nd) {
+ PyErr_Format(PyExc_ValueError, "strides must be " \
+ " same length as shape (%d)", self->nd);
+ goto fail;
+ }
+ new = self;
+ while(new->base && PyArray_Check(new->base)) {
+ new = (PyArrayObject *)(new->base);
+ }
+ /*
+ * Get the available memory through the buffer interface on
+ * new->base or if that fails from the current new
+ */
+ if (new->base && PyObject_AsReadBuffer(new->base,
+ (const void **)&buf,
+ &buf_len) >= 0) {
+ offset = self->data - buf;
+ numbytes = buf_len + offset;
+ }
+ else {
+ PyErr_Clear();
+ numbytes = PyArray_MultiplyList(new->dimensions,
+ new->nd)*new->descr->elsize;
+ offset = self->data - new->data;
+ }
+
+ if (!PyArray_CheckStrides(self->descr->elsize, self->nd, numbytes,
+ offset,
+ self->dimensions, newstrides.ptr)) {
+ PyErr_SetString(PyExc_ValueError, "strides is not "\
+ "compatible with available memory");
+ goto fail;
+ }
+ memcpy(self->strides, newstrides.ptr, sizeof(intp)*newstrides.len);
+ PyArray_UpdateFlags(self, CONTIGUOUS | FORTRAN);
+ PyDimMem_FREE(newstrides.ptr);
+ return 0;
+
+ fail:
+ PyDimMem_FREE(newstrides.ptr);
+ return -1;
+}
+
+
+
+static PyObject *
+array_priority_get(PyArrayObject *self)
+{
+ if (PyArray_CheckExact(self)) {
+ return PyFloat_FromDouble(PyArray_PRIORITY);
+ }
+ else {
+ return PyFloat_FromDouble(PyArray_SUBTYPE_PRIORITY);
+ }
+}
+
+static PyObject *
+array_typestr_get(PyArrayObject *self)
+{
+ return arraydescr_protocol_typestr_get(self->descr);
+}
+
+static PyObject *
+array_descr_get(PyArrayObject *self)
+{
+ Py_INCREF(self->descr);
+ return (PyObject *)self->descr;
+}
+
+static PyObject *
+array_protocol_descr_get(PyArrayObject *self)
+{
+ PyObject *res;
+ PyObject *dobj;
+
+ res = arraydescr_protocol_descr_get(self->descr);
+ if (res) {
+ return res;
+ }
+ PyErr_Clear();
+
+ /* get default */
+ dobj = PyTuple_New(2);
+ if (dobj == NULL) {
+ return NULL;
+ }
+ PyTuple_SET_ITEM(dobj, 0, PyString_FromString(""));
+ PyTuple_SET_ITEM(dobj, 1, array_typestr_get(self));
+ res = PyList_New(1);
+ if (res == NULL) {
+ Py_DECREF(dobj);
+ return NULL;
+ }
+ PyList_SET_ITEM(res, 0, dobj);
+ return res;
+}
+
+static PyObject *
+array_protocol_strides_get(PyArrayObject *self)
+{
+ if PyArray_ISCONTIGUOUS(self) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyArray_IntTupleFromIntp(self->nd, self->strides);
+}
+
+
+
+static PyObject *
+array_dataptr_get(PyArrayObject *self)
+{
+ return Py_BuildValue("NO",
+ PyLong_FromVoidPtr(self->data),
+ (self->flags & WRITEABLE ? Py_False :
+ Py_True));
+}
+
+static PyObject *
+array_ctypes_get(PyArrayObject *self)
+{
+ PyObject *_numpy_internal;
+ PyObject *ret;
+ _numpy_internal = PyImport_ImportModule("numpy.core._internal");
+ if (_numpy_internal == NULL) {
+ return NULL;
+ }
+ ret = PyObject_CallMethod(_numpy_internal, "_ctypes", "ON", self,
+ PyLong_FromVoidPtr(self->data));
+ Py_DECREF(_numpy_internal);
+ return ret;
+}
+
+static PyObject *
+array_interface_get(PyArrayObject *self)
+{
+ PyObject *dict;
+ PyObject *obj;
+
+ dict = PyDict_New();
+ if (dict == NULL) {
+ return NULL;
+ }
+
+ /* dataptr */
+ obj = array_dataptr_get(self);
+ PyDict_SetItemString(dict, "data", obj);
+ Py_DECREF(obj);
+
+ obj = array_protocol_strides_get(self);
+ PyDict_SetItemString(dict, "strides", obj);
+ Py_DECREF(obj);
+
+ obj = array_protocol_descr_get(self);
+ PyDict_SetItemString(dict, "descr", obj);
+ Py_DECREF(obj);
+
+ obj = arraydescr_protocol_typestr_get(self->descr);
+ PyDict_SetItemString(dict, "typestr", obj);
+ Py_DECREF(obj);
+
+ obj = array_shape_get(self);
+ PyDict_SetItemString(dict, "shape", obj);
+ Py_DECREF(obj);
+
+ obj = PyInt_FromLong(3);
+ PyDict_SetItemString(dict, "version", obj);
+ Py_DECREF(obj);
+
+ return dict;
+}
+
+static PyObject *
+array_data_get(PyArrayObject *self)
+{
+ intp nbytes;
+ if (!(PyArray_ISONESEGMENT(self))) {
+ PyErr_SetString(PyExc_AttributeError, "cannot get single-"\
+ "segment buffer for discontiguous array");
+ return NULL;
+ }
+ nbytes = PyArray_NBYTES(self);
+ if PyArray_ISWRITEABLE(self) {
+ return PyBuffer_FromReadWriteObject((PyObject *)self, 0, (Py_ssize_t) nbytes);
+ }
+ else {
+ return PyBuffer_FromObject((PyObject *)self, 0, (Py_ssize_t) nbytes);
+ }
+}
+
+static int
+array_data_set(PyArrayObject *self, PyObject *op)
+{
+ void *buf;
+ Py_ssize_t buf_len;
+ int writeable=1;
+
+ if (PyObject_AsWriteBuffer(op, &buf, &buf_len) < 0) {
+ writeable = 0;
+ if (PyObject_AsReadBuffer(op, (const void **)&buf, &buf_len) < 0) {
+ PyErr_SetString(PyExc_AttributeError,
+ "object does not have single-segment " \
+ "buffer interface");
+ return -1;
+ }
+ }
+ if (!PyArray_ISONESEGMENT(self)) {
+ PyErr_SetString(PyExc_AttributeError, "cannot set single-" \
+ "segment buffer for discontiguous array");
+ return -1;
+ }
+ if (PyArray_NBYTES(self) > buf_len) {
+ PyErr_SetString(PyExc_AttributeError, "not enough data for array");
+ return -1;
+ }
+ if (self->flags & OWNDATA) {
+ PyArray_XDECREF(self);
+ PyDataMem_FREE(self->data);
+ }
+ if (self->base) {
+ if (self->flags & UPDATEIFCOPY) {
+ ((PyArrayObject *)self->base)->flags |= WRITEABLE;
+ self->flags &= ~UPDATEIFCOPY;
+ }
+ Py_DECREF(self->base);
+ }
+ Py_INCREF(op);
+ self->base = op;
+ self->data = buf;
+ self->flags = CARRAY;
+ if (!writeable) {
+ self->flags &= ~WRITEABLE;
+ }
+ return 0;
+}
+
+
+static PyObject *
+array_itemsize_get(PyArrayObject *self)
+{
+ return PyInt_FromLong((long) self->descr->elsize);
+}
+
+static PyObject *
+array_size_get(PyArrayObject *self)
+{
+ intp size=PyArray_SIZE(self);
+#if SIZEOF_INTP <= SIZEOF_LONG
+ return PyInt_FromLong((long) size);
+#else
+ if (size > MAX_LONG || size < MIN_LONG) {
+ return PyLong_FromLongLong(size);
+ }
+ else {
+ return PyInt_FromLong((long) size);
+ }
+#endif
+}
+
+static PyObject *
+array_nbytes_get(PyArrayObject *self)
+{
+ intp nbytes = PyArray_NBYTES(self);
+#if SIZEOF_INTP <= SIZEOF_LONG
+ return PyInt_FromLong((long) nbytes);
+#else
+ if (nbytes > MAX_LONG || nbytes < MIN_LONG) {
+ return PyLong_FromLongLong(nbytes);
+ }
+ else {
+ return PyInt_FromLong((long) nbytes);
+ }
+#endif
+}
+
+
+/*
+ * If the type is changed.
+ * Also needing change: strides, itemsize
+ *
+ * Either itemsize is exactly the same or the array is single-segment
+ * (contiguous or fortran) with compatibile dimensions The shape and strides
+ * will be adjusted in that case as well.
+ */
+
+static int
+array_descr_set(PyArrayObject *self, PyObject *arg)
+{
+ PyArray_Descr *newtype = NULL;
+ intp newdim;
+ int index;
+ char *msg = "new type not compatible with array.";
+
+ if (!(PyArray_DescrConverter(arg, &newtype)) ||
+ newtype == NULL) {
+ PyErr_SetString(PyExc_TypeError, "invalid data-type for array");
+ return -1;
+ }
+ if (PyDataType_FLAGCHK(newtype, NPY_ITEM_HASOBJECT) ||
+ PyDataType_FLAGCHK(newtype, NPY_ITEM_IS_POINTER) ||
+ PyDataType_FLAGCHK(self->descr, NPY_ITEM_HASOBJECT) ||
+ PyDataType_FLAGCHK(self->descr, NPY_ITEM_IS_POINTER)) {
+ PyErr_SetString(PyExc_TypeError, \
+ "Cannot change data-type for object " \
+ "array.");
+ Py_DECREF(newtype);
+ return -1;
+ }
+
+ if (newtype->elsize == 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "data-type must not be 0-sized");
+ Py_DECREF(newtype);
+ return -1;
+ }
+
+
+ if ((newtype->elsize != self->descr->elsize) &&
+ (self->nd == 0 || !PyArray_ISONESEGMENT(self) ||
+ newtype->subarray)) {
+ goto fail;
+ }
+ if (PyArray_ISCONTIGUOUS(self)) {
+ index = self->nd - 1;
+ }
+ else {
+ index = 0;
+ }
+ if (newtype->elsize < self->descr->elsize) {
+ /*
+ * if it is compatible increase the size of the
+ * dimension at end (or at the front for FORTRAN)
+ */
+ if (self->descr->elsize % newtype->elsize != 0) {
+ goto fail;
+ }
+ newdim = self->descr->elsize / newtype->elsize;
+ self->dimensions[index] *= newdim;
+ self->strides[index] = newtype->elsize;
+ }
+ else if (newtype->elsize > self->descr->elsize) {
+ /*
+ * Determine if last (or first if FORTRAN) dimension
+ * is compatible
+ */
+ newdim = self->dimensions[index] * self->descr->elsize;
+ if ((newdim % newtype->elsize) != 0) {
+ goto fail;
+ }
+ self->dimensions[index] = newdim / newtype->elsize;
+ self->strides[index] = newtype->elsize;
+ }
+
+ /* fall through -- adjust type*/
+ Py_DECREF(self->descr);
+ if (newtype->subarray) {
+ /*
+ * create new array object from data and update
+ * dimensions, strides and descr from it
+ */
+ PyArrayObject *temp;
+ /*
+ * We would decref newtype here.
+ * temp will steal a reference to it
+ */
+ temp = (PyArrayObject *)
+ PyArray_NewFromDescr(&PyArray_Type, newtype, self->nd,
+ self->dimensions, self->strides,
+ self->data, self->flags, NULL);
+ if (temp == NULL) {
+ return -1;
+ }
+ PyDimMem_FREE(self->dimensions);
+ self->dimensions = temp->dimensions;
+ self->nd = temp->nd;
+ self->strides = temp->strides;
+ newtype = temp->descr;
+ Py_INCREF(temp->descr);
+ /* Fool deallocator not to delete these*/
+ temp->nd = 0;
+ temp->dimensions = NULL;
+ Py_DECREF(temp);
+ }
+
+ self->descr = newtype;
+ PyArray_UpdateFlags(self, UPDATE_ALL);
+ return 0;
+
+ fail:
+ PyErr_SetString(PyExc_ValueError, msg);
+ Py_DECREF(newtype);
+ return -1;
+}
+
+static PyObject *
+array_struct_get(PyArrayObject *self)
+{
+ PyArrayInterface *inter;
+
+ inter = (PyArrayInterface *)_pya_malloc(sizeof(PyArrayInterface));
+ if (inter==NULL) {
+ return PyErr_NoMemory();
+ }
+ inter->two = 2;
+ inter->nd = self->nd;
+ inter->typekind = self->descr->kind;
+ inter->itemsize = self->descr->elsize;
+ inter->flags = self->flags;
+ /* reset unused flags */
+ inter->flags &= ~(UPDATEIFCOPY | OWNDATA);
+ if (PyArray_ISNOTSWAPPED(self)) inter->flags |= NOTSWAPPED;
+ /*
+ * Copy shape and strides over since these can be reset
+ *when the array is "reshaped".
+ */
+ if (self->nd > 0) {
+ inter->shape = (intp *)_pya_malloc(2*sizeof(intp)*self->nd);
+ if (inter->shape == NULL) {
+ _pya_free(inter);
+ return PyErr_NoMemory();
+ }
+ inter->strides = inter->shape + self->nd;
+ memcpy(inter->shape, self->dimensions, sizeof(intp)*self->nd);
+ memcpy(inter->strides, self->strides, sizeof(intp)*self->nd);
+ }
+ else {
+ inter->shape = NULL;
+ inter->strides = NULL;
+ }
+ inter->data = self->data;
+ if (self->descr->names) {
+ inter->descr = arraydescr_protocol_descr_get(self->descr);
+ if (inter->descr == NULL) {
+ PyErr_Clear();
+ }
+ else {
+ inter->flags &= ARR_HAS_DESCR;
+ }
+ }
+ else {
+ inter->descr = NULL;
+ }
+ Py_INCREF(self);
+ return PyCObject_FromVoidPtrAndDesc(inter, self, gentype_struct_free);
+}
+
+static PyObject *
+array_base_get(PyArrayObject *self)
+{
+ if (self->base == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else {
+ Py_INCREF(self->base);
+ return self->base;
+ }
+}
+
+
+NPY_NO_EXPORT int
+_zerofill(PyArrayObject *ret)
+{
+ if (PyDataType_REFCHK(ret->descr)) {
+ PyObject *zero = PyInt_FromLong(0);
+ PyArray_FillObjectArray(ret, zero);
+ Py_DECREF(zero);
+ if (PyErr_Occurred()) {
+ Py_DECREF(ret);
+ return -1;
+ }
+ }
+ else {
+ intp n = PyArray_NBYTES(ret);
+ memset(ret->data, 0, n);
+ }
+ return 0;
+}
+
+
+/*
+ * Create a view of a complex array with an equivalent data-type
+ * except it is real instead of complex.
+ */
+static PyArrayObject *
+_get_part(PyArrayObject *self, int imag)
+{
+ PyArray_Descr *type;
+ PyArrayObject *ret;
+ int offset;
+
+ type = PyArray_DescrFromType(self->descr->type_num -
+ PyArray_NUM_FLOATTYPE);
+ offset = (imag ? type->elsize : 0);
+
+ if (!PyArray_ISNBO(self->descr->byteorder)) {
+ PyArray_Descr *new;
+ new = PyArray_DescrNew(type);
+ new->byteorder = self->descr->byteorder;
+ Py_DECREF(type);
+ type = new;
+ }
+ ret = (PyArrayObject *)
+ PyArray_NewFromDescr(self->ob_type,
+ type,
+ self->nd,
+ self->dimensions,
+ self->strides,
+ self->data + offset,
+ self->flags, (PyObject *)self);
+ if (ret == NULL) {
+ return NULL;
+ }
+ ret->flags &= ~CONTIGUOUS;
+ ret->flags &= ~FORTRAN;
+ Py_INCREF(self);
+ ret->base = (PyObject *)self;
+ return ret;
+}
+
+static PyObject *
+array_real_get(PyArrayObject *self)
+{
+ PyArrayObject *ret;
+
+ if (PyArray_ISCOMPLEX(self)) {
+ ret = _get_part(self, 0);
+ return (PyObject *)ret;
+ }
+ else {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+}
+
+
+static int
+array_real_set(PyArrayObject *self, PyObject *val)
+{
+ PyArrayObject *ret;
+ PyArrayObject *new;
+ int rint;
+
+ if (PyArray_ISCOMPLEX(self)) {
+ ret = _get_part(self, 0);
+ if (ret == NULL) {
+ return -1;
+ }
+ }
+ else {
+ Py_INCREF(self);
+ ret = self;
+ }
+ new = (PyArrayObject *)PyArray_FromAny(val, NULL, 0, 0, 0, NULL);
+ if (new == NULL) {
+ Py_DECREF(ret);
+ return -1;
+ }
+ rint = PyArray_MoveInto(ret, new);
+ Py_DECREF(ret);
+ Py_DECREF(new);
+ return rint;
+}
+
+static PyObject *
+array_imag_get(PyArrayObject *self)
+{
+ PyArrayObject *ret;
+
+ if (PyArray_ISCOMPLEX(self)) {
+ ret = _get_part(self, 1);
+ }
+ else {
+ Py_INCREF(self->descr);
+ ret = (PyArrayObject *)PyArray_NewFromDescr(self->ob_type,
+ self->descr,
+ self->nd,
+ self->dimensions,
+ NULL, NULL,
+ PyArray_ISFORTRAN(self),
+ (PyObject *)self);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (_zerofill(ret) < 0) {
+ return NULL;
+ }
+ ret->flags &= ~WRITEABLE;
+ }
+ return (PyObject *) ret;
+}
+
+static int
+array_imag_set(PyArrayObject *self, PyObject *val)
+{
+ if (PyArray_ISCOMPLEX(self)) {
+ PyArrayObject *ret;
+ PyArrayObject *new;
+ int rint;
+
+ ret = _get_part(self, 1);
+ if (ret == NULL) {
+ return -1;
+ }
+ new = (PyArrayObject *)PyArray_FromAny(val, NULL, 0, 0, 0, NULL);
+ if (new == NULL) {
+ Py_DECREF(ret);
+ return -1;
+ }
+ rint = PyArray_MoveInto(ret, new);
+ Py_DECREF(ret);
+ Py_DECREF(new);
+ return rint;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "array does not have "\
+ "imaginary part to set");
+ return -1;
+ }
+}
+
+static PyObject *
+array_flat_get(PyArrayObject *self)
+{
+ return PyArray_IterNew((PyObject *)self);
+}
+
+static int
+array_flat_set(PyArrayObject *self, PyObject *val)
+{
+ PyObject *arr = NULL;
+ int retval = -1;
+ PyArrayIterObject *selfit = NULL, *arrit = NULL;
+ PyArray_Descr *typecode;
+ int swap;
+ PyArray_CopySwapFunc *copyswap;
+
+ typecode = self->descr;
+ Py_INCREF(typecode);
+ arr = PyArray_FromAny(val, typecode,
+ 0, 0, FORCECAST | FORTRAN_IF(self), NULL);
+ if (arr == NULL) {
+ return -1;
+ }
+ arrit = (PyArrayIterObject *)PyArray_IterNew(arr);
+ if (arrit == NULL) {
+ goto exit;
+ }
+ selfit = (PyArrayIterObject *)PyArray_IterNew((PyObject *)self);
+ if (selfit == NULL) {
+ goto exit;
+ }
+ if (arrit->size == 0) {
+ retval = 0;
+ goto exit;
+ }
+ swap = PyArray_ISNOTSWAPPED(self) != PyArray_ISNOTSWAPPED(arr);
+ copyswap = self->descr->f->copyswap;
+ if (PyDataType_REFCHK(self->descr)) {
+ while (selfit->index < selfit->size) {
+ PyArray_Item_XDECREF(selfit->dataptr, self->descr);
+ PyArray_Item_INCREF(arrit->dataptr, PyArray_DESCR(arr));
+ memmove(selfit->dataptr, arrit->dataptr, sizeof(PyObject **));
+ if (swap) {
+ copyswap(selfit->dataptr, NULL, swap, self);
+ }
+ PyArray_ITER_NEXT(selfit);
+ PyArray_ITER_NEXT(arrit);
+ if (arrit->index == arrit->size) {
+ PyArray_ITER_RESET(arrit);
+ }
+ }
+ retval = 0;
+ goto exit;
+ }
+
+ while(selfit->index < selfit->size) {
+ memmove(selfit->dataptr, arrit->dataptr, self->descr->elsize);
+ if (swap) {
+ copyswap(selfit->dataptr, NULL, swap, self);
+ }
+ PyArray_ITER_NEXT(selfit);
+ PyArray_ITER_NEXT(arrit);
+ if (arrit->index == arrit->size) {
+ PyArray_ITER_RESET(arrit);
+ }
+ }
+ retval = 0;
+
+ exit:
+ Py_XDECREF(selfit);
+ Py_XDECREF(arrit);
+ Py_XDECREF(arr);
+ return retval;
+}
+
+static PyObject *
+array_transpose_get(PyArrayObject *self)
+{
+ return PyArray_Transpose(self, NULL);
+}
+
+/* If this is None, no function call is made
+ --- default sub-class behavior
+*/
+static PyObject *
+array_finalize_get(PyArrayObject *NPY_UNUSED(self))
+{
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+NPY_NO_EXPORT PyGetSetDef array_getsetlist[] = {
+ {"ndim",
+ (getter)array_ndim_get,
+ NULL, NULL, NULL},
+ {"flags",
+ (getter)array_flags_get,
+ NULL, NULL, NULL},
+ {"shape",
+ (getter)array_shape_get,
+ (setter)array_shape_set,
+ NULL, NULL},
+ {"strides",
+ (getter)array_strides_get,
+ (setter)array_strides_set,
+ NULL, NULL},
+ {"data",
+ (getter)array_data_get,
+ (setter)array_data_set,
+ NULL, NULL},
+ {"itemsize",
+ (getter)array_itemsize_get,
+ NULL, NULL, NULL},
+ {"size",
+ (getter)array_size_get,
+ NULL, NULL, NULL},
+ {"nbytes",
+ (getter)array_nbytes_get,
+ NULL, NULL, NULL},
+ {"base",
+ (getter)array_base_get,
+ NULL, NULL, NULL},
+ {"dtype",
+ (getter)array_descr_get,
+ (setter)array_descr_set,
+ NULL, NULL},
+ {"real",
+ (getter)array_real_get,
+ (setter)array_real_set,
+ NULL, NULL},
+ {"imag",
+ (getter)array_imag_get,
+ (setter)array_imag_set,
+ NULL, NULL},
+ {"flat",
+ (getter)array_flat_get,
+ (setter)array_flat_set,
+ NULL, NULL},
+ {"ctypes",
+ (getter)array_ctypes_get,
+ NULL, NULL, NULL},
+ {"T",
+ (getter)array_transpose_get,
+ NULL, NULL, NULL},
+ {"__array_interface__",
+ (getter)array_interface_get,
+ NULL, NULL, NULL},
+ {"__array_struct__",
+ (getter)array_struct_get,
+ NULL, NULL, NULL},
+ {"__array_priority__",
+ (getter)array_priority_get,
+ NULL, NULL, NULL},
+ {"__array_finalize__",
+ (getter)array_finalize_get,
+ NULL, NULL, NULL},
+ {NULL, NULL, NULL, NULL, NULL}, /* Sentinel */
+};
+
+/****************** end of attribute get and set routines *******************/
diff --git a/numpy/core/src/arraygetset.h b/numpy/core/src/arraygetset.h
new file mode 100644
index 000000000..4f1209de5
--- /dev/null
+++ b/numpy/core/src/arraygetset.h
@@ -0,0 +1,6 @@
+#ifndef _NPY_ARRAY_GETSET_H_
+#define _NPY_ARRAY_GETSET_H_
+
+extern NPY_NO_EXPORT PyGetSetDef array_getsetlist[];
+
+#endif
diff --git a/numpy/core/src/arraynumber.c b/numpy/core/src/arraynumber.c
new file mode 100644
index 000000000..aa3e250cb
--- /dev/null
+++ b/numpy/core/src/arraynumber.c
@@ -0,0 +1,807 @@
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include "structmember.h"
+
+/*#include <stdio.h>*/
+#define _MULTIARRAYMODULE
+#define NPY_NO_PREFIX
+#include "numpy/arrayobject.h"
+
+#include "arrayobject.h"
+#include "arraynumber.h"
+
+/*************************************************************************
+ **************** Implement Number Protocol ****************************
+ *************************************************************************/
+
+NPY_NO_EXPORT NumericOps n_ops; /* NB: static objects initialized to zero */
+
+/* Dictionary can contain any of the numeric operations, by name.
+ Those not present will not be changed
+*/
+
+#define SET(op) temp=PyDict_GetItemString(dict, #op); \
+ if (temp != NULL) { \
+ if (!(PyCallable_Check(temp))) return -1; \
+ Py_XDECREF(n_ops.op); \
+ n_ops.op = temp; \
+ }
+
+
+/*NUMPY_API
+ Set internal structure with number functions that all arrays will use
+*/
+NPY_NO_EXPORT int
+PyArray_SetNumericOps(PyObject *dict)
+{
+ PyObject *temp = NULL;
+ SET(add);
+ SET(subtract);
+ SET(multiply);
+ SET(divide);
+ SET(remainder);
+ SET(power);
+ SET(square);
+ SET(reciprocal);
+ SET(ones_like);
+ SET(sqrt);
+ SET(negative);
+ SET(absolute);
+ SET(invert);
+ SET(left_shift);
+ SET(right_shift);
+ SET(bitwise_and);
+ SET(bitwise_or);
+ SET(bitwise_xor);
+ SET(less);
+ SET(less_equal);
+ SET(equal);
+ SET(not_equal);
+ SET(greater);
+ SET(greater_equal);
+ SET(floor_divide);
+ SET(true_divide);
+ SET(logical_or);
+ SET(logical_and);
+ SET(floor);
+ SET(ceil);
+ SET(maximum);
+ SET(minimum);
+ SET(rint);
+ SET(conjugate);
+ return 0;
+}
+
+#define GET(op) if (n_ops.op && \
+ (PyDict_SetItemString(dict, #op, n_ops.op)==-1)) \
+ goto fail;
+
+/*NUMPY_API
+ Get dictionary showing number functions that all arrays will use
+*/
+NPY_NO_EXPORT PyObject *
+PyArray_GetNumericOps(void)
+{
+ PyObject *dict;
+ if ((dict = PyDict_New())==NULL)
+ return NULL;
+ GET(add);
+ GET(subtract);
+ GET(multiply);
+ GET(divide);
+ GET(remainder);
+ GET(power);
+ GET(square);
+ GET(reciprocal);
+ GET(ones_like);
+ GET(sqrt);
+ GET(negative);
+ GET(absolute);
+ GET(invert);
+ GET(left_shift);
+ GET(right_shift);
+ GET(bitwise_and);
+ GET(bitwise_or);
+ GET(bitwise_xor);
+ GET(less);
+ GET(less_equal);
+ GET(equal);
+ GET(not_equal);
+ GET(greater);
+ GET(greater_equal);
+ GET(floor_divide);
+ GET(true_divide);
+ GET(logical_or);
+ GET(logical_and);
+ GET(floor);
+ GET(ceil);
+ GET(maximum);
+ GET(minimum);
+ GET(rint);
+ GET(conjugate);
+ return dict;
+
+ fail:
+ Py_DECREF(dict);
+ return NULL;
+}
+
+static PyObject *
+_get_keywords(int rtype, PyArrayObject *out)
+{
+ PyObject *kwds = NULL;
+ if (rtype != PyArray_NOTYPE || out != NULL) {
+ kwds = PyDict_New();
+ if (rtype != PyArray_NOTYPE) {
+ PyArray_Descr *descr;
+ descr = PyArray_DescrFromType(rtype);
+ if (descr) {
+ PyDict_SetItemString(kwds, "dtype", (PyObject *)descr);
+ Py_DECREF(descr);
+ }
+ }
+ if (out != NULL) {
+ PyDict_SetItemString(kwds, "out", (PyObject *)out);
+ }
+ }
+ return kwds;
+}
+
+NPY_NO_EXPORT PyObject *
+PyArray_GenericReduceFunction(PyArrayObject *m1, PyObject *op, int axis,
+ int rtype, PyArrayObject *out)
+{
+ PyObject *args, *ret = NULL, *meth;
+ PyObject *kwds;
+ if (op == NULL) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ args = Py_BuildValue("(Oi)", m1, axis);
+ kwds = _get_keywords(rtype, out);
+ meth = PyObject_GetAttrString(op, "reduce");
+ if (meth && PyCallable_Check(meth)) {
+ ret = PyObject_Call(meth, args, kwds);
+ }
+ Py_DECREF(args);
+ Py_DECREF(meth);
+ Py_XDECREF(kwds);
+ return ret;
+}
+
+
+NPY_NO_EXPORT PyObject *
+PyArray_GenericAccumulateFunction(PyArrayObject *m1, PyObject *op, int axis,
+ int rtype, PyArrayObject *out)
+{
+ PyObject *args, *ret = NULL, *meth;
+ PyObject *kwds;
+ if (op == NULL) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ args = Py_BuildValue("(Oi)", m1, axis);
+ kwds = _get_keywords(rtype, out);
+ meth = PyObject_GetAttrString(op, "accumulate");
+ if (meth && PyCallable_Check(meth)) {
+ ret = PyObject_Call(meth, args, kwds);
+ }
+ Py_DECREF(args);
+ Py_DECREF(meth);
+ Py_XDECREF(kwds);
+ return ret;
+}
+
+
+NPY_NO_EXPORT PyObject *
+PyArray_GenericBinaryFunction(PyArrayObject *m1, PyObject *m2, PyObject *op)
+{
+ if (op == NULL) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return PyObject_CallFunction(op, "OO", m1, m2);
+}
+
+NPY_NO_EXPORT PyObject *
+PyArray_GenericUnaryFunction(PyArrayObject *m1, PyObject *op)
+{
+ if (op == NULL) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return PyObject_CallFunction(op, "(O)", m1);
+}
+
+static PyObject *
+PyArray_GenericInplaceBinaryFunction(PyArrayObject *m1,
+ PyObject *m2, PyObject *op)
+{
+ if (op == NULL) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return PyObject_CallFunction(op, "OOO", m1, m2, m1);
+}
+
+static PyObject *
+PyArray_GenericInplaceUnaryFunction(PyArrayObject *m1, PyObject *op)
+{
+ if (op == NULL) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return PyObject_CallFunction(op, "OO", m1, m1);
+}
+
+static PyObject *
+array_add(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.add);
+}
+
+static PyObject *
+array_subtract(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.subtract);
+}
+
+static PyObject *
+array_multiply(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.multiply);
+}
+
+static PyObject *
+array_divide(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.divide);
+}
+
+static PyObject *
+array_remainder(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.remainder);
+}
+
+static int
+array_power_is_scalar(PyObject *o2, double* exp)
+{
+ PyObject *temp;
+ const int optimize_fpexps = 1;
+
+ if (PyInt_Check(o2)) {
+ *exp = (double)PyInt_AsLong(o2);
+ return 1;
+ }
+ if (optimize_fpexps && PyFloat_Check(o2)) {
+ *exp = PyFloat_AsDouble(o2);
+ return 1;
+ }
+ if ((PyArray_IsZeroDim(o2) &&
+ ((PyArray_ISINTEGER(o2) ||
+ (optimize_fpexps && PyArray_ISFLOAT(o2))))) ||
+ PyArray_IsScalar(o2, Integer) ||
+ (optimize_fpexps && PyArray_IsScalar(o2, Floating))) {
+ temp = o2->ob_type->tp_as_number->nb_float(o2);
+ if (temp != NULL) {
+ *exp = PyFloat_AsDouble(o2);
+ Py_DECREF(temp);
+ return 1;
+ }
+ }
+#if (PY_VERSION_HEX >= 0x02050000)
+ if (PyIndex_Check(o2)) {
+ PyObject* value = PyNumber_Index(o2);
+ Py_ssize_t val;
+ if (value==NULL) {
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ }
+ return 0;
+ }
+ val = PyInt_AsSsize_t(value);
+ if (val == -1 && PyErr_Occurred()) {
+ PyErr_Clear();
+ return 0;
+ }
+ *exp = (double) val;
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+/* optimize float array or complex array to a scalar power */
+static PyObject *
+fast_scalar_power(PyArrayObject *a1, PyObject *o2, int inplace)
+{
+ double exp;
+
+ if (PyArray_Check(a1) && array_power_is_scalar(o2, &exp)) {
+ PyObject *fastop = NULL;
+ if (PyArray_ISFLOAT(a1) || PyArray_ISCOMPLEX(a1)) {
+ if (exp == 1.0) {
+ /* we have to do this one special, as the
+ "copy" method of array objects isn't set
+ up early enough to be added
+ by PyArray_SetNumericOps.
+ */
+ if (inplace) {
+ Py_INCREF(a1);
+ return (PyObject *)a1;
+ } else {
+ return PyArray_Copy(a1);
+ }
+ }
+ else if (exp == -1.0) {
+ fastop = n_ops.reciprocal;
+ }
+ else if (exp == 0.0) {
+ fastop = n_ops.ones_like;
+ }
+ else if (exp == 0.5) {
+ fastop = n_ops.sqrt;
+ }
+ else if (exp == 2.0) {
+ fastop = n_ops.square;
+ }
+ else {
+ return NULL;
+ }
+
+ if (inplace) {
+ return PyArray_GenericInplaceUnaryFunction(a1, fastop);
+ } else {
+ return PyArray_GenericUnaryFunction(a1, fastop);
+ }
+ }
+ else if (exp==2.0) {
+ fastop = n_ops.multiply;
+ if (inplace) {
+ return PyArray_GenericInplaceBinaryFunction
+ (a1, (PyObject *)a1, fastop);
+ }
+ else {
+ return PyArray_GenericBinaryFunction
+ (a1, (PyObject *)a1, fastop);
+ }
+ }
+ }
+ return NULL;
+}
+
+static PyObject *
+array_power(PyArrayObject *a1, PyObject *o2, PyObject *NPY_UNUSED(modulo))
+{
+ /* modulo is ignored! */
+ PyObject *value;
+ value = fast_scalar_power(a1, o2, 0);
+ if (!value) {
+ value = PyArray_GenericBinaryFunction(a1, o2, n_ops.power);
+ }
+ return value;
+}
+
+
+static PyObject *
+array_negative(PyArrayObject *m1)
+{
+ return PyArray_GenericUnaryFunction(m1, n_ops.negative);
+}
+
+static PyObject *
+array_absolute(PyArrayObject *m1)
+{
+ return PyArray_GenericUnaryFunction(m1, n_ops.absolute);
+}
+
+static PyObject *
+array_invert(PyArrayObject *m1)
+{
+ return PyArray_GenericUnaryFunction(m1, n_ops.invert);
+}
+
+static PyObject *
+array_left_shift(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.left_shift);
+}
+
+static PyObject *
+array_right_shift(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.right_shift);
+}
+
+static PyObject *
+array_bitwise_and(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_and);
+}
+
+static PyObject *
+array_bitwise_or(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_or);
+}
+
+static PyObject *
+array_bitwise_xor(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_xor);
+}
+
+static PyObject *
+array_inplace_add(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.add);
+}
+
+static PyObject *
+array_inplace_subtract(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.subtract);
+}
+
+static PyObject *
+array_inplace_multiply(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.multiply);
+}
+
+static PyObject *
+array_inplace_divide(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.divide);
+}
+
+static PyObject *
+array_inplace_remainder(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.remainder);
+}
+
+static PyObject *
+array_inplace_power(PyArrayObject *a1, PyObject *o2, PyObject *NPY_UNUSED(modulo))
+{
+ /* modulo is ignored! */
+ PyObject *value;
+ value = fast_scalar_power(a1, o2, 1);
+ if (!value) {
+ value = PyArray_GenericInplaceBinaryFunction(a1, o2, n_ops.power);
+ }
+ return value;
+}
+
+static PyObject *
+array_inplace_left_shift(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.left_shift);
+}
+
+static PyObject *
+array_inplace_right_shift(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.right_shift);
+}
+
+static PyObject *
+array_inplace_bitwise_and(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_and);
+}
+
+static PyObject *
+array_inplace_bitwise_or(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_or);
+}
+
+static PyObject *
+array_inplace_bitwise_xor(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_xor);
+}
+
+static PyObject *
+array_floor_divide(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.floor_divide);
+}
+
+static PyObject *
+array_true_divide(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericBinaryFunction(m1, m2, n_ops.true_divide);
+}
+
+static PyObject *
+array_inplace_floor_divide(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2,
+ n_ops.floor_divide);
+}
+
+static PyObject *
+array_inplace_true_divide(PyArrayObject *m1, PyObject *m2)
+{
+ return PyArray_GenericInplaceBinaryFunction(m1, m2,
+ n_ops.true_divide);
+}
+
+/* Array evaluates as "TRUE" if any of the elements are non-zero*/
+NPY_NO_EXPORT int
+array_any_nonzero(PyArrayObject *mp)
+{
+ intp index;
+ PyArrayIterObject *it;
+ Bool anyTRUE = FALSE;
+
+ it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
+ if (it == NULL) {
+ return anyTRUE;
+ }
+ index = it->size;
+ while(index--) {
+ if (mp->descr->f->nonzero(it->dataptr, mp)) {
+ anyTRUE = TRUE;
+ break;
+ }
+ PyArray_ITER_NEXT(it);
+ }
+ Py_DECREF(it);
+ return anyTRUE;
+}
+
+static int
+_array_nonzero(PyArrayObject *mp)
+{
+ intp n;
+
+ n = PyArray_SIZE(mp);
+ if (n == 1) {
+ return mp->descr->f->nonzero(mp->data, mp);
+ }
+ else if (n == 0) {
+ return 0;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "The truth value of an array " \
+ "with more than one element is ambiguous. " \
+ "Use a.any() or a.all()");
+ return -1;
+ }
+}
+
+
+
+static PyObject *
+array_divmod(PyArrayObject *op1, PyObject *op2)
+{
+ PyObject *divp, *modp, *result;
+
+ divp = array_floor_divide(op1, op2);
+ if (divp == NULL) {
+ return NULL;
+ }
+ modp = array_remainder(op1, op2);
+ if (modp == NULL) {
+ Py_DECREF(divp);
+ return NULL;
+ }
+ result = Py_BuildValue("OO", divp, modp);
+ Py_DECREF(divp);
+ Py_DECREF(modp);
+ return result;
+}
+
+
+NPY_NO_EXPORT PyObject *
+array_int(PyArrayObject *v)
+{
+ PyObject *pv, *pv2;
+ if (PyArray_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError, "only length-1 arrays can be"\
+ " converted to Python scalars");
+ return NULL;
+ }
+ pv = v->descr->f->getitem(v->data, v);
+ if (pv == NULL) {
+ return NULL;
+ }
+ if (pv->ob_type->tp_as_number == 0) {
+ PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
+ "scalar object is not a number");
+ Py_DECREF(pv);
+ return NULL;
+ }
+ if (pv->ob_type->tp_as_number->nb_int == 0) {
+ PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
+ "scalar number to int");
+ Py_DECREF(pv);
+ return NULL;
+ }
+
+ pv2 = pv->ob_type->tp_as_number->nb_int(pv);
+ Py_DECREF(pv);
+ return pv2;
+}
+
+static PyObject *
+array_float(PyArrayObject *v)
+{
+ PyObject *pv, *pv2;
+ if (PyArray_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
+ "be converted to Python scalars");
+ return NULL;
+ }
+ pv = v->descr->f->getitem(v->data, v);
+ if (pv == NULL) {
+ return NULL;
+ }
+ if (pv->ob_type->tp_as_number == 0) {
+ PyErr_SetString(PyExc_TypeError, "cannot convert to a "\
+ "float; scalar object is not a number");
+ Py_DECREF(pv);
+ return NULL;
+ }
+ if (pv->ob_type->tp_as_number->nb_float == 0) {
+ PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
+ "scalar number to float");
+ Py_DECREF(pv);
+ return NULL;
+ }
+ pv2 = pv->ob_type->tp_as_number->nb_float(pv);
+ Py_DECREF(pv);
+ return pv2;
+}
+
+static PyObject *
+array_long(PyArrayObject *v)
+{
+ PyObject *pv, *pv2;
+ if (PyArray_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
+ "be converted to Python scalars");
+ return NULL;
+ }
+ pv = v->descr->f->getitem(v->data, v);
+ if (pv->ob_type->tp_as_number == 0) {
+ PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
+ "scalar object is not a number");
+ return NULL;
+ }
+ if (pv->ob_type->tp_as_number->nb_long == 0) {
+ PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
+ "scalar number to long");
+ return NULL;
+ }
+ pv2 = pv->ob_type->tp_as_number->nb_long(pv);
+ Py_DECREF(pv);
+ return pv2;
+}
+
+static PyObject *
+array_oct(PyArrayObject *v)
+{
+ PyObject *pv, *pv2;
+ if (PyArray_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
+ "be converted to Python scalars");
+ return NULL;
+ }
+ pv = v->descr->f->getitem(v->data, v);
+ if (pv->ob_type->tp_as_number == 0) {
+ PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
+ "scalar object is not a number");
+ return NULL;
+ }
+ if (pv->ob_type->tp_as_number->nb_oct == 0) {
+ PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
+ "scalar number to oct");
+ return NULL;
+ }
+ pv2 = pv->ob_type->tp_as_number->nb_oct(pv);
+ Py_DECREF(pv);
+ return pv2;
+}
+
+static PyObject *
+array_hex(PyArrayObject *v)
+{
+ PyObject *pv, *pv2;
+ if (PyArray_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
+ "be converted to Python scalars");
+ return NULL;
+ }
+ pv = v->descr->f->getitem(v->data, v);
+ if (pv->ob_type->tp_as_number == 0) {
+ PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
+ "scalar object is not a number");
+ return NULL;
+ }
+ if (pv->ob_type->tp_as_number->nb_hex == 0) {
+ PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
+ "scalar number to hex");
+ return NULL;
+ }
+ pv2 = pv->ob_type->tp_as_number->nb_hex(pv);
+ Py_DECREF(pv);
+ return pv2;
+}
+
+static PyObject *
+_array_copy_nice(PyArrayObject *self)
+{
+ return PyArray_Return((PyArrayObject *) PyArray_Copy(self));
+}
+
+#if PY_VERSION_HEX >= 0x02050000
+static PyObject *
+array_index(PyArrayObject *v)
+{
+ if (!PyArray_ISINTEGER(v) || PyArray_SIZE(v) != 1) {
+ PyErr_SetString(PyExc_TypeError, "only integer arrays with " \
+ "one element can be converted to an index");
+ return NULL;
+ }
+ return v->descr->f->getitem(v->data, v);
+}
+#endif
+
+
+NPY_NO_EXPORT PyNumberMethods array_as_number = {
+ (binaryfunc)array_add, /*nb_add*/
+ (binaryfunc)array_subtract, /*nb_subtract*/
+ (binaryfunc)array_multiply, /*nb_multiply*/
+ (binaryfunc)array_divide, /*nb_divide*/
+ (binaryfunc)array_remainder, /*nb_remainder*/
+ (binaryfunc)array_divmod, /*nb_divmod*/
+ (ternaryfunc)array_power, /*nb_power*/
+ (unaryfunc)array_negative, /*nb_neg*/
+ (unaryfunc)_array_copy_nice, /*nb_pos*/
+ (unaryfunc)array_absolute, /*(unaryfunc)array_abs,*/
+ (inquiry)_array_nonzero, /*nb_nonzero*/
+ (unaryfunc)array_invert, /*nb_invert*/
+ (binaryfunc)array_left_shift, /*nb_lshift*/
+ (binaryfunc)array_right_shift, /*nb_rshift*/
+ (binaryfunc)array_bitwise_and, /*nb_and*/
+ (binaryfunc)array_bitwise_xor, /*nb_xor*/
+ (binaryfunc)array_bitwise_or, /*nb_or*/
+ 0, /*nb_coerce*/
+ (unaryfunc)array_int, /*nb_int*/
+ (unaryfunc)array_long, /*nb_long*/
+ (unaryfunc)array_float, /*nb_float*/
+ (unaryfunc)array_oct, /*nb_oct*/
+ (unaryfunc)array_hex, /*nb_hex*/
+
+ /*
+ * This code adds augmented assignment functionality
+ * that was made available in Python 2.0
+ */
+ (binaryfunc)array_inplace_add, /*inplace_add*/
+ (binaryfunc)array_inplace_subtract, /*inplace_subtract*/
+ (binaryfunc)array_inplace_multiply, /*inplace_multiply*/
+ (binaryfunc)array_inplace_divide, /*inplace_divide*/
+ (binaryfunc)array_inplace_remainder, /*inplace_remainder*/
+ (ternaryfunc)array_inplace_power, /*inplace_power*/
+ (binaryfunc)array_inplace_left_shift, /*inplace_lshift*/
+ (binaryfunc)array_inplace_right_shift, /*inplace_rshift*/
+ (binaryfunc)array_inplace_bitwise_and, /*inplace_and*/
+ (binaryfunc)array_inplace_bitwise_xor, /*inplace_xor*/
+ (binaryfunc)array_inplace_bitwise_or, /*inplace_or*/
+
+ (binaryfunc)array_floor_divide, /*nb_floor_divide*/
+ (binaryfunc)array_true_divide, /*nb_true_divide*/
+ (binaryfunc)array_inplace_floor_divide, /*nb_inplace_floor_divide*/
+ (binaryfunc)array_inplace_true_divide, /*nb_inplace_true_divide*/
+
+#if PY_VERSION_HEX >= 0x02050000
+ (unaryfunc)array_index, /* nb_index */
+#endif
+
+};
diff --git a/numpy/core/src/arraynumber.h b/numpy/core/src/arraynumber.h
new file mode 100644
index 000000000..8c004a198
--- /dev/null
+++ b/numpy/core/src/arraynumber.h
@@ -0,0 +1,19 @@
+#ifndef _NPY_ARRAY_NUMBER_H_
+#define _NPY_ARRAY_NUMBER_H_
+
+extern NPY_NO_EXPORT NumericOps n_ops;
+extern NPY_NO_EXPORT PyNumberMethods array_as_number;
+
+NPY_NO_EXPORT int
+array_any_nonzero(PyArrayObject *mp);
+
+NPY_NO_EXPORT PyObject *
+array_int(PyArrayObject *v);
+
+NPY_NO_EXPORT int
+PyArray_SetNumericOps(PyObject *dict);
+
+NPY_NO_EXPORT PyObject *
+PyArray_GetNumericOps(void);
+
+#endif
diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c
index 1d9256b28..be4932551 100644
--- a/numpy/core/src/arrayobject.c
+++ b/numpy/core/src/arrayobject.c
@@ -34,6 +34,7 @@ maintainer email: oliphant.travis@ieee.org
#include "arraydescr.h"
#include "arrayiterators.h"
#include "arraymapping.h"
+#include "arraygetset.h"
#ifndef Py_UNICODE_WIDE
#include "ucsnarrow.h"
#endif
@@ -652,9 +653,6 @@ PyArray_PyIntAsIntp(PyObject *o)
return (intp) long_value;
}
-
-static PyObject *array_int(PyArrayObject *v);
-
/*NUMPY_API*/
NPY_NO_EXPORT int
PyArray_PyIntAsInt(PyObject *o)
@@ -2221,805 +2219,6 @@ static PyBufferProcs array_as_buffer = {
/*************************************************************************
- **************** Implement Number Protocol ****************************
- *************************************************************************/
-
-NPY_NO_EXPORT NumericOps n_ops; /* NB: static objects initialized to zero */
-
-/* Dictionary can contain any of the numeric operations, by name.
- Those not present will not be changed
-*/
-
-#define SET(op) temp=PyDict_GetItemString(dict, #op); \
- if (temp != NULL) { \
- if (!(PyCallable_Check(temp))) return -1; \
- Py_XDECREF(n_ops.op); \
- n_ops.op = temp; \
- }
-
-
-/*NUMPY_API
- Set internal structure with number functions that all arrays will use
-*/
-NPY_NO_EXPORT int
-PyArray_SetNumericOps(PyObject *dict)
-{
- PyObject *temp = NULL;
- SET(add);
- SET(subtract);
- SET(multiply);
- SET(divide);
- SET(remainder);
- SET(power);
- SET(square);
- SET(reciprocal);
- SET(ones_like);
- SET(sqrt);
- SET(negative);
- SET(absolute);
- SET(invert);
- SET(left_shift);
- SET(right_shift);
- SET(bitwise_and);
- SET(bitwise_or);
- SET(bitwise_xor);
- SET(less);
- SET(less_equal);
- SET(equal);
- SET(not_equal);
- SET(greater);
- SET(greater_equal);
- SET(floor_divide);
- SET(true_divide);
- SET(logical_or);
- SET(logical_and);
- SET(floor);
- SET(ceil);
- SET(maximum);
- SET(minimum);
- SET(rint);
- SET(conjugate);
- return 0;
-}
-
-#define GET(op) if (n_ops.op && \
- (PyDict_SetItemString(dict, #op, n_ops.op)==-1)) \
- goto fail;
-
-/*NUMPY_API
- Get dictionary showing number functions that all arrays will use
-*/
-NPY_NO_EXPORT PyObject *
-PyArray_GetNumericOps(void)
-{
- PyObject *dict;
- if ((dict = PyDict_New())==NULL)
- return NULL;
- GET(add);
- GET(subtract);
- GET(multiply);
- GET(divide);
- GET(remainder);
- GET(power);
- GET(square);
- GET(reciprocal);
- GET(ones_like);
- GET(sqrt);
- GET(negative);
- GET(absolute);
- GET(invert);
- GET(left_shift);
- GET(right_shift);
- GET(bitwise_and);
- GET(bitwise_or);
- GET(bitwise_xor);
- GET(less);
- GET(less_equal);
- GET(equal);
- GET(not_equal);
- GET(greater);
- GET(greater_equal);
- GET(floor_divide);
- GET(true_divide);
- GET(logical_or);
- GET(logical_and);
- GET(floor);
- GET(ceil);
- GET(maximum);
- GET(minimum);
- GET(rint);
- GET(conjugate);
- return dict;
-
- fail:
- Py_DECREF(dict);
- return NULL;
-}
-
-static PyObject *
-_get_keywords(int rtype, PyArrayObject *out)
-{
- PyObject *kwds = NULL;
- if (rtype != PyArray_NOTYPE || out != NULL) {
- kwds = PyDict_New();
- if (rtype != PyArray_NOTYPE) {
- PyArray_Descr *descr;
- descr = PyArray_DescrFromType(rtype);
- if (descr) {
- PyDict_SetItemString(kwds, "dtype", (PyObject *)descr);
- Py_DECREF(descr);
- }
- }
- if (out != NULL) {
- PyDict_SetItemString(kwds, "out", (PyObject *)out);
- }
- }
- return kwds;
-}
-
-NPY_NO_EXPORT PyObject *
-PyArray_GenericReduceFunction(PyArrayObject *m1, PyObject *op, int axis,
- int rtype, PyArrayObject *out)
-{
- PyObject *args, *ret = NULL, *meth;
- PyObject *kwds;
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- args = Py_BuildValue("(Oi)", m1, axis);
- kwds = _get_keywords(rtype, out);
- meth = PyObject_GetAttrString(op, "reduce");
- if (meth && PyCallable_Check(meth)) {
- ret = PyObject_Call(meth, args, kwds);
- }
- Py_DECREF(args);
- Py_DECREF(meth);
- Py_XDECREF(kwds);
- return ret;
-}
-
-
-NPY_NO_EXPORT PyObject *
-PyArray_GenericAccumulateFunction(PyArrayObject *m1, PyObject *op, int axis,
- int rtype, PyArrayObject *out)
-{
- PyObject *args, *ret = NULL, *meth;
- PyObject *kwds;
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- args = Py_BuildValue("(Oi)", m1, axis);
- kwds = _get_keywords(rtype, out);
- meth = PyObject_GetAttrString(op, "accumulate");
- if (meth && PyCallable_Check(meth)) {
- ret = PyObject_Call(meth, args, kwds);
- }
- Py_DECREF(args);
- Py_DECREF(meth);
- Py_XDECREF(kwds);
- return ret;
-}
-
-
-NPY_NO_EXPORT PyObject *
-PyArray_GenericBinaryFunction(PyArrayObject *m1, PyObject *m2, PyObject *op)
-{
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- return PyObject_CallFunction(op, "OO", m1, m2);
-}
-
-NPY_NO_EXPORT PyObject *
-PyArray_GenericUnaryFunction(PyArrayObject *m1, PyObject *op)
-{
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- return PyObject_CallFunction(op, "(O)", m1);
-}
-
-static PyObject *
-PyArray_GenericInplaceBinaryFunction(PyArrayObject *m1,
- PyObject *m2, PyObject *op)
-{
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- return PyObject_CallFunction(op, "OOO", m1, m2, m1);
-}
-
-static PyObject *
-PyArray_GenericInplaceUnaryFunction(PyArrayObject *m1, PyObject *op)
-{
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- return PyObject_CallFunction(op, "OO", m1, m1);
-}
-
-static PyObject *
-array_add(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.add);
-}
-
-static PyObject *
-array_subtract(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.subtract);
-}
-
-static PyObject *
-array_multiply(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.multiply);
-}
-
-static PyObject *
-array_divide(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.divide);
-}
-
-static PyObject *
-array_remainder(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.remainder);
-}
-
-static int
-array_power_is_scalar(PyObject *o2, double* exp)
-{
- PyObject *temp;
- const int optimize_fpexps = 1;
-
- if (PyInt_Check(o2)) {
- *exp = (double)PyInt_AsLong(o2);
- return 1;
- }
- if (optimize_fpexps && PyFloat_Check(o2)) {
- *exp = PyFloat_AsDouble(o2);
- return 1;
- }
- if ((PyArray_IsZeroDim(o2) &&
- ((PyArray_ISINTEGER(o2) ||
- (optimize_fpexps && PyArray_ISFLOAT(o2))))) ||
- PyArray_IsScalar(o2, Integer) ||
- (optimize_fpexps && PyArray_IsScalar(o2, Floating))) {
- temp = o2->ob_type->tp_as_number->nb_float(o2);
- if (temp != NULL) {
- *exp = PyFloat_AsDouble(o2);
- Py_DECREF(temp);
- return 1;
- }
- }
-#if (PY_VERSION_HEX >= 0x02050000)
- if (PyIndex_Check(o2)) {
- PyObject* value = PyNumber_Index(o2);
- Py_ssize_t val;
- if (value==NULL) {
- if (PyErr_Occurred()) {
- PyErr_Clear();
- }
- return 0;
- }
- val = PyInt_AsSsize_t(value);
- if (val == -1 && PyErr_Occurred()) {
- PyErr_Clear();
- return 0;
- }
- *exp = (double) val;
- return 1;
- }
-#endif
- return 0;
-}
-
-/* optimize float array or complex array to a scalar power */
-static PyObject *
-fast_scalar_power(PyArrayObject *a1, PyObject *o2, int inplace)
-{
- double exp;
-
- if (PyArray_Check(a1) && array_power_is_scalar(o2, &exp)) {
- PyObject *fastop = NULL;
- if (PyArray_ISFLOAT(a1) || PyArray_ISCOMPLEX(a1)) {
- if (exp == 1.0) {
- /* we have to do this one special, as the
- "copy" method of array objects isn't set
- up early enough to be added
- by PyArray_SetNumericOps.
- */
- if (inplace) {
- Py_INCREF(a1);
- return (PyObject *)a1;
- } else {
- return PyArray_Copy(a1);
- }
- }
- else if (exp == -1.0) {
- fastop = n_ops.reciprocal;
- }
- else if (exp == 0.0) {
- fastop = n_ops.ones_like;
- }
- else if (exp == 0.5) {
- fastop = n_ops.sqrt;
- }
- else if (exp == 2.0) {
- fastop = n_ops.square;
- }
- else {
- return NULL;
- }
-
- if (inplace) {
- return PyArray_GenericInplaceUnaryFunction(a1, fastop);
- } else {
- return PyArray_GenericUnaryFunction(a1, fastop);
- }
- }
- else if (exp==2.0) {
- fastop = n_ops.multiply;
- if (inplace) {
- return PyArray_GenericInplaceBinaryFunction
- (a1, (PyObject *)a1, fastop);
- }
- else {
- return PyArray_GenericBinaryFunction
- (a1, (PyObject *)a1, fastop);
- }
- }
- }
- return NULL;
-}
-
-static PyObject *
-array_power(PyArrayObject *a1, PyObject *o2, PyObject *NPY_UNUSED(modulo))
-{
- /* modulo is ignored! */
- PyObject *value;
- value = fast_scalar_power(a1, o2, 0);
- if (!value) {
- value = PyArray_GenericBinaryFunction(a1, o2, n_ops.power);
- }
- return value;
-}
-
-
-static PyObject *
-array_negative(PyArrayObject *m1)
-{
- return PyArray_GenericUnaryFunction(m1, n_ops.negative);
-}
-
-static PyObject *
-array_absolute(PyArrayObject *m1)
-{
- return PyArray_GenericUnaryFunction(m1, n_ops.absolute);
-}
-
-static PyObject *
-array_invert(PyArrayObject *m1)
-{
- return PyArray_GenericUnaryFunction(m1, n_ops.invert);
-}
-
-static PyObject *
-array_left_shift(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.left_shift);
-}
-
-static PyObject *
-array_right_shift(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.right_shift);
-}
-
-static PyObject *
-array_bitwise_and(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_and);
-}
-
-static PyObject *
-array_bitwise_or(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_or);
-}
-
-static PyObject *
-array_bitwise_xor(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_xor);
-}
-
-static PyObject *
-array_inplace_add(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.add);
-}
-
-static PyObject *
-array_inplace_subtract(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.subtract);
-}
-
-static PyObject *
-array_inplace_multiply(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.multiply);
-}
-
-static PyObject *
-array_inplace_divide(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.divide);
-}
-
-static PyObject *
-array_inplace_remainder(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.remainder);
-}
-
-static PyObject *
-array_inplace_power(PyArrayObject *a1, PyObject *o2, PyObject *NPY_UNUSED(modulo))
-{
- /* modulo is ignored! */
- PyObject *value;
- value = fast_scalar_power(a1, o2, 1);
- if (!value) {
- value = PyArray_GenericInplaceBinaryFunction(a1, o2, n_ops.power);
- }
- return value;
-}
-
-static PyObject *
-array_inplace_left_shift(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.left_shift);
-}
-
-static PyObject *
-array_inplace_right_shift(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.right_shift);
-}
-
-static PyObject *
-array_inplace_bitwise_and(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_and);
-}
-
-static PyObject *
-array_inplace_bitwise_or(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_or);
-}
-
-static PyObject *
-array_inplace_bitwise_xor(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_xor);
-}
-
-static PyObject *
-array_floor_divide(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.floor_divide);
-}
-
-static PyObject *
-array_true_divide(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericBinaryFunction(m1, m2, n_ops.true_divide);
-}
-
-static PyObject *
-array_inplace_floor_divide(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2,
- n_ops.floor_divide);
-}
-
-static PyObject *
-array_inplace_true_divide(PyArrayObject *m1, PyObject *m2)
-{
- return PyArray_GenericInplaceBinaryFunction(m1, m2,
- n_ops.true_divide);
-}
-
-/* Array evaluates as "TRUE" if any of the elements are non-zero*/
-static int
-array_any_nonzero(PyArrayObject *mp)
-{
- intp index;
- PyArrayIterObject *it;
- Bool anyTRUE = FALSE;
-
- it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
- if (it == NULL) {
- return anyTRUE;
- }
- index = it->size;
- while(index--) {
- if (mp->descr->f->nonzero(it->dataptr, mp)) {
- anyTRUE = TRUE;
- break;
- }
- PyArray_ITER_NEXT(it);
- }
- Py_DECREF(it);
- return anyTRUE;
-}
-
-static int
-_array_nonzero(PyArrayObject *mp)
-{
- intp n;
-
- n = PyArray_SIZE(mp);
- if (n == 1) {
- return mp->descr->f->nonzero(mp->data, mp);
- }
- else if (n == 0) {
- return 0;
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "The truth value of an array " \
- "with more than one element is ambiguous. " \
- "Use a.any() or a.all()");
- return -1;
- }
-}
-
-
-
-static PyObject *
-array_divmod(PyArrayObject *op1, PyObject *op2)
-{
- PyObject *divp, *modp, *result;
-
- divp = array_floor_divide(op1, op2);
- if (divp == NULL) {
- return NULL;
- }
- modp = array_remainder(op1, op2);
- if (modp == NULL) {
- Py_DECREF(divp);
- return NULL;
- }
- result = Py_BuildValue("OO", divp, modp);
- Py_DECREF(divp);
- Py_DECREF(modp);
- return result;
-}
-
-
-static PyObject *
-array_int(PyArrayObject *v)
-{
- PyObject *pv, *pv2;
- if (PyArray_SIZE(v) != 1) {
- PyErr_SetString(PyExc_TypeError, "only length-1 arrays can be"\
- " converted to Python scalars");
- return NULL;
- }
- pv = v->descr->f->getitem(v->data, v);
- if (pv == NULL) {
- return NULL;
- }
- if (pv->ob_type->tp_as_number == 0) {
- PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
- "scalar object is not a number");
- Py_DECREF(pv);
- return NULL;
- }
- if (pv->ob_type->tp_as_number->nb_int == 0) {
- PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
- "scalar number to int");
- Py_DECREF(pv);
- return NULL;
- }
-
- pv2 = pv->ob_type->tp_as_number->nb_int(pv);
- Py_DECREF(pv);
- return pv2;
-}
-
-static PyObject *
-array_float(PyArrayObject *v)
-{
- PyObject *pv, *pv2;
- if (PyArray_SIZE(v) != 1) {
- PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
- "be converted to Python scalars");
- return NULL;
- }
- pv = v->descr->f->getitem(v->data, v);
- if (pv == NULL) {
- return NULL;
- }
- if (pv->ob_type->tp_as_number == 0) {
- PyErr_SetString(PyExc_TypeError, "cannot convert to a "\
- "float; scalar object is not a number");
- Py_DECREF(pv);
- return NULL;
- }
- if (pv->ob_type->tp_as_number->nb_float == 0) {
- PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
- "scalar number to float");
- Py_DECREF(pv);
- return NULL;
- }
- pv2 = pv->ob_type->tp_as_number->nb_float(pv);
- Py_DECREF(pv);
- return pv2;
-}
-
-static PyObject *
-array_long(PyArrayObject *v)
-{
- PyObject *pv, *pv2;
- if (PyArray_SIZE(v) != 1) {
- PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
- "be converted to Python scalars");
- return NULL;
- }
- pv = v->descr->f->getitem(v->data, v);
- if (pv->ob_type->tp_as_number == 0) {
- PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
- "scalar object is not a number");
- return NULL;
- }
- if (pv->ob_type->tp_as_number->nb_long == 0) {
- PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
- "scalar number to long");
- return NULL;
- }
- pv2 = pv->ob_type->tp_as_number->nb_long(pv);
- Py_DECREF(pv);
- return pv2;
-}
-
-static PyObject *
-array_oct(PyArrayObject *v)
-{
- PyObject *pv, *pv2;
- if (PyArray_SIZE(v) != 1) {
- PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
- "be converted to Python scalars");
- return NULL;
- }
- pv = v->descr->f->getitem(v->data, v);
- if (pv->ob_type->tp_as_number == 0) {
- PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
- "scalar object is not a number");
- return NULL;
- }
- if (pv->ob_type->tp_as_number->nb_oct == 0) {
- PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
- "scalar number to oct");
- return NULL;
- }
- pv2 = pv->ob_type->tp_as_number->nb_oct(pv);
- Py_DECREF(pv);
- return pv2;
-}
-
-static PyObject *
-array_hex(PyArrayObject *v)
-{
- PyObject *pv, *pv2;
- if (PyArray_SIZE(v) != 1) {
- PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
- "be converted to Python scalars");
- return NULL;
- }
- pv = v->descr->f->getitem(v->data, v);
- if (pv->ob_type->tp_as_number == 0) {
- PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
- "scalar object is not a number");
- return NULL;
- }
- if (pv->ob_type->tp_as_number->nb_hex == 0) {
- PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
- "scalar number to hex");
- return NULL;
- }
- pv2 = pv->ob_type->tp_as_number->nb_hex(pv);
- Py_DECREF(pv);
- return pv2;
-}
-
-static PyObject *
-_array_copy_nice(PyArrayObject *self)
-{
- return PyArray_Return((PyArrayObject *) PyArray_Copy(self));
-}
-
-#if PY_VERSION_HEX >= 0x02050000
-static PyObject *
-array_index(PyArrayObject *v)
-{
- if (!PyArray_ISINTEGER(v) || PyArray_SIZE(v) != 1) {
- PyErr_SetString(PyExc_TypeError, "only integer arrays with " \
- "one element can be converted to an index");
- return NULL;
- }
- return v->descr->f->getitem(v->data, v);
-}
-#endif
-
-
-static PyNumberMethods array_as_number = {
- (binaryfunc)array_add, /*nb_add*/
- (binaryfunc)array_subtract, /*nb_subtract*/
- (binaryfunc)array_multiply, /*nb_multiply*/
- (binaryfunc)array_divide, /*nb_divide*/
- (binaryfunc)array_remainder, /*nb_remainder*/
- (binaryfunc)array_divmod, /*nb_divmod*/
- (ternaryfunc)array_power, /*nb_power*/
- (unaryfunc)array_negative, /*nb_neg*/
- (unaryfunc)_array_copy_nice, /*nb_pos*/
- (unaryfunc)array_absolute, /*(unaryfunc)array_abs,*/
- (inquiry)_array_nonzero, /*nb_nonzero*/
- (unaryfunc)array_invert, /*nb_invert*/
- (binaryfunc)array_left_shift, /*nb_lshift*/
- (binaryfunc)array_right_shift, /*nb_rshift*/
- (binaryfunc)array_bitwise_and, /*nb_and*/
- (binaryfunc)array_bitwise_xor, /*nb_xor*/
- (binaryfunc)array_bitwise_or, /*nb_or*/
- 0, /*nb_coerce*/
- (unaryfunc)array_int, /*nb_int*/
- (unaryfunc)array_long, /*nb_long*/
- (unaryfunc)array_float, /*nb_float*/
- (unaryfunc)array_oct, /*nb_oct*/
- (unaryfunc)array_hex, /*nb_hex*/
-
- /*
- * This code adds augmented assignment functionality
- * that was made available in Python 2.0
- */
- (binaryfunc)array_inplace_add, /*inplace_add*/
- (binaryfunc)array_inplace_subtract, /*inplace_subtract*/
- (binaryfunc)array_inplace_multiply, /*inplace_multiply*/
- (binaryfunc)array_inplace_divide, /*inplace_divide*/
- (binaryfunc)array_inplace_remainder, /*inplace_remainder*/
- (ternaryfunc)array_inplace_power, /*inplace_power*/
- (binaryfunc)array_inplace_left_shift, /*inplace_lshift*/
- (binaryfunc)array_inplace_right_shift, /*inplace_rshift*/
- (binaryfunc)array_inplace_bitwise_and, /*inplace_and*/
- (binaryfunc)array_inplace_bitwise_xor, /*inplace_xor*/
- (binaryfunc)array_inplace_bitwise_or, /*inplace_or*/
-
- (binaryfunc)array_floor_divide, /*nb_floor_divide*/
- (binaryfunc)array_true_divide, /*nb_true_divide*/
- (binaryfunc)array_inplace_floor_divide, /*nb_inplace_floor_divide*/
- (binaryfunc)array_inplace_true_divide, /*nb_inplace_true_divide*/
-
-#if PY_VERSION_HEX >= 0x02050000
- (unaryfunc)array_index, /* nb_index */
-#endif
-
-};
-
-/****************** End of Buffer Protocol *******************************/
-
-
-/*************************************************************************
**************** Implement Sequence Protocol **************************
*************************************************************************/
@@ -5244,877 +4443,6 @@ array_iter(PyArrayObject *arr)
return PySeqIter_New((PyObject *)arr);
}
-
-/******************* array attribute get and set routines ******************/
-
-static PyObject *
-array_ndim_get(PyArrayObject *self)
-{
- return PyInt_FromLong(self->nd);
-}
-
-static PyObject *
-array_flags_get(PyArrayObject *self)
-{
- return PyArray_NewFlagsObject((PyObject *)self);
-}
-
-static PyObject *
-array_shape_get(PyArrayObject *self)
-{
- return PyArray_IntTupleFromIntp(self->nd, self->dimensions);
-}
-
-
-static int
-array_shape_set(PyArrayObject *self, PyObject *val)
-{
- int nd;
- PyObject *ret;
-
- /* Assumes C-order */
- ret = PyArray_Reshape(self, val);
- if (ret == NULL) {
- return -1;
- }
- if (PyArray_DATA(ret) != PyArray_DATA(self)) {
- Py_DECREF(ret);
- PyErr_SetString(PyExc_AttributeError,
- "incompatible shape for a non-contiguous "\
- "array");
- return -1;
- }
-
- /* Free old dimensions and strides */
- PyDimMem_FREE(self->dimensions);
- nd = PyArray_NDIM(ret);
- self->nd = nd;
- if (nd > 0) {
- /* create new dimensions and strides */
- self->dimensions = PyDimMem_NEW(2*nd);
- if (self->dimensions == NULL) {
- Py_DECREF(ret);
- PyErr_SetString(PyExc_MemoryError,"");
- return -1;
- }
- self->strides = self->dimensions + nd;
- memcpy(self->dimensions, PyArray_DIMS(ret), nd*sizeof(intp));
- memcpy(self->strides, PyArray_STRIDES(ret), nd*sizeof(intp));
- }
- else {
- self->dimensions = NULL;
- self->strides = NULL;
- }
- Py_DECREF(ret);
- PyArray_UpdateFlags(self, CONTIGUOUS | FORTRAN);
- return 0;
-}
-
-
-static PyObject *
-array_strides_get(PyArrayObject *self)
-{
- return PyArray_IntTupleFromIntp(self->nd, self->strides);
-}
-
-static int
-array_strides_set(PyArrayObject *self, PyObject *obj)
-{
- PyArray_Dims newstrides = {NULL, 0};
- PyArrayObject *new;
- intp numbytes = 0;
- intp offset = 0;
- Py_ssize_t buf_len;
- char *buf;
-
- if (!PyArray_IntpConverter(obj, &newstrides) ||
- newstrides.ptr == NULL) {
- PyErr_SetString(PyExc_TypeError, "invalid strides");
- return -1;
- }
- if (newstrides.len != self->nd) {
- PyErr_Format(PyExc_ValueError, "strides must be " \
- " same length as shape (%d)", self->nd);
- goto fail;
- }
- new = self;
- while(new->base && PyArray_Check(new->base)) {
- new = (PyArrayObject *)(new->base);
- }
- /*
- * Get the available memory through the buffer interface on
- * new->base or if that fails from the current new
- */
- if (new->base && PyObject_AsReadBuffer(new->base,
- (const void **)&buf,
- &buf_len) >= 0) {
- offset = self->data - buf;
- numbytes = buf_len + offset;
- }
- else {
- PyErr_Clear();
- numbytes = PyArray_MultiplyList(new->dimensions,
- new->nd)*new->descr->elsize;
- offset = self->data - new->data;
- }
-
- if (!PyArray_CheckStrides(self->descr->elsize, self->nd, numbytes,
- offset,
- self->dimensions, newstrides.ptr)) {
- PyErr_SetString(PyExc_ValueError, "strides is not "\
- "compatible with available memory");
- goto fail;
- }
- memcpy(self->strides, newstrides.ptr, sizeof(intp)*newstrides.len);
- PyArray_UpdateFlags(self, CONTIGUOUS | FORTRAN);
- PyDimMem_FREE(newstrides.ptr);
- return 0;
-
- fail:
- PyDimMem_FREE(newstrides.ptr);
- return -1;
-}
-
-
-
-static PyObject *
-array_priority_get(PyArrayObject *self)
-{
- if (PyArray_CheckExact(self)) {
- return PyFloat_FromDouble(PyArray_PRIORITY);
- }
- else {
- return PyFloat_FromDouble(PyArray_SUBTYPE_PRIORITY);
- }
-}
-
-static PyObject *
-array_typestr_get(PyArrayObject *self)
-{
- return arraydescr_protocol_typestr_get(self->descr);
-}
-
-static PyObject *
-array_descr_get(PyArrayObject *self)
-{
- Py_INCREF(self->descr);
- return (PyObject *)self->descr;
-}
-
-static PyObject *
-array_protocol_descr_get(PyArrayObject *self)
-{
- PyObject *res;
- PyObject *dobj;
-
- res = arraydescr_protocol_descr_get(self->descr);
- if (res) {
- return res;
- }
- PyErr_Clear();
-
- /* get default */
- dobj = PyTuple_New(2);
- if (dobj == NULL) {
- return NULL;
- }
- PyTuple_SET_ITEM(dobj, 0, PyString_FromString(""));
- PyTuple_SET_ITEM(dobj, 1, array_typestr_get(self));
- res = PyList_New(1);
- if (res == NULL) {
- Py_DECREF(dobj);
- return NULL;
- }
- PyList_SET_ITEM(res, 0, dobj);
- return res;
-}
-
-static PyObject *
-array_protocol_strides_get(PyArrayObject *self)
-{
- if PyArray_ISCONTIGUOUS(self) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- return PyArray_IntTupleFromIntp(self->nd, self->strides);
-}
-
-
-
-static PyObject *
-array_dataptr_get(PyArrayObject *self)
-{
- return Py_BuildValue("NO",
- PyLong_FromVoidPtr(self->data),
- (self->flags & WRITEABLE ? Py_False :
- Py_True));
-}
-
-static PyObject *
-array_ctypes_get(PyArrayObject *self)
-{
- PyObject *_numpy_internal;
- PyObject *ret;
- _numpy_internal = PyImport_ImportModule("numpy.core._internal");
- if (_numpy_internal == NULL) {
- return NULL;
- }
- ret = PyObject_CallMethod(_numpy_internal, "_ctypes", "ON", self,
- PyLong_FromVoidPtr(self->data));
- Py_DECREF(_numpy_internal);
- return ret;
-}
-
-static PyObject *
-array_interface_get(PyArrayObject *self)
-{
- PyObject *dict;
- PyObject *obj;
-
- dict = PyDict_New();
- if (dict == NULL) {
- return NULL;
- }
-
- /* dataptr */
- obj = array_dataptr_get(self);
- PyDict_SetItemString(dict, "data", obj);
- Py_DECREF(obj);
-
- obj = array_protocol_strides_get(self);
- PyDict_SetItemString(dict, "strides", obj);
- Py_DECREF(obj);
-
- obj = array_protocol_descr_get(self);
- PyDict_SetItemString(dict, "descr", obj);
- Py_DECREF(obj);
-
- obj = arraydescr_protocol_typestr_get(self->descr);
- PyDict_SetItemString(dict, "typestr", obj);
- Py_DECREF(obj);
-
- obj = array_shape_get(self);
- PyDict_SetItemString(dict, "shape", obj);
- Py_DECREF(obj);
-
- obj = PyInt_FromLong(3);
- PyDict_SetItemString(dict, "version", obj);
- Py_DECREF(obj);
-
- return dict;
-}
-
-static PyObject *
-array_data_get(PyArrayObject *self)
-{
- intp nbytes;
- if (!(PyArray_ISONESEGMENT(self))) {
- PyErr_SetString(PyExc_AttributeError, "cannot get single-"\
- "segment buffer for discontiguous array");
- return NULL;
- }
- nbytes = PyArray_NBYTES(self);
- if PyArray_ISWRITEABLE(self) {
- return PyBuffer_FromReadWriteObject((PyObject *)self, 0, (Py_ssize_t) nbytes);
- }
- else {
- return PyBuffer_FromObject((PyObject *)self, 0, (Py_ssize_t) nbytes);
- }
-}
-
-static int
-array_data_set(PyArrayObject *self, PyObject *op)
-{
- void *buf;
- Py_ssize_t buf_len;
- int writeable=1;
-
- if (PyObject_AsWriteBuffer(op, &buf, &buf_len) < 0) {
- writeable = 0;
- if (PyObject_AsReadBuffer(op, (const void **)&buf, &buf_len) < 0) {
- PyErr_SetString(PyExc_AttributeError,
- "object does not have single-segment " \
- "buffer interface");
- return -1;
- }
- }
- if (!PyArray_ISONESEGMENT(self)) {
- PyErr_SetString(PyExc_AttributeError, "cannot set single-" \
- "segment buffer for discontiguous array");
- return -1;
- }
- if (PyArray_NBYTES(self) > buf_len) {
- PyErr_SetString(PyExc_AttributeError, "not enough data for array");
- return -1;
- }
- if (self->flags & OWNDATA) {
- PyArray_XDECREF(self);
- PyDataMem_FREE(self->data);
- }
- if (self->base) {
- if (self->flags & UPDATEIFCOPY) {
- ((PyArrayObject *)self->base)->flags |= WRITEABLE;
- self->flags &= ~UPDATEIFCOPY;
- }
- Py_DECREF(self->base);
- }
- Py_INCREF(op);
- self->base = op;
- self->data = buf;
- self->flags = CARRAY;
- if (!writeable) {
- self->flags &= ~WRITEABLE;
- }
- return 0;
-}
-
-
-static PyObject *
-array_itemsize_get(PyArrayObject *self)
-{
- return PyInt_FromLong((long) self->descr->elsize);
-}
-
-static PyObject *
-array_size_get(PyArrayObject *self)
-{
- intp size=PyArray_SIZE(self);
-#if SIZEOF_INTP <= SIZEOF_LONG
- return PyInt_FromLong((long) size);
-#else
- if (size > MAX_LONG || size < MIN_LONG) {
- return PyLong_FromLongLong(size);
- }
- else {
- return PyInt_FromLong((long) size);
- }
-#endif
-}
-
-static PyObject *
-array_nbytes_get(PyArrayObject *self)
-{
- intp nbytes = PyArray_NBYTES(self);
-#if SIZEOF_INTP <= SIZEOF_LONG
- return PyInt_FromLong((long) nbytes);
-#else
- if (nbytes > MAX_LONG || nbytes < MIN_LONG) {
- return PyLong_FromLongLong(nbytes);
- }
- else {
- return PyInt_FromLong((long) nbytes);
- }
-#endif
-}
-
-
-/*
- * If the type is changed.
- * Also needing change: strides, itemsize
- *
- * Either itemsize is exactly the same or the array is single-segment
- * (contiguous or fortran) with compatibile dimensions The shape and strides
- * will be adjusted in that case as well.
- */
-
-static int
-array_descr_set(PyArrayObject *self, PyObject *arg)
-{
- PyArray_Descr *newtype = NULL;
- intp newdim;
- int index;
- char *msg = "new type not compatible with array.";
-
- if (!(PyArray_DescrConverter(arg, &newtype)) ||
- newtype == NULL) {
- PyErr_SetString(PyExc_TypeError, "invalid data-type for array");
- return -1;
- }
- if (PyDataType_FLAGCHK(newtype, NPY_ITEM_HASOBJECT) ||
- PyDataType_FLAGCHK(newtype, NPY_ITEM_IS_POINTER) ||
- PyDataType_FLAGCHK(self->descr, NPY_ITEM_HASOBJECT) ||
- PyDataType_FLAGCHK(self->descr, NPY_ITEM_IS_POINTER)) {
- PyErr_SetString(PyExc_TypeError, \
- "Cannot change data-type for object " \
- "array.");
- Py_DECREF(newtype);
- return -1;
- }
-
- if (newtype->elsize == 0) {
- PyErr_SetString(PyExc_TypeError,
- "data-type must not be 0-sized");
- Py_DECREF(newtype);
- return -1;
- }
-
-
- if ((newtype->elsize != self->descr->elsize) &&
- (self->nd == 0 || !PyArray_ISONESEGMENT(self) ||
- newtype->subarray)) {
- goto fail;
- }
- if (PyArray_ISCONTIGUOUS(self)) {
- index = self->nd - 1;
- }
- else {
- index = 0;
- }
- if (newtype->elsize < self->descr->elsize) {
- /*
- * if it is compatible increase the size of the
- * dimension at end (or at the front for FORTRAN)
- */
- if (self->descr->elsize % newtype->elsize != 0) {
- goto fail;
- }
- newdim = self->descr->elsize / newtype->elsize;
- self->dimensions[index] *= newdim;
- self->strides[index] = newtype->elsize;
- }
- else if (newtype->elsize > self->descr->elsize) {
- /*
- * Determine if last (or first if FORTRAN) dimension
- * is compatible
- */
- newdim = self->dimensions[index] * self->descr->elsize;
- if ((newdim % newtype->elsize) != 0) {
- goto fail;
- }
- self->dimensions[index] = newdim / newtype->elsize;
- self->strides[index] = newtype->elsize;
- }
-
- /* fall through -- adjust type*/
- Py_DECREF(self->descr);
- if (newtype->subarray) {
- /*
- * create new array object from data and update
- * dimensions, strides and descr from it
- */
- PyArrayObject *temp;
- /*
- * We would decref newtype here.
- * temp will steal a reference to it
- */
- temp = (PyArrayObject *)
- PyArray_NewFromDescr(&PyArray_Type, newtype, self->nd,
- self->dimensions, self->strides,
- self->data, self->flags, NULL);
- if (temp == NULL) {
- return -1;
- }
- PyDimMem_FREE(self->dimensions);
- self->dimensions = temp->dimensions;
- self->nd = temp->nd;
- self->strides = temp->strides;
- newtype = temp->descr;
- Py_INCREF(temp->descr);
- /* Fool deallocator not to delete these*/
- temp->nd = 0;
- temp->dimensions = NULL;
- Py_DECREF(temp);
- }
-
- self->descr = newtype;
- PyArray_UpdateFlags(self, UPDATE_ALL);
- return 0;
-
- fail:
- PyErr_SetString(PyExc_ValueError, msg);
- Py_DECREF(newtype);
- return -1;
-}
-
-static PyObject *
-array_struct_get(PyArrayObject *self)
-{
- PyArrayInterface *inter;
-
- inter = (PyArrayInterface *)_pya_malloc(sizeof(PyArrayInterface));
- if (inter==NULL) {
- return PyErr_NoMemory();
- }
- inter->two = 2;
- inter->nd = self->nd;
- inter->typekind = self->descr->kind;
- inter->itemsize = self->descr->elsize;
- inter->flags = self->flags;
- /* reset unused flags */
- inter->flags &= ~(UPDATEIFCOPY | OWNDATA);
- if (PyArray_ISNOTSWAPPED(self)) inter->flags |= NOTSWAPPED;
- /*
- * Copy shape and strides over since these can be reset
- *when the array is "reshaped".
- */
- if (self->nd > 0) {
- inter->shape = (intp *)_pya_malloc(2*sizeof(intp)*self->nd);
- if (inter->shape == NULL) {
- _pya_free(inter);
- return PyErr_NoMemory();
- }
- inter->strides = inter->shape + self->nd;
- memcpy(inter->shape, self->dimensions, sizeof(intp)*self->nd);
- memcpy(inter->strides, self->strides, sizeof(intp)*self->nd);
- }
- else {
- inter->shape = NULL;
- inter->strides = NULL;
- }
- inter->data = self->data;
- if (self->descr->names) {
- inter->descr = arraydescr_protocol_descr_get(self->descr);
- if (inter->descr == NULL) {
- PyErr_Clear();
- }
- else {
- inter->flags &= ARR_HAS_DESCR;
- }
- }
- else {
- inter->descr = NULL;
- }
- Py_INCREF(self);
- return PyCObject_FromVoidPtrAndDesc(inter, self, gentype_struct_free);
-}
-
-static PyObject *
-array_base_get(PyArrayObject *self)
-{
- if (self->base == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- else {
- Py_INCREF(self->base);
- return self->base;
- }
-}
-
-
-NPY_NO_EXPORT int
-_zerofill(PyArrayObject *ret)
-{
- if (PyDataType_REFCHK(ret->descr)) {
- PyObject *zero = PyInt_FromLong(0);
- PyArray_FillObjectArray(ret, zero);
- Py_DECREF(zero);
- if (PyErr_Occurred()) {
- Py_DECREF(ret);
- return -1;
- }
- }
- else {
- intp n = PyArray_NBYTES(ret);
- memset(ret->data, 0, n);
- }
- return 0;
-}
-
-
-/*
- * Create a view of a complex array with an equivalent data-type
- * except it is real instead of complex.
- */
-static PyArrayObject *
-_get_part(PyArrayObject *self, int imag)
-{
- PyArray_Descr *type;
- PyArrayObject *ret;
- int offset;
-
- type = PyArray_DescrFromType(self->descr->type_num -
- PyArray_NUM_FLOATTYPE);
- offset = (imag ? type->elsize : 0);
-
- if (!PyArray_ISNBO(self->descr->byteorder)) {
- PyArray_Descr *new;
- new = PyArray_DescrNew(type);
- new->byteorder = self->descr->byteorder;
- Py_DECREF(type);
- type = new;
- }
- ret = (PyArrayObject *)
- PyArray_NewFromDescr(self->ob_type,
- type,
- self->nd,
- self->dimensions,
- self->strides,
- self->data + offset,
- self->flags, (PyObject *)self);
- if (ret == NULL) {
- return NULL;
- }
- ret->flags &= ~CONTIGUOUS;
- ret->flags &= ~FORTRAN;
- Py_INCREF(self);
- ret->base = (PyObject *)self;
- return ret;
-}
-
-static PyObject *
-array_real_get(PyArrayObject *self)
-{
- PyArrayObject *ret;
-
- if (PyArray_ISCOMPLEX(self)) {
- ret = _get_part(self, 0);
- return (PyObject *)ret;
- }
- else {
- Py_INCREF(self);
- return (PyObject *)self;
- }
-}
-
-
-static int
-array_real_set(PyArrayObject *self, PyObject *val)
-{
- PyArrayObject *ret;
- PyArrayObject *new;
- int rint;
-
- if (PyArray_ISCOMPLEX(self)) {
- ret = _get_part(self, 0);
- if (ret == NULL) {
- return -1;
- }
- }
- else {
- Py_INCREF(self);
- ret = self;
- }
- new = (PyArrayObject *)PyArray_FromAny(val, NULL, 0, 0, 0, NULL);
- if (new == NULL) {
- Py_DECREF(ret);
- return -1;
- }
- rint = PyArray_MoveInto(ret, new);
- Py_DECREF(ret);
- Py_DECREF(new);
- return rint;
-}
-
-static PyObject *
-array_imag_get(PyArrayObject *self)
-{
- PyArrayObject *ret;
-
- if (PyArray_ISCOMPLEX(self)) {
- ret = _get_part(self, 1);
- }
- else {
- Py_INCREF(self->descr);
- ret = (PyArrayObject *)PyArray_NewFromDescr(self->ob_type,
- self->descr,
- self->nd,
- self->dimensions,
- NULL, NULL,
- PyArray_ISFORTRAN(self),
- (PyObject *)self);
- if (ret == NULL) {
- return NULL;
- }
- if (_zerofill(ret) < 0) {
- return NULL;
- }
- ret->flags &= ~WRITEABLE;
- }
- return (PyObject *) ret;
-}
-
-static int
-array_imag_set(PyArrayObject *self, PyObject *val)
-{
- if (PyArray_ISCOMPLEX(self)) {
- PyArrayObject *ret;
- PyArrayObject *new;
- int rint;
-
- ret = _get_part(self, 1);
- if (ret == NULL) {
- return -1;
- }
- new = (PyArrayObject *)PyArray_FromAny(val, NULL, 0, 0, 0, NULL);
- if (new == NULL) {
- Py_DECREF(ret);
- return -1;
- }
- rint = PyArray_MoveInto(ret, new);
- Py_DECREF(ret);
- Py_DECREF(new);
- return rint;
- }
- else {
- PyErr_SetString(PyExc_TypeError, "array does not have "\
- "imaginary part to set");
- return -1;
- }
-}
-
-static PyObject *
-array_flat_get(PyArrayObject *self)
-{
- return PyArray_IterNew((PyObject *)self);
-}
-
-static int
-array_flat_set(PyArrayObject *self, PyObject *val)
-{
- PyObject *arr = NULL;
- int retval = -1;
- PyArrayIterObject *selfit = NULL, *arrit = NULL;
- PyArray_Descr *typecode;
- int swap;
- PyArray_CopySwapFunc *copyswap;
-
- typecode = self->descr;
- Py_INCREF(typecode);
- arr = PyArray_FromAny(val, typecode,
- 0, 0, FORCECAST | FORTRAN_IF(self), NULL);
- if (arr == NULL) {
- return -1;
- }
- arrit = (PyArrayIterObject *)PyArray_IterNew(arr);
- if (arrit == NULL) {
- goto exit;
- }
- selfit = (PyArrayIterObject *)PyArray_IterNew((PyObject *)self);
- if (selfit == NULL) {
- goto exit;
- }
- if (arrit->size == 0) {
- retval = 0;
- goto exit;
- }
- swap = PyArray_ISNOTSWAPPED(self) != PyArray_ISNOTSWAPPED(arr);
- copyswap = self->descr->f->copyswap;
- if (PyDataType_REFCHK(self->descr)) {
- while (selfit->index < selfit->size) {
- PyArray_Item_XDECREF(selfit->dataptr, self->descr);
- PyArray_Item_INCREF(arrit->dataptr, PyArray_DESCR(arr));
- memmove(selfit->dataptr, arrit->dataptr, sizeof(PyObject **));
- if (swap) {
- copyswap(selfit->dataptr, NULL, swap, self);
- }
- PyArray_ITER_NEXT(selfit);
- PyArray_ITER_NEXT(arrit);
- if (arrit->index == arrit->size) {
- PyArray_ITER_RESET(arrit);
- }
- }
- retval = 0;
- goto exit;
- }
-
- while(selfit->index < selfit->size) {
- memmove(selfit->dataptr, arrit->dataptr, self->descr->elsize);
- if (swap) {
- copyswap(selfit->dataptr, NULL, swap, self);
- }
- PyArray_ITER_NEXT(selfit);
- PyArray_ITER_NEXT(arrit);
- if (arrit->index == arrit->size) {
- PyArray_ITER_RESET(arrit);
- }
- }
- retval = 0;
-
- exit:
- Py_XDECREF(selfit);
- Py_XDECREF(arrit);
- Py_XDECREF(arr);
- return retval;
-}
-
-static PyObject *
-array_transpose_get(PyArrayObject *self)
-{
- return PyArray_Transpose(self, NULL);
-}
-
-/* If this is None, no function call is made
- --- default sub-class behavior
-*/
-static PyObject *
-array_finalize_get(PyArrayObject *NPY_UNUSED(self))
-{
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyGetSetDef array_getsetlist[] = {
- {"ndim",
- (getter)array_ndim_get,
- NULL, NULL, NULL},
- {"flags",
- (getter)array_flags_get,
- NULL, NULL, NULL},
- {"shape",
- (getter)array_shape_get,
- (setter)array_shape_set,
- NULL, NULL},
- {"strides",
- (getter)array_strides_get,
- (setter)array_strides_set,
- NULL, NULL},
- {"data",
- (getter)array_data_get,
- (setter)array_data_set,
- NULL, NULL},
- {"itemsize",
- (getter)array_itemsize_get,
- NULL, NULL, NULL},
- {"size",
- (getter)array_size_get,
- NULL, NULL, NULL},
- {"nbytes",
- (getter)array_nbytes_get,
- NULL, NULL, NULL},
- {"base",
- (getter)array_base_get,
- NULL, NULL, NULL},
- {"dtype",
- (getter)array_descr_get,
- (setter)array_descr_set,
- NULL, NULL},
- {"real",
- (getter)array_real_get,
- (setter)array_real_set,
- NULL, NULL},
- {"imag",
- (getter)array_imag_get,
- (setter)array_imag_set,
- NULL, NULL},
- {"flat",
- (getter)array_flat_get,
- (setter)array_flat_set,
- NULL, NULL},
- {"ctypes",
- (getter)array_ctypes_get,
- NULL, NULL, NULL},
- {"T",
- (getter)array_transpose_get,
- NULL, NULL, NULL},
- {"__array_interface__",
- (getter)array_interface_get,
- NULL, NULL, NULL},
- {"__array_struct__",
- (getter)array_struct_get,
- NULL, NULL, NULL},
- {"__array_priority__",
- (getter)array_priority_get,
- NULL, NULL, NULL},
- {"__array_finalize__",
- (getter)array_finalize_get,
- NULL, NULL, NULL},
- {NULL, NULL, NULL, NULL, NULL}, /* Sentinel */
-};
-
-/****************** end of attribute get and set routines *******************/
-
-
static PyObject *
array_alloc(PyTypeObject *type, Py_ssize_t NPY_UNUSED(nitems))
{
diff --git a/numpy/core/src/arrayobject.h b/numpy/core/src/arrayobject.h
index bedbf6223..cd66e9108 100644
--- a/numpy/core/src/arrayobject.h
+++ b/numpy/core/src/arrayobject.h
@@ -42,7 +42,6 @@ typedef struct {
PyObject *conjugate;
} NumericOps;
-extern NPY_NO_EXPORT NumericOps n_ops;
extern NPY_NO_EXPORT PyArray_Descr **userdescrs;
@@ -146,4 +145,7 @@ set_typeinfo(PyObject *dict);
extern NPY_NO_EXPORT PyArray_Descr LONG_Descr;
extern NPY_NO_EXPORT PyArray_Descr INT_Descr;
+/* Number protocol */
+#include "arraynumber.h"
+
#endif