From adc21734b3b1d5bfdf027c4966fba3bbece12468 Mon Sep 17 00:00:00 2001 From: sasha Date: Fri, 24 Feb 2006 00:37:16 +0000 Subject: added rint ufunc and ndarray.round --- numpy/core/src/arrayobject.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 3d11d42ac..afca2b618 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -2334,14 +2334,12 @@ typedef struct { *floor, *ceil, *maximum, - *minimum; + *minimum, + *rint; } NumericOps; -static NumericOps n_ops = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL}; +static NumericOps n_ops; /* NB: static objects inlitialized to zero */ /* Dictionary can contain any of the numeric operations, by name. Those not present will not be changed @@ -2391,6 +2389,7 @@ PyArray_SetNumericOps(PyObject *dict) SET(ceil); SET(maximum); SET(minimum); + SET(rint); return 0; } @@ -2436,6 +2435,7 @@ PyArray_GetNumericOps(void) GET(ceil); GET(maximum); GET(minimum); + GET(rint); return dict; fail: -- cgit v1.2.1 From 8db604ba730d0d64b6491cee731ef363d459207f Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Fri, 24 Feb 2006 10:36:36 +0000 Subject: Fix problem with subspace indexing an matrix subclass --- numpy/core/src/arrayobject.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index afca2b618..532daf31b 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -7466,8 +7466,19 @@ PyArray_MapIterBind(PyArrayMapIterObject *mit, PyArrayObject *arr) therefore we can extract the subspace with a simple getitem call which will use view semantics */ - - sub = PyObject_GetItem((PyObject *)arr, mit->indexobj); + /* But, be sure to do it with a true array. + */ + if (PyArray_CheckExact(arr)) { + sub = array_subscript(arr, mit->indexobj); + } + else { + Py_INCREF(arr); + obj = PyArray_EnsureArray((PyObject *)arr); + if (obj == NULL) goto fail; + sub = array_subscript((PyArrayObject *)obj, mit->indexobj); + Py_DECREF(obj); + } + if (sub == NULL) goto fail; mit->subspace = (PyArrayIterObject *)PyArray_IterNew(sub); Py_DECREF(sub); -- cgit v1.2.1 From 27e255bc8e5149b5326b4940d33db6d337f89a94 Mon Sep 17 00:00:00 2001 From: sasha Date: Fri, 24 Feb 2006 20:55:26 +0000 Subject: allow array(()) --- numpy/core/src/arrayobject.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 532daf31b..288071cde 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -4142,12 +4142,6 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) type_num = descr->type_num; itemsize = descr->elsize; - if (dims.ptr == NULL) { - PyErr_SetString(PyExc_ValueError, "need to give a "\ - "valid shape as the first argument"); - goto fail; - } - if (buffer.ptr == NULL) { ret = (PyArrayObject *)\ PyArray_NewFromDescr(subtype, descr, -- cgit v1.2.1 From 4156b241aa3670f923428d4e72577a9962cdf042 Mon Sep 17 00:00:00 2001 From: sasha Date: Sun, 26 Feb 2006 04:14:32 +0000 Subject: made subscripting return ndarray if ellipsis is present --- numpy/core/src/arrayobject.c | 53 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 288071cde..212064807 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -1995,13 +1995,20 @@ array_subscript(PyArrayObject *self, PyObject *op) return NULL; } if (self->nd == 0) { - if (op == Py_Ellipsis) - return PyArray_ToScalar(self->data, self); + if (op == Py_Ellipsis) { + /* XXX: This leads to a small inconsistency + XXX: with the nd>0 case where (x[...] is x) + XXX: is false for nd>0 case. */ + Py_INCREF(self); + return (PyObject *)self; + } if (op == Py_None) return add_new_axes_0d(self, 1); if (PyTuple_Check(op)) { - if (0 == PyTuple_GET_SIZE(op)) - return PyArray_ToScalar(self->data, self); + if (0 == PyTuple_GET_SIZE(op)) { + Py_INCREF(self); + return (PyObject *)self; + } if ((nd = count_new_axes_0d(op)) == -1) return NULL; return add_new_axes_0d(self, nd); @@ -2211,7 +2218,43 @@ array_ass_sub(PyArrayObject *self, PyObject *index, PyObject *op) static PyObject * array_subscript_nice(PyArrayObject *self, PyObject *op) { - return PyArray_Return((PyArrayObject *)array_subscript(self, op)); + /* The following is just a copy of PyArray_Return with an + additional logic in the nd == 0 case. More efficient + implementation may be possible by refactoring + array_subscript */ + + PyArrayObject *mp = (PyArrayObject *)array_subscript(self, op); + + if (mp == NULL) return NULL; + + if (PyErr_Occurred()) { + Py_XDECREF(mp); + return NULL; + } + + if (!PyArray_Check(mp)) return (PyObject *)mp; + + if (mp->nd == 0) { + Bool noellipses = TRUE; + if (op == Py_Ellipsis) + noellipses = FALSE; + else if (PySequence_Check(op)) { + int n, i; + n = PySequence_Size(op); + for (i = 0; i < n; ++i) + if (PySequence_GetItem(op, i) == Py_Ellipsis) { + noellipses = FALSE; + break; + } + } + if (noellipses) { + PyObject *ret; + ret = PyArray_ToScalar(mp->data, mp); + Py_DECREF(mp); + return ret; + } + } + return (PyObject *)mp; } -- cgit v1.2.1 From def1c92c288699c65356e52722487bbacc036343 Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Mon, 27 Feb 2006 18:24:25 +0000 Subject: Fix segfault due to no error check. --- numpy/core/src/arrayobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 212064807..bc0a7abdb 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -3042,8 +3042,8 @@ array_slice(PyArrayObject *self, int ilow, int ihigh) self->nd, self->dimensions, self->strides, data, self->flags, (PyObject *)self); - self->dimensions[0] = l; + if (r == NULL) return NULL; r->base = (PyObject *)self; Py_INCREF(self); PyArray_UpdateFlags(r, UPDATE_ALL_FLAGS); -- cgit v1.2.1 From b8ba26230f5290093351e4ebad676ed9b6471d8a Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Mon, 27 Feb 2006 19:23:05 +0000 Subject: Have __array_finalize__ be called for every sub-class creation. --- numpy/core/src/arrayobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index bc0a7abdb..5a54195f8 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -3931,7 +3931,7 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, /* call the __array_finalize__ method if a subtype and some object passed in */ - if ((obj != NULL) && (subtype != &PyArray_Type) && + if ((subtype != &PyArray_Type) && (subtype != &PyBigArray_Type)) { PyObject *res, *func, *args; static PyObject *str=NULL; @@ -3947,6 +3947,7 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, func = PyObject_GetAttr((PyObject *)self, str); if (func) { args = PyTuple_New(1); + if (obj == NULL) obj=Py_None; Py_INCREF(obj); PyTuple_SET_ITEM(args, 0, obj); res = PyObject_Call(func, args, NULL); -- cgit v1.2.1 From a538c37f2a78fda5118ffa54f8b6257f11d4b5a3 Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Tue, 28 Feb 2006 07:43:19 +0000 Subject: Allow any integer as a stride (including zero --- though you need to understand that case to use it effectively). Also. fix a bug in strides_set that appeared when an array had say a string as it's base object instead of an array. --- numpy/core/src/arrayobject.c | 84 ++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 39 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 5a54195f8..7530eba4a 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -3592,49 +3592,40 @@ PyArray_UpdateFlags(PyArrayObject *ret, int flagmask) } /* This routine checks to see if newstrides (of length nd) will not - walk outside of the memory implied by a single segment array of the provided - dimensions and element size. If numbytes is 0 it will be calculated from - the provided shape and element size. - - For axes with a positive stride this function checks for a walk - beyond the right end of the buffer, for axes with a negative stride, - it checks for a walk beyond the left end of the buffer. Zero strides - are disallowed. + ever be able to walk outside of the memory implied numbytes and offset. + + The available memory is assumed to start at -offset and proceed + to numbytes-offset. The strides are checked to ensure + that accessing memory using striding will not try to reach beyond + this memory for any of the axes. + + If numbytes is 0 it will be calculated using the dimensions and + element-size. + + This function checks for walking beyond the beginning and right-end + of the buffer and therefore works for any integer stride (positive + or negative). */ + /*OBJECT_API*/ static Bool PyArray_CheckStrides(int elsize, int nd, intp numbytes, intp offset, intp *dims, intp *newstrides) { int i; - + intp byte_begin; + intp begin; + intp end; + if (numbytes == 0) numbytes = PyArray_MultiplyList(dims, nd) * elsize; - + + begin = -offset; + end = numbytes - offset - elsize; for (i=0; i 0) { - /* The last stride does not need to be fully inside - the buffer, only its first elsize bytes */ - if (offset + stride*(dims[i]-1)+elsize > numbytes) { - return FALSE; - } - } - else if (stride < 0) { - if (offset + stride*dims[i] < 0) { - return FALSE; - } - } else { - /* XXX: Zero strides may be useful, but currently - XXX: allowing them would lead to strange results, - XXX: for example : - XXX: >>> x = arange(5) - XXX: >>> x.strides = 0 - XXX: >>> x += 1 - XXX: >>> x - XXX: array([5, 5, 5, 5, 5]) */ + byte_begin = newstrides[i]*(dims[i]-1); + if ((byte_begin < begin) || (byte_begin > end)) return FALSE; - } } return TRUE; @@ -4334,7 +4325,10 @@ array_strides_set(PyArrayObject *self, PyObject *obj) { PyArray_Dims newstrides = {NULL, 0}; PyArrayObject *new; - intp numbytes; + intp numbytes=-1; + intp offset; + int buf_len; + char *buf; if (!PyArray_IntpConverter(obj, &newstrides) || \ newstrides.ptr == NULL) { @@ -4347,13 +4341,25 @@ array_strides_set(PyArrayObject *self, PyObject *obj) goto fail; } new = self; - while(new->base != NULL) { - if (PyArray_Check(new->base)) - new = (PyArrayObject *)new->base; + offset = 0; + while(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 (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; } - numbytes = PyArray_MultiplyList(new->dimensions, - new->nd)*new->descr->elsize; - + if (!PyArray_CheckStrides(self->descr->elsize, self->nd, numbytes, self->data - new->data, self->dimensions, newstrides.ptr)) { -- cgit v1.2.1 From e11ca4d8afc3e412f530ccd55657b401294387ea Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Tue, 28 Feb 2006 07:54:11 +0000 Subject: Fix tests and segfault in set_strides. --- numpy/core/src/arrayobject.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 7530eba4a..eed01f93a 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -4325,8 +4325,8 @@ array_strides_set(PyArrayObject *self, PyObject *obj) { PyArray_Dims newstrides = {NULL, 0}; PyArrayObject *new; - intp numbytes=-1; - intp offset; + intp numbytes=0; + intp offset=0; int buf_len; char *buf; @@ -4341,15 +4341,15 @@ array_strides_set(PyArrayObject *self, PyObject *obj) goto fail; } new = self; - offset = 0; - while(PyArray_Check(new->base)) { + 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 (PyObject_AsReadBuffer(new->base, (const void **)&buf, - &buf_len) >= 0) { + if (new->base && PyObject_AsReadBuffer(new->base, + (const void **)&buf, + &buf_len) >= 0) { offset = self->data - buf; numbytes = buf_len + offset; } @@ -4361,7 +4361,7 @@ array_strides_set(PyArrayObject *self, PyObject *obj) } if (!PyArray_CheckStrides(self->descr->elsize, self->nd, numbytes, - self->data - new->data, + offset, self->dimensions, newstrides.ptr)) { PyErr_SetString(PyExc_ValueError, "strides is not "\ "compatible with available memory"); -- cgit v1.2.1 From fc064db275032fa5c2b0f9d86945988051cfa11c Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Tue, 28 Feb 2006 21:13:49 +0000 Subject: Add refcheck keyword argument to resize method to allow override of reference count check. Allow 0-stride arrays to be created and allow setting of strides even when we create the memory. --- numpy/core/src/arrayobject.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index eed01f93a..b48489f12 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -3845,7 +3845,7 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, self->nd = nd; self->dimensions = NULL; self->data = NULL; - if (data == NULL) { /* strides is NULL too */ + if (data == NULL) { self->flags = DEFAULT_FLAGS; if (flags) { self->flags |= FORTRAN; @@ -3872,14 +3872,9 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, sd = _array_fill_strides(self->strides, dims, nd, sd, flags, &(self->flags)); } - else { - if (data == NULL) { - PyErr_SetString(PyExc_ValueError, - "if 'strides' is given in " \ - "array creation, data must " \ - "be given too"); - goto fail; - } + else { /* we allow strides even when we create + the memory, but be careful with this... + */ memcpy(self->strides, strides, sizeof(intp)*nd); } } @@ -3922,17 +3917,17 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, /* call the __array_finalize__ method if a subtype and some object passed in */ - if ((subtype != &PyArray_Type) && - (subtype != &PyBigArray_Type)) { + if ((subtype != &PyArray_Type) && (subtype != &PyBigArray_Type)) { PyObject *res, *func, *args; static PyObject *str=NULL; if (str == NULL) { str = PyString_InternFromString("__array_finalize__"); } - if (!(self->flags & OWNDATA)) { /* did not allocate own data */ - /* update flags before calling back into - Python */ + if (strides != NULL) { /* did not allocate own data + or funny strides */ + /* update flags before calling back into + Python */ PyArray_UpdateFlags(self, UPDATE_ALL_FLAGS); } func = PyObject_GetAttr((PyObject *)self, str); @@ -3961,9 +3956,13 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, /*OBJECT_API Resize (reallocate data). Only works if nothing else is referencing this array and it is contiguous. + If refcheck is 0, then the reference count is not checked + and assumed to be 1. + You still must own this data and have no weak-references and no base + object. */ static PyObject * -PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape) +PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck) { intp oldsize, newsize; int new_nd=newshape->len, k, n, elsize; @@ -3991,7 +3990,8 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape) return NULL; } - refcnt = REFCOUNT(self); + if (refcheck) refcnt = REFCOUNT(self); + else refcnt = 1; if ((refcnt > 2) || (self->base != NULL) || \ (self->weakreflist != NULL)) { PyErr_SetString(PyExc_ValueError, @@ -4177,6 +4177,13 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) type_num = descr->type_num; itemsize = descr->elsize; + if (itemsize == 0) { + PyErr_SetString(PyExc_ValueError, + "data-type with unspecified variable length"); + Py_DECREF(descr); + return NULL; + } + if (buffer.ptr == NULL) { ret = (PyArrayObject *)\ PyArray_NewFromDescr(subtype, descr, @@ -4190,9 +4197,10 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) } else { /* buffer given -- use it */ if (dims.len == 1 && dims.ptr[0] == -1) { - dims.ptr[offset] = buffer.len / itemsize; + dims.ptr[0] = (buffer.len-offset) / itemsize; } - else if (buffer.len < itemsize* \ + else if ((strides.ptr == NULL) && \ + buffer.len < itemsize* \ PyArray_MultiplyList(dims.ptr, dims.len)) { PyErr_SetString(PyExc_TypeError, "buffer is too small for " \ -- cgit v1.2.1 From f4fc0196c348b52417ddc546c8a43ef946ae7f8a Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Tue, 28 Feb 2006 21:56:13 +0000 Subject: Check strides every time it is allowed. --- numpy/core/src/arrayobject.c | 60 +++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 23 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index b48489f12..1cca1eebe 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -3973,9 +3973,9 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck) intp *dimptr; char *new_data; - if (!PyArray_ISCONTIGUOUS(self)) { + if (!PyArray_ISONESEGMENT(self)) { PyErr_SetString(PyExc_ValueError, - "resize only works on contiguous arrays"); + "resize only works on single-segment arrays"); return NULL; } @@ -4052,7 +4052,7 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck) /* make new_strides variable */ sd = (intp) self->descr->elsize; sd = _array_fill_strides(new_strides, new_dimensions, new_nd, sd, - 0, &(self->flags)); + self->flags, &(self->flags)); memmove(self->dimensions, new_dimensions, new_nd*sizeof(intp)); @@ -4147,6 +4147,7 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) longlong offset=0; int fortran = 0; PyArrayObject *ret; + intp nb, off; buffer.ptr = NULL; /* Usually called with shape and type @@ -4180,12 +4181,42 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) if (itemsize == 0) { PyErr_SetString(PyExc_ValueError, "data-type with unspecified variable length"); - Py_DECREF(descr); - return NULL; + goto fail; + } + + if (strides.ptr != NULL) { + if (strides.len != dims.len) { + PyErr_SetString(PyExc_ValueError, + "strides, if given, must be " \ + "the same length as shape"); + goto fail; + } + } + + if (buffer.ptr == NULL) { + nb = 0; + off = 0; + } + else { + nb = buffer.len; + off = offset; } + + if (strides.ptr && \ + !PyArray_CheckStrides(itemsize, dims.len, + nb, off, + dims.ptr, strides.ptr)) { + PyErr_SetString(PyExc_ValueError, + "strides is incompatible " \ + "with shape of requested " \ + "array and size of buffer"); + goto fail; + } + + if (buffer.ptr == NULL) { - ret = (PyArrayObject *)\ + ret = (PyArrayObject *) \ PyArray_NewFromDescr(subtype, descr, (int)dims.len, dims.ptr, @@ -4207,23 +4238,6 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) "requested array"); goto fail; } - if (strides.ptr != NULL) { - if (strides.len != dims.len) { - PyErr_SetString(PyExc_ValueError, - "strides, if given, must be "\ - "the same length as shape"); - goto fail; - } - if (!PyArray_CheckStrides(itemsize, strides.len, - buffer.len, offset, - dims.ptr, strides.ptr)) { - PyErr_SetString(PyExc_ValueError, - "strides is incompatible "\ - "with shape of requested "\ - "array and size of buffer"); - goto fail; - } - } if (type_num == PyArray_OBJECT) { PyErr_SetString(PyExc_TypeError, "cannot construct "\ "an object array from buffer data"); -- cgit v1.2.1 From 931a4a355aeb3a5f272af91258b848e81114febb Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Tue, 28 Feb 2006 21:58:27 +0000 Subject: Code cleanup --- numpy/core/src/arrayobject.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 1cca1eebe..55abc36f0 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -4147,7 +4147,6 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) longlong offset=0; int fortran = 0; PyArrayObject *ret; - intp nb, off; buffer.ptr = NULL; /* Usually called with shape and type @@ -4185,36 +4184,35 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) } if (strides.ptr != NULL) { + intp nb, off; if (strides.len != dims.len) { PyErr_SetString(PyExc_ValueError, "strides, if given, must be " \ "the same length as shape"); goto fail; } - } - if (buffer.ptr == NULL) { - nb = 0; - off = 0; - } - else { - nb = buffer.len; - off = offset; - } - + if (buffer.ptr == NULL) { + nb = 0; + off = 0; + } + else { + nb = buffer.len; + off = offset; + } + - if (strides.ptr && \ - !PyArray_CheckStrides(itemsize, dims.len, - nb, off, - dims.ptr, strides.ptr)) { - PyErr_SetString(PyExc_ValueError, - "strides is incompatible " \ - "with shape of requested " \ - "array and size of buffer"); - goto fail; + if (!PyArray_CheckStrides(itemsize, dims.len, + nb, off, + dims.ptr, strides.ptr)) { + PyErr_SetString(PyExc_ValueError, + "strides is incompatible " \ + "with shape of requested " \ + "array and size of buffer"); + goto fail; + } } - - + if (buffer.ptr == NULL) { ret = (PyArrayObject *) \ PyArray_NewFromDescr(subtype, descr, -- cgit v1.2.1 From b25ddc20561f810283b7a6ecb49910f45df9770d Mon Sep 17 00:00:00 2001 From: sasha Date: Wed, 1 Mar 2006 03:41:58 +0000 Subject: faster ndarray.fill --- numpy/core/src/arrayobject.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 55abc36f0..cd83f31e1 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -4108,9 +4108,17 @@ PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj) copyswap = arr->descr->f->copyswap; if (PyArray_ISONESEGMENT(arr)) { char *toptr=PyArray_DATA(arr); - while (size--) { - copyswap(toptr, fromptr, swap, itemsize); - toptr += itemsize; + PyArray_FillWithScalarFunc* fillwithscalar = + arr->descr->f->fillwithscalar; + if (fillwithscalar && PyArray_ISALIGNED(arr)) { + copyswap(fromptr, NULL, swap, itemsize); + fillwithscalar(toptr, size, itemsize, fromptr); + } + else { + while (size--) { + copyswap(toptr, fromptr, swap, itemsize); + toptr += itemsize; + } } } else { -- cgit v1.2.1 From 3f8c2dea68dd5d8b437a02f002836f09644e5c3f Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Wed, 1 Mar 2006 06:10:17 +0000 Subject: Swap order of fill-function arguments and make ones use fill now. --- numpy/core/src/arrayobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index cd83f31e1..fe53283a5 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -4112,7 +4112,7 @@ PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj) arr->descr->f->fillwithscalar; if (fillwithscalar && PyArray_ISALIGNED(arr)) { copyswap(fromptr, NULL, swap, itemsize); - fillwithscalar(toptr, size, itemsize, fromptr); + fillwithscalar(toptr, size, fromptr, arr); } else { while (size--) { -- cgit v1.2.1 From 6fd31c330e6572963a03b71bcd479dbedd153ac8 Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Wed, 1 Mar 2006 06:49:10 +0000 Subject: Remove bigndarray because Python SVN has support for 64-bit indexing. --- numpy/core/src/arrayobject.c | 62 +++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 38 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index fe53283a5..6b8012f73 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -32,8 +32,6 @@ PyArray_GetPriority(PyObject *obj, double default_) if (PyArray_CheckExact(obj)) return priority; - if (PyBigArray_CheckExact(obj)) - return PyArray_BIG_PRIORITY; ret = PyObject_GetAttrString(obj, "__array_priority__"); if (ret != NULL) priority = PyFloat_AsDouble(ret); @@ -3917,7 +3915,7 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, /* call the __array_finalize__ method if a subtype and some object passed in */ - if ((subtype != &PyArray_Type) && (subtype != &PyBigArray_Type)) { + if ((subtype != &PyArray_Type)) { PyObject *res, *func, *args; static PyObject *str=NULL; @@ -4421,8 +4419,6 @@ array_priority_get(PyArrayObject *self) { if (PyArray_CheckExact(self)) return PyFloat_FromDouble(PyArray_PRIORITY); - else if (PyBigArray_CheckExact(self)) - return PyFloat_FromDouble(PyArray_BIG_PRIORITY); else return PyFloat_FromDouble(PyArray_SUBTYPE_PRIORITY); } @@ -5027,10 +5023,10 @@ static char Arraytype__doc__[] = " No __init__ method is needed because the array is fully \n" " initialized after the __new__ method."; -static PyTypeObject PyBigArray_Type = { +static PyTypeObject PyArray_Type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - "numpy.bigndarray", /*tp_name*/ + "numpy.ndarray", /*tp_name*/ sizeof(PyArrayObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ @@ -5041,7 +5037,7 @@ static PyTypeObject PyBigArray_Type = { (cmpfunc)0, /*tp_compare*/ (reprfunc)array_repr, /*tp_repr*/ &array_as_number, /*tp_as_number*/ - NULL, /*tp_as_sequence*/ + &array_as_sequence, /*tp_as_sequence*/ &array_as_mapping, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ @@ -5049,7 +5045,7 @@ static PyTypeObject PyBigArray_Type = { (getattrofunc)0, /*tp_getattro*/ (setattrofunc)0, /*tp_setattro*/ - NULL, /*tp_as_buffer*/ + &array_as_buffer, /*tp_as_buffer*/ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES), /*tp_flags*/ @@ -5088,20 +5084,6 @@ static PyTypeObject PyBigArray_Type = { 0 /* tp_weaklist */ }; -/* A standard array will subclass from the Big Array and - add the array_as_sequence table - and the array_as_buffer table - */ - -static PyTypeObject PyArray_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "numpy.ndarray", /*tp_name*/ - sizeof(PyArrayObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ -}; - - /* The rest of this code is to build the right kind of array from a python */ /* object. */ @@ -5804,8 +5786,7 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags) PyErr_SetString(PyExc_ValueError, msg); return NULL; } - if ((flags & ENSUREARRAY) && \ - (subtype != &PyBigArray_Type)) { + if ((flags & ENSUREARRAY)) { subtype = &PyArray_Type; } ret = (PyArrayObject *) \ @@ -5828,8 +5809,7 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags) /* If no copy then just increase the reference count and return the input */ else { - if ((flags & ENSUREARRAY) && \ - (subtype != &PyBigArray_Type)) { + if ((flags & ENSUREARRAY)) { Py_DECREF(newtype); Py_INCREF(arr->descr); ret = (PyArrayObject *) \ @@ -5864,8 +5844,7 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags) PyErr_SetString(PyExc_ValueError, msg); return NULL; } - if ((flags & ENSUREARRAY) && \ - (subtype != &PyBigArray_Type)) { + if ((flags & ENSUREARRAY)) { subtype = &PyArray_Type; } ret = (PyArrayObject *)\ @@ -6206,22 +6185,28 @@ PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject *context) array_meth = PyObject_GetAttrString(op, "__array__"); if (array_meth == NULL) {PyErr_Clear(); return Py_NotImplemented;} if (context == NULL) { - if (typecode == NULL) new = PyObject_CallFunction(array_meth, NULL); + if (typecode == NULL) new = PyObject_CallFunction(array_meth, + NULL); else new = PyObject_CallFunction(array_meth, "O", typecode); } else { if (typecode == NULL) { - new = PyObject_CallFunction(array_meth, "OO", Py_None, context); - if (new == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { + new = PyObject_CallFunction(array_meth, "OO", Py_None, + context); + if (new == NULL && \ + PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_Clear(); new = PyObject_CallFunction(array_meth, ""); } } else { - new = PyObject_CallFunction(array_meth, "OO", typecode, context); - if (new == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { + new = PyObject_CallFunction(array_meth, "OO", + typecode, context); + if (new == NULL && \ + PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_Clear(); - new = PyObject_CallFunction(array_meth, "O", typecode); + new = PyObject_CallFunction(array_meth, "O", + typecode); } } } @@ -6266,7 +6251,8 @@ PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth, PyObject *new; if (r == NULL) return NULL; if (newtype != NULL || flags != 0) { - new = PyArray_FromArray((PyArrayObject *)r, newtype, flags); + new = PyArray_FromArray((PyArrayObject *)r, newtype, + flags); Py_DECREF(r); r = new; } @@ -6417,7 +6403,7 @@ PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int min_depth, ENSUREARRAY) */ /* that special cases Arrays and PyArray_Scalars up front */ /* It *steals a reference* to the object */ -/* It also guarantees that the result is PyArray_Type or PyBigArray_Type */ +/* It also guarantees that the result is PyArray_Type */ /* Because it decrefs op if any conversion needs to take place so it can be used like PyArray_EnsureArray(some_function(...)) */ @@ -6430,7 +6416,7 @@ PyArray_EnsureArray(PyObject *op) if (op == NULL) return NULL; - if (PyArray_CheckExact(op) || PyBigArray_CheckExact(op)) return op; + if (PyArray_CheckExact(op)) return op; if (PyArray_IsScalar(op, Generic)) { new = PyArray_FromScalar(op, NULL); -- cgit v1.2.1 From a93cea60ef4816a150f741cca2f55b63f265291b Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Wed, 1 Mar 2006 17:49:45 +0000 Subject: Fix equality and inequality comparison so that non-array objects are not cast to the type of the array object unless that array is of type PyArray_OBJECT. --- numpy/core/src/arrayobject.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 6b8012f73..b004ca6a4 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -3255,6 +3255,7 @@ static PyObject * array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op) { PyObject *array_other, *result; + int typenum; switch (cmp_op) { @@ -3271,13 +3272,17 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op) } /* Try to convert other to an array */ if (!PyArray_Check(other)) { - array_other = PyArray_FromObject(other, - self->descr->type_num, 0, 0); - /* If not successful, then return the integer - object 0. This fixes code that used to + typenum = self->descr->type_num; + if (typenum != PyArray_OBJECT) { + typenum = PyArray_NOTYPE; + } + array_other = PyArray_FromObject \ + (other, typenum, 0, 0); + /* If not successful, then return False + This fixes code that used to allow equality comparisons between arrays and other objects which would give a result - of 0 + of False */ if ((array_other == NULL) || \ (array_other == Py_None)) { @@ -3312,8 +3317,12 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op) } /* Try to convert other to an array */ if (!PyArray_Check(other)) { - array_other = PyArray_FromObject(other, - self->descr->type_num, 0, 0); + typenum = self->descr->type_num; + if (typenum != PyArray_OBJECT) { + typenum = PyArray_NOTYPE; + } + array_other = PyArray_FromObject \ + (other, typenum, 0, 0); /* If not successful, then objects cannot be compared and cannot be equal, therefore, return True; -- cgit v1.2.1 From 07a9750e934ad45f086b73b9f9f114ea4b2fcdd1 Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Fri, 3 Mar 2006 16:45:16 +0000 Subject: Fix an issue with string/unicode arrays created from scalars. --- numpy/core/src/arrayobject.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index b004ca6a4..739dc69c7 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -5431,10 +5431,8 @@ Array_FromScalar(PyObject *op, PyArray_Descr *typecode) if (type == PyArray_UNICODE) itemsize *= 4; } - ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, typecode, - 0, NULL, - NULL, NULL, 0, NULL); - + ret = (PyArrayObject *)PyArray_New(&PyArray_Type, 0, NULL, type, + NULL, NULL, itemsize, 0, NULL); if (ret == NULL) return NULL; if (ret->nd > 0) { PyErr_SetString(PyExc_ValueError, -- cgit v1.2.1 From d5c0229e1ac366b43bc35c9fdbf6d0f102d00539 Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Fri, 3 Mar 2006 23:40:17 +0000 Subject: Fix bug when ENSURECOPY was present but types are different. --- numpy/core/src/arrayobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 739dc69c7..65443ecd9 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -5776,7 +5776,7 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags) itemsize = newtype->elsize; /* Don't copy if sizes are compatible */ - if (PyArray_EquivTypes(oldtype, newtype)) { + if ((flags & ENSURECOPY) || PyArray_EquivTypes(oldtype, newtype)) { arrflags = arr->flags; copy = (flags & ENSURECOPY) || \ -- cgit v1.2.1 From 07bdddd17c9953d9ce4e5ebe1cceda9e21eb855d Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Mon, 6 Mar 2006 04:20:01 +0000 Subject: Fix bad substitution of PyArray_New --- numpy/core/src/arrayobject.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 65443ecd9..e7aad394a 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -5431,8 +5431,14 @@ Array_FromScalar(PyObject *op, PyArray_Descr *typecode) if (type == PyArray_UNICODE) itemsize *= 4; } - ret = (PyArrayObject *)PyArray_New(&PyArray_Type, 0, NULL, type, - NULL, NULL, itemsize, 0, NULL); + if (itemsize != typecode->elsize) { + PyArray_DESCR_REPLACE(typecode); + typecode->elsize = itemsize; + } + + ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, typecode, + 0, NULL, + NULL, NULL, 0, NULL); if (ret == NULL) return NULL; if (ret->nd > 0) { PyErr_SetString(PyExc_ValueError, -- cgit v1.2.1 From f1fb5f8d6b3fe27dae96acd274fed9bafa8977c7 Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Mon, 6 Mar 2006 04:23:46 +0000 Subject: A little re-ordering. --- numpy/core/src/arrayobject.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index e7aad394a..7b13f5a4e 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -5429,11 +5429,11 @@ Array_FromScalar(PyObject *op, PyArray_Descr *typecode) if (itemsize == 0 && PyTypeNum_ISEXTENDED(type)) { itemsize = PyObject_Length(op); if (type == PyArray_UNICODE) itemsize *= 4; - } - if (itemsize != typecode->elsize) { - PyArray_DESCR_REPLACE(typecode); - typecode->elsize = itemsize; + if (itemsize != typecode->elsize) { + PyArray_DESCR_REPLACE(typecode); + typecode->elsize = itemsize; + } } ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, typecode, -- cgit v1.2.1