diff options
author | cookedm <cookedm@localhost> | 2006-03-07 22:02:23 +0000 |
---|---|---|
committer | cookedm <cookedm@localhost> | 2006-03-07 22:02:23 +0000 |
commit | c9d2cdc913171d079eabb6b71405d7101041356b (patch) | |
tree | a66f5fe7b0d197b434e83fe3e17dbd87076f3839 /numpy/core/src | |
parent | e3a1d502e5d08a755dd1d91eb74341c7617adbdd (diff) | |
parent | 5bb7342c6c2fa9757edc28df0dbbc8d433ac50d8 (diff) | |
download | numpy-c9d2cdc913171d079eabb6b71405d7101041356b.tar.gz |
Merge trunk (r2142:2204) to power_optimization branch
Diffstat (limited to 'numpy/core/src')
-rw-r--r-- | numpy/core/src/arraymethods.c | 142 | ||||
-rw-r--r-- | numpy/core/src/arrayobject.c | 365 | ||||
-rw-r--r-- | numpy/core/src/arraytypes.inc.src | 41 | ||||
-rw-r--r-- | numpy/core/src/multiarraymodule.c | 138 | ||||
-rw-r--r-- | numpy/core/src/scalartypes.inc.src | 30 | ||||
-rw-r--r-- | numpy/core/src/ufuncobject.c | 34 | ||||
-rw-r--r-- | numpy/core/src/umathmodule.c.src | 43 |
7 files changed, 523 insertions, 270 deletions
diff --git a/numpy/core/src/arraymethods.c b/numpy/core/src/arraymethods.c index fe87009e0..c48904f25 100644 --- a/numpy/core/src/arraymethods.c +++ b/numpy/core/src/arraymethods.c @@ -21,7 +21,7 @@ array_take(PyArrayObject *self, PyObject *args, PyObject *kwds) return _ARET(PyArray_Take(self, indices, dimension)); } -static char doc_fill[] = "a.fill(value) places the scalar value at every"\ +static char doc_fill[] = "a.fill(value) places the scalar value at every "\ "position in the array."; static PyObject * @@ -166,9 +166,9 @@ array_view(PyArrayObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "|O", &otype)) return NULL; if (otype) { - if (PyType_Check(otype) && \ + if (PyType_Check(otype) && \ PyType_IsSubtype((PyTypeObject *)otype, - &PyBigArray_Type)) { + &PyArray_Type)) { return PyArray_View(self, NULL, (PyTypeObject *)otype); } @@ -183,12 +183,15 @@ array_view(PyArrayObject *self, PyObject *args) static char doc_argmax[] = "a.argmax(axis=None)"; static PyObject * -array_argmax(PyArrayObject *self, PyObject *args) +array_argmax(PyArrayObject *self, PyObject *args, PyObject *kwds) { int axis=MAX_DIMS; + static char *kwlist[] = {"axis", NULL}; - if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter, - &axis)) return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist, + PyArray_AxisConverter, + &axis)) + return NULL; return _ARET(PyArray_ArgMax(self, axis)); } @@ -196,12 +199,15 @@ array_argmax(PyArrayObject *self, PyObject *args) static char doc_argmin[] = "a.argmin(axis=None)"; static PyObject * -array_argmin(PyArrayObject *self, PyObject *args) +array_argmin(PyArrayObject *self, PyObject *args, PyObject *kwds) { int axis=MAX_DIMS; + static char *kwlist[] = {"axis", NULL}; - if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter, - &axis)) return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist, + PyArray_AxisConverter, + &axis)) + return NULL; return _ARET(PyArray_ArgMin(self, axis)); } @@ -209,12 +215,15 @@ array_argmin(PyArrayObject *self, PyObject *args) static char doc_max[] = "a.max(axis=None)"; static PyObject * -array_max(PyArrayObject *self, PyObject *args) +array_max(PyArrayObject *self, PyObject *args, PyObject *kwds) { int axis=MAX_DIMS; + static char *kwlist[] = {"axis", NULL}; - if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter, - &axis)) return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist, + PyArray_AxisConverter, + &axis)) + return NULL; return PyArray_Max(self, axis); } @@ -222,13 +231,16 @@ array_max(PyArrayObject *self, PyObject *args) static char doc_ptp[] = "a.ptp(axis=None) a.max(axis)-a.min(axis)"; static PyObject * -array_ptp(PyArrayObject *self, PyObject *args) +array_ptp(PyArrayObject *self, PyObject *args, PyObject *kwds) { int axis=MAX_DIMS; + static char *kwlist[] = {"axis", NULL}; - if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter, - &axis)) return NULL; - + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist, + PyArray_AxisConverter, + &axis)) + return NULL; + return PyArray_Ptp(self, axis); } @@ -236,17 +248,19 @@ array_ptp(PyArrayObject *self, PyObject *args) static char doc_min[] = "a.min(axis=None)"; static PyObject * -array_min(PyArrayObject *self, PyObject *args) +array_min(PyArrayObject *self, PyObject *args, PyObject *kwds) { int axis=MAX_DIMS; + static char *kwlist[] = {"axis", NULL}; - if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter, - &axis)) return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist, + PyArray_AxisConverter, + &axis)) + return NULL; return PyArray_Min(self, axis); } - static char doc_swapaxes[] = "a.swapaxes(axis1, axis2) returns new view with axes swapped."; static PyObject * @@ -590,13 +604,13 @@ array_getarray(PyArrayObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "|O&", PyArray_DescrConverter, &newtype)) return NULL; - /* convert to PyArray_Type or PyBigArray_Type */ - if (!PyArray_CheckExact(self) || !PyBigArray_CheckExact(self)) { + /* convert to PyArray_Type */ + if (!PyArray_CheckExact(self)) { PyObject *new; PyTypeObject *subtype = &PyArray_Type; if (!PyType_IsSubtype(self->ob_type, &PyArray_Type)) { - subtype = &PyBigArray_Type; + subtype = &PyArray_Type; } Py_INCREF(PyArray_DESCR(self)); @@ -642,18 +656,29 @@ array_copy(PyArrayObject *self, PyObject *args) return PyArray_NewCopy(self, fortran); } -static char doc_resize[] = "self.resize(new_shape). "\ +static char doc_resize[] = "self.resize(new_shape, refcheck=True). "\ "Change size and shape of self inplace.\n"\ "\n Array must own its own memory and not be referenced by other " \ "arrays\n Returns None."; static PyObject * -array_resize(PyArrayObject *self, PyObject *args) +array_resize(PyArrayObject *self, PyObject *args, PyObject *kwds) { PyArray_Dims newshape; PyObject *ret; int n; - + int refcheck = 1; + + if (kwds != NULL) { + PyObject *ref; + ref = PyDict_GetItemString(kwds, "refcheck"); + if (ref) { + refcheck = PyInt_AsLong(ref); + if (refcheck==-1 && PyErr_Occurred()) { + return NULL; + } + } + } n = PyTuple_Size(args); if (n <= 1) { if (!PyArg_ParseTuple(args, "O&", PyArray_IntpConverter, @@ -668,7 +693,8 @@ array_resize(PyArrayObject *self, PyObject *args) return NULL; } } - ret = PyArray_Resize(self, &newshape); + + ret = PyArray_Resize(self, &newshape, refcheck); PyDimMem_FREE(newshape.ptr); if (ret == NULL) return NULL; Py_DECREF(ret); @@ -741,7 +767,7 @@ array_sort(PyArrayObject *self, PyObject *args, PyObject *kwds) static char doc_argsort[] = "a.argsort(axis=-1,kind='quicksort')\n"\ " Return the indexes into a that would sort it along the"\ - " given axis; kind can be 'quicksort', 'mergesort', or 'heapsort'"; + " given axis; kind can be 'quicksort', 'mergesort', or 'heapsort'"; static PyObject * array_argsort(PyArrayObject *self, PyObject *args, PyObject *kwds) @@ -1013,7 +1039,8 @@ array_setstate(PyArrayObject *self, PyObject *args) self->strides = self->dimensions + nd; memcpy(self->dimensions, dimensions, sizeof(intp)*nd); (void) _array_fill_strides(self->strides, dimensions, nd, - self->descr->elsize, fortran, + self->descr->elsize, + (fortran ? FORTRAN : CONTIGUOUS), &(self->flags)); } @@ -1275,12 +1302,15 @@ array_cumprod(PyArrayObject *self, PyObject *args, PyObject *kwds) static char doc_any[] = "a.any(axis=None)"; static PyObject * -array_any(PyArrayObject *self, PyObject *args) +array_any(PyArrayObject *self, PyObject *args, PyObject *kwds) { int axis=MAX_DIMS; + static char *kwlist[] = {"axis", NULL}; - if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter, - &axis)) return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist, + PyArray_AxisConverter, + &axis)) + return NULL; return PyArray_Any(self, axis); } @@ -1288,13 +1318,16 @@ array_any(PyArrayObject *self, PyObject *args) static char doc_all[] = "a.all(axis=None)"; static PyObject * -array_all(PyArrayObject *self, PyObject *args) +array_all(PyArrayObject *self, PyObject *args, PyObject *kwds) { int axis=MAX_DIMS; + static char *kwlist[] = {"axis", NULL}; - if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter, - &axis)) return NULL; - + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist, + PyArray_AxisConverter, + &axis)) + return NULL; + return PyArray_All(self, axis); } @@ -1348,7 +1381,7 @@ array_compress(PyArrayObject *self, PyObject *args, PyObject *kwds) return _ARET(PyArray_Compress(self, condition, axis)); } -static char doc_nonzero[] = "a.nonzero() return a tuple of indices referencing"\ +static char doc_nonzero[] = "a.nonzero() return a tuple of indices referencing "\ "the elements of a that are nonzero."; static PyObject * @@ -1360,7 +1393,7 @@ array_nonzero(PyArrayObject *self, PyObject *args) } -static char doc_trace[] = "a.trace(offset=0, axis1=0, axis2=1, dtype=None) \n"\ +static char doc_trace[] = "a.trace(offset=0, axis1=0, axis2=1, dtype=None)\n"\ "return the sum along the offset diagonal of the arrays indicated\n" \ "axis1 and axis2."; @@ -1451,6 +1484,20 @@ array_ravel(PyArrayObject *self, PyObject *args) return PyArray_Ravel(self, fortran); } +static char doc_round[] = "a.round(decimals=0)"; + +static PyObject * +array_round(PyArrayObject *self, PyObject *args, PyObject *kwds) +{ + int decimals = 0; + static char *kwlist[] = {"decimals", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, + &decimals)) + return NULL; + + return _ARET(PyArray_Round(self, decimals)); +} static char doc_setflags[] = "a.setflags(write=None, align=None, uic=None)"; @@ -1549,7 +1596,8 @@ static PyMethodDef array_methods[] = { {"setfield", (PyCFunction)array_setfield, METH_VARARGS | METH_KEYWORDS, doc_setfield}, {"copy", (PyCFunction)array_copy, 1, doc_copy}, - {"resize", (PyCFunction)array_resize, 1, doc_resize}, + {"resize", (PyCFunction)array_resize, + METH_VARARGS | METH_KEYWORDS, doc_resize}, /* for subtypes */ {"__array__", (PyCFunction)array_getarray, 1, doc_array_getarray}, @@ -1590,9 +1638,9 @@ static PyMethodDef array_methods[] = { {"searchsorted", (PyCFunction)array_searchsorted, METH_VARARGS, doc_searchsorted}, {"argmax", (PyCFunction)array_argmax, - METH_VARARGS, doc_argmax}, + METH_VARARGS|METH_KEYWORDS, doc_argmax}, {"argmin", (PyCFunction)array_argmin, - METH_VARARGS, doc_argmin}, + METH_VARARGS|METH_KEYWORDS, doc_argmin}, {"reshape", (PyCFunction)array_reshape, METH_VARARGS, doc_reshape}, {"squeeze", (PyCFunction)array_squeeze, @@ -1602,11 +1650,11 @@ static PyMethodDef array_methods[] = { {"swapaxes", (PyCFunction)array_swapaxes, METH_VARARGS, doc_swapaxes}, {"max", (PyCFunction)array_max, - METH_VARARGS, doc_max}, + METH_VARARGS|METH_KEYWORDS, doc_max}, {"min", (PyCFunction)array_min, - METH_VARARGS, doc_min}, + METH_VARARGS|METH_KEYWORDS, doc_min}, {"ptp", (PyCFunction)array_ptp, - METH_VARARGS, doc_ptp}, + METH_VARARGS|METH_KEYWORDS, doc_ptp}, {"mean", (PyCFunction)array_mean, METH_VARARGS|METH_KEYWORDS, doc_mean}, {"trace", (PyCFunction)array_trace, @@ -1634,15 +1682,17 @@ static PyMethodDef array_methods[] = { {"cumprod", (PyCFunction)array_cumprod, METH_VARARGS|METH_KEYWORDS, doc_cumprod}, {"all", (PyCFunction)array_all, - METH_VARARGS, doc_all}, + METH_VARARGS|METH_KEYWORDS, doc_all}, {"any", (PyCFunction)array_any, - METH_VARARGS, doc_any}, + METH_VARARGS|METH_KEYWORDS, doc_any}, {"compress", (PyCFunction)array_compress, METH_VARARGS|METH_KEYWORDS, doc_compress}, {"flatten", (PyCFunction)array_flatten, METH_VARARGS, doc_flatten}, {"ravel", (PyCFunction)array_ravel, METH_VARARGS, doc_ravel}, + {"round", (PyCFunction)array_round, + METH_VARARGS|METH_KEYWORDS, doc_round}, {"setflags", (PyCFunction)array_setflags, METH_VARARGS|METH_KEYWORDS, doc_setflags}, {"newbyteorder", (PyCFunction)array_newbyteorder, diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 2e2f6021b..8ef1758e1 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); @@ -1995,13 +1993,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 +2216,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; } @@ -2337,14 +2378,11 @@ 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, 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 @@ -2397,6 +2435,7 @@ PyArray_SetNumericOps(PyObject *dict) SET(ceil); SET(maximum); SET(minimum); + SET(rint); return 0; } @@ -2445,6 +2484,7 @@ PyArray_GetNumericOps(void) GET(ceil); GET(maximum); GET(minimum); + GET(rint); return dict; fail: @@ -3099,8 +3139,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); @@ -3314,6 +3354,7 @@ static PyObject * array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op) { PyObject *array_other, *result; + int typenum; switch (cmp_op) { @@ -3330,13 +3371,17 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op) } /* Try to convert other to an array */ if (!PyArray_Check(other)) { + typenum = self->descr->type_num; + if (typenum != PyArray_OBJECT) { + typenum = PyArray_NOTYPE; + } 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, 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)) { @@ -3371,8 +3416,12 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op) } /* Try to convert other to an array */ if (!PyArray_Check(other)) { + typenum = self->descr->type_num; + if (typenum != PyArray_OBJECT) { + typenum = PyArray_NOTYPE; + } array_other = PyArray_FromObject(other, - self->descr->type_num, 0, 0); + typenum, 0, 0); /* If not successful, then objects cannot be compared and cannot be equal, therefore, return True; @@ -3649,49 +3698,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<nd; i++) { - intp stride = newstrides[i]; - if (stride > 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; @@ -3911,7 +3951,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; @@ -3938,14 +3978,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); } } @@ -3988,22 +4023,23 @@ 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) && - (subtype != &PyBigArray_Type)) { + if ((subtype != &PyArray_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); 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); @@ -4026,9 +4062,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; @@ -4039,9 +4079,9 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape) 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; } @@ -4056,7 +4096,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, @@ -4117,7 +4158,7 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape) /* 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)); @@ -4173,9 +4214,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, fromptr, arr); + } + else { + while (size--) { + copyswap(toptr, fromptr, swap, itemsize); + toptr += itemsize; + } } } else { @@ -4242,14 +4291,44 @@ 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 (itemsize == 0) { + PyErr_SetString(PyExc_ValueError, + "data-type with unspecified variable length"); + goto fail; + } + + 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 (!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, @@ -4261,32 +4340,16 @@ 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 " \ "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"); @@ -4396,7 +4459,10 @@ array_strides_set(PyArrayObject *self, PyObject *obj) { PyArray_Dims newstrides = {NULL, 0}; PyArrayObject *new; - intp numbytes; + intp numbytes=0; + intp offset=0; + int buf_len; + char *buf; if (!PyArray_IntpConverter(obj, &newstrides) || \ newstrides.ptr == NULL) { @@ -4409,15 +4475,27 @@ array_strides_set(PyArrayObject *self, PyObject *obj) goto fail; } new = self; - while(new->base != NULL) { - if (PyArray_Check(new->base)) - new = (PyArrayObject *)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 (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; } - numbytes = PyArray_MultiplyList(new->dimensions, - new->nd)*new->descr->elsize; 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"); @@ -4449,8 +4527,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); } @@ -5055,10 +5131,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 */ @@ -5069,7 +5145,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*/ @@ -5077,7 +5153,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*/ @@ -5116,20 +5192,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. */ @@ -5474,12 +5536,16 @@ 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; + } } - ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, typecode, + 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, @@ -5823,7 +5889,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) || \ @@ -5840,8 +5906,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 *) \ @@ -5864,8 +5929,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 *) \ @@ -5900,8 +5964,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 *)\ @@ -6242,22 +6305,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); } } } @@ -6305,7 +6374,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; } @@ -6456,7 +6526,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(...)) */ @@ -6469,7 +6539,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); @@ -7577,8 +7647,19 @@ PyArray_MapIterBind(PyArrayMapIterObject *mit, PyArrayObject *arr) therefore we can extract the subspace with a simple getitem call which will use view semantics */ + /* 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); + } - sub = PyObject_GetItem((PyObject *)arr, mit->indexobj); if (sub == NULL) goto fail; mit->subspace = (PyArrayIterObject *)PyArray_IterNew(sub); Py_DECREF(sub); diff --git a/numpy/core/src/arraytypes.inc.src b/numpy/core/src/arraytypes.inc.src index 0fd105ab1..4bd24904a 100644 --- a/numpy/core/src/arraytypes.inc.src +++ b/numpy/core/src/arraytypes.inc.src @@ -1713,6 +1713,45 @@ static void /**end repeat**/ +/* this requires buffer to be filled with objects or NULL */ +static void +OBJECT_fillwithscalar(PyObject **buffer, intp length, PyObject **value, void *ignored) +{ + intp i; + PyObject *val = *value; + for (i=0; i<length; i++) { + Py_XDECREF(buffer[i]); + Py_INCREF(val); + buffer[i] = val; + } +} +/**begin repeat +#NAME=BOOL,BYTE,UBYTE# +#typ=Bool,byte,ubyte# +*/ +static void +@NAME@_fillwithscalar(@typ@ *buffer, intp length, @typ@ *value, void *ignored) +{ + memset(buffer, *value, length); +} +/**end repeat**/ + +/**begin repeat +#NAME=SHORT,USHORT,INT,UINT,LONG,ULONG,LONGLONG,ULONGLONG,FLOAT,DOUBLE,LONGDOUBLE,CFLOAT,CDOUBLE,CLONGDOUBLE# +#typ=short,ushort,int,uint,long,ulong,longlong,ulonglong,float,double,longdouble,cfloat,cdouble,clongdouble# +*/ +static void +@NAME@_fillwithscalar(@typ@ *buffer, intp length, @typ@ *value, void *ignored) +{ + register intp i; + @typ@ val = *value; + for (i=0; i<length; ++i) { + buffer[i] = val; + } +} + +/**end repeat**/ + #define _ALIGN(type) offsetof(struct {char c; type v;},v) /**begin repeat @@ -1758,6 +1797,7 @@ static PyArray_ArrFuncs _Py@NAME@_ArrFuncs = { (PyArray_FromStrFunc*)@from@_fromstr, (PyArray_NonzeroFunc*)@from@_nonzero, (PyArray_FillFunc*)NULL, + (PyArray_FillWithScalarFunc*)NULL, { NULL, NULL, NULL, NULL }, @@ -1828,6 +1868,7 @@ static PyArray_ArrFuncs _Py@NAME@_ArrFuncs = { (PyArray_FromStrFunc*)@from@_fromstr, (PyArray_NonzeroFunc*)@from@_nonzero, (PyArray_FillFunc*)@from@_fill, + (PyArray_FillWithScalarFunc*)@from@_fillwithscalar, { NULL, NULL, NULL, NULL }, diff --git a/numpy/core/src/multiarraymodule.c b/numpy/core/src/multiarraymodule.c index 481e5709a..3e3f71527 100644 --- a/numpy/core/src/multiarraymodule.c +++ b/numpy/core/src/multiarraymodule.c @@ -195,6 +195,87 @@ PyArray_Ravel(PyArrayObject *a, int fortran) return PyArray_Flatten(a, fortran); } +static double +power_of_ten(int n) +{ + static const double p10[] = {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8}; + double ret; + if (n < 9) + ret = p10[n]; + else { + ret = 1e9; + while (n-- > 9) + ret *= 10.; + } + return ret; +} + +/*MULTIARRAY_API + Round +*/ +static PyObject * +PyArray_Round(PyArrayObject *a, int decimals) +{ + /* do the most common case first */ + if (decimals == 0) { + if (PyArray_ISINTEGER(a)) { + Py_INCREF(a); + return (PyObject *)a; + } + return PyArray_GenericUnaryFunction((PyAO *)a, n_ops.rint); + } + if (decimals > 0) { + PyObject *f, *ret; + if (PyArray_ISINTEGER(a)) { + Py_INCREF(a); + return (PyObject *)a; + } + f = PyFloat_FromDouble(power_of_ten(decimals)); + if (f==NULL) return NULL; + ret = PyNumber_Multiply((PyObject *)a, f); + if (ret==NULL) {Py_DECREF(f); return NULL;} + if (PyArray_IsScalar(ret, Generic)) { + /* array scalars cannot be modified inplace */ + PyObject *tmp; + tmp = PyObject_CallFunction(n_ops.rint, "O", ret); + Py_DECREF(ret); + ret = PyObject_CallFunction(n_ops.divide, "OO", + tmp, f); + Py_DECREF(tmp); + } else { + PyObject_CallFunction(n_ops.rint, "OO", ret, ret); + PyObject_CallFunction(n_ops.divide, "OOO", ret, + f, ret); + } + Py_DECREF(f); + return ret; + } + else { + /* remaining case: decimals < 0 */ + PyObject *f, *ret; + f = PyFloat_FromDouble(power_of_ten(-decimals)); + if (f==NULL) return NULL; + ret = PyNumber_Divide((PyObject *)a, f); + if (ret==NULL) {Py_DECREF(f); return NULL;} + if (PyArray_IsScalar(ret, Generic)) { + /* array scalars cannot be modified inplace */ + PyObject *tmp; + tmp = PyObject_CallFunction(n_ops.rint, "O", ret); + Py_DECREF(ret); + ret = PyObject_CallFunction(n_ops.multiply, "OO", + tmp, f); + Py_DECREF(tmp); + } else { + PyObject_CallFunction(n_ops.rint, "OO", ret, ret); + PyObject_CallFunction(n_ops.multiply, "OOO", ret, + f, ret); + } + Py_DECREF(f); + return ret; + } +} + + /*MULTIARRAY_API Flatten */ @@ -1434,40 +1515,40 @@ _signbit_set(PyArrayObject *arr) /*OBJECT_API*/ -static char +static PyArray_SCALARKIND PyArray_ScalarKind(int typenum, PyArrayObject **arr) { if (PyTypeNum_ISSIGNED(typenum)) { - if (arr && _signbit_set(*arr)) return UFUNC_INTNEG_SCALAR; - else return UFUNC_INTPOS_SCALAR; + if (arr && _signbit_set(*arr)) return PyArray_INTNEG_SCALAR; + else return PyArray_INTPOS_SCALAR; } - if (PyTypeNum_ISFLOAT(typenum)) return UFUNC_FLOAT_SCALAR; - if (PyTypeNum_ISUNSIGNED(typenum)) return UFUNC_INTPOS_SCALAR; - if (PyTypeNum_ISCOMPLEX(typenum)) return UFUNC_COMPLEX_SCALAR; - if (PyTypeNum_ISBOOL(typenum)) return UFUNC_BOOL_SCALAR; + if (PyTypeNum_ISFLOAT(typenum)) return PyArray_FLOAT_SCALAR; + if (PyTypeNum_ISUNSIGNED(typenum)) return PyArray_INTPOS_SCALAR; + if (PyTypeNum_ISCOMPLEX(typenum)) return PyArray_COMPLEX_SCALAR; + if (PyTypeNum_ISBOOL(typenum)) return PyArray_BOOL_SCALAR; - return UFUNC_OBJECT_SCALAR; + return PyArray_OBJECT_SCALAR; } - /*OBJECT_API*/ static int -PyArray_CanCoerceScalar(char thistype, char neededtype, char scalar) +PyArray_CanCoerceScalar(char thistype, char neededtype, + PyArray_SCALARKIND scalar) { switch(scalar) { - case UFUNC_NOSCALAR: - case UFUNC_BOOL_SCALAR: - case UFUNC_OBJECT_SCALAR: + case PyArray_NOSCALAR: + case PyArray_BOOL_SCALAR: + case PyArray_OBJECT_SCALAR: return PyArray_CanCastSafely(thistype, neededtype); - case UFUNC_INTPOS_SCALAR: + case PyArray_INTPOS_SCALAR: return (neededtype >= PyArray_UBYTE); - case UFUNC_INTNEG_SCALAR: + case PyArray_INTNEG_SCALAR: return (neededtype >= PyArray_BYTE) && \ !(PyTypeNum_ISUNSIGNED(neededtype)); - case UFUNC_FLOAT_SCALAR: + case PyArray_FLOAT_SCALAR: return (neededtype >= PyArray_FLOAT); - case UFUNC_COMPLEX_SCALAR: + case PyArray_COMPLEX_SCALAR: return (neededtype >= PyArray_CFLOAT); } fprintf(stderr, "\n**Error** coerce fall through: %d %d %d\n\n", @@ -4246,7 +4327,7 @@ _array_fromobject(PyObject *ignored, PyObject *args, PyObject *kws) return NULL; /* fast exit if simple call */ - if ((PyArray_CheckExact(op) || PyBigArray_CheckExact(op))) { + if (PyArray_CheckExact(op)) { if (type==NULL) { if (!copy && fortran==PyArray_ISFORTRAN(op)) { Py_INCREF(op); @@ -5750,25 +5831,6 @@ DL_EXPORT(void) initmultiarray(void) { d = PyModule_GetDict(m); if (!d) goto err; - /* Create the module and add the functions */ - if (PyType_Ready(&PyBigArray_Type) < 0) - return; - - PyArray_Type.tp_base = &PyBigArray_Type; - - PyArray_Type.tp_as_mapping = &array_as_mapping; - /* Even though, this would be inherited, it needs to be set now - so that the __getitem__ will map to the as_mapping descriptor - */ - PyArray_Type.tp_as_number = &array_as_number; - /* For good measure */ - PyArray_Type.tp_as_sequence = &array_as_sequence; - PyArray_Type.tp_as_buffer = &array_as_buffer; - PyArray_Type.tp_flags = (Py_TPFLAGS_DEFAULT - | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_CHECKTYPES); - PyArray_Type.tp_doc = Arraytype__doc__; - if (PyType_Ready(&PyArray_Type) < 0) return; @@ -5800,8 +5862,6 @@ DL_EXPORT(void) initmultiarray(void) { s = PyString_FromString("3.0"); PyDict_SetItemString(d, "__version__", s); Py_DECREF(s); - Py_INCREF(&PyBigArray_Type); - PyDict_SetItemString(d, "bigndarray", (PyObject *)&PyBigArray_Type); Py_INCREF(&PyArray_Type); PyDict_SetItemString(d, "ndarray", (PyObject *)&PyArray_Type); Py_INCREF(&PyArrayIter_Type); diff --git a/numpy/core/src/scalartypes.inc.src b/numpy/core/src/scalartypes.inc.src index 9926cd83c..b984cf81a 100644 --- a/numpy/core/src/scalartypes.inc.src +++ b/numpy/core/src/scalartypes.inc.src @@ -459,14 +459,11 @@ gentype_multiply(PyObject *m1, PyObject *m2) Py_DECREF(arr); Py_DECREF(tup); return ret; - } - - /**begin repeat -#name=negative, absolute, invert, int, long, float, oct, hex# +#name=positive, negative, absolute, invert, int, long, float, oct, hex# */ static PyObject * @@ -639,7 +636,6 @@ static PyObject * /**end repeat**/ -static PyObject *gentype_copy(PyObject *, PyObject *); static PyNumberMethods gentype_as_number = { (binaryfunc)gentype_add, /*nb_add*/ @@ -650,7 +646,7 @@ static PyNumberMethods gentype_as_number = { (binaryfunc)gentype_divmod, /*nb_divmod*/ (ternaryfunc)gentype_power, /*nb_power*/ (unaryfunc)gentype_negative, - (unaryfunc)gentype_copy, /*nb_pos*/ + (unaryfunc)gentype_positive, /*nb_pos*/ (unaryfunc)gentype_absolute, /*(unaryfunc)gentype_abs,*/ (inquiry)gentype_nonzero_number, /*nb_nonzero*/ (unaryfunc)gentype_invert, /*nb_invert*/ @@ -1065,7 +1061,7 @@ gentype_wraparray(PyObject *scalar, PyObject *args) /**begin repeat -#name=tolist, item, tostring, astype, copy, resize, __deepcopy__, choose, searchsorted, argmax, argmin, reshape, view, swapaxes, max, min, ptp, conj, conjugate, nonzero, all, any, flatten, ravel, fill, transpose, newbyteorder# +#name=tolist, item, tostring, astype, copy, __deepcopy__, choose, searchsorted, reshape, view, swapaxes, conj, conjugate, nonzero, flatten, ravel, fill, transpose, newbyteorder# */ static PyObject * @@ -1124,7 +1120,7 @@ gentype_byteswap(PyObject *self, PyObject *args) /**begin repeat -#name=take, getfield, put, putmask, repeat, tofile, mean, trace, diagonal, clip, std, var, sum, cumsum, prod, cumprod, compress, sort, argsort# +#name=take, getfield, put, putmask, repeat, tofile, mean, trace, diagonal, clip, std, var, sum, cumsum, prod, cumprod, compress, sort, argsort, round, argmax, argmin, max, min, ptp, any, all, resize# */ static PyObject * @@ -1338,9 +1334,9 @@ static PyMethodDef gentype_methods[] = { {"searchsorted", (PyCFunction)gentype_searchsorted, METH_VARARGS, NULL}, {"argmax", (PyCFunction)gentype_argmax, - METH_VARARGS, NULL}, + METH_VARARGS|METH_KEYWORDS, NULL}, {"argmin", (PyCFunction)gentype_argmin, - METH_VARARGS, NULL}, + METH_VARARGS|METH_KEYWORDS, NULL}, {"reshape", (PyCFunction)gentype_reshape, METH_VARARGS, NULL}, {"squeeze", (PyCFunction)gentype_squeeze, @@ -1350,11 +1346,11 @@ static PyMethodDef gentype_methods[] = { {"swapaxes", (PyCFunction)gentype_swapaxes, METH_VARARGS, NULL}, {"max", (PyCFunction)gentype_max, - METH_VARARGS, NULL}, + METH_VARARGS|METH_KEYWORDS, NULL}, {"min", (PyCFunction)gentype_min, - METH_VARARGS, NULL}, + METH_VARARGS|METH_KEYWORDS, NULL}, {"ptp", (PyCFunction)gentype_ptp, - METH_VARARGS, NULL}, + METH_VARARGS|METH_KEYWORDS, NULL}, {"mean", (PyCFunction)gentype_mean, METH_VARARGS|METH_KEYWORDS, NULL}, {"trace", (PyCFunction)gentype_trace, @@ -1382,15 +1378,17 @@ static PyMethodDef gentype_methods[] = { {"cumprod", (PyCFunction)gentype_cumprod, METH_VARARGS|METH_KEYWORDS, NULL}, {"all", (PyCFunction)gentype_all, - METH_VARARGS, NULL}, + METH_VARARGS|METH_KEYWORDS, NULL}, {"any", (PyCFunction)gentype_any, - METH_VARARGS, NULL}, + METH_VARARGS|METH_KEYWORDS, NULL}, {"compress", (PyCFunction)gentype_compress, METH_VARARGS|METH_KEYWORDS, NULL}, {"flatten", (PyCFunction)gentype_flatten, METH_VARARGS, NULL}, {"ravel", (PyCFunction)gentype_ravel, METH_VARARGS, NULL}, + {"round", (PyCFunction)gentype_round, + METH_VARARGS|METH_KEYWORDS, NULL}, {"setflags", (PyCFunction)gentype_setflags, METH_VARARGS|METH_KEYWORDS, NULL}, {"newbyteorder", (PyCFunction)gentype_newbyteorder, @@ -2423,8 +2421,8 @@ PyArray_TypeObjectFromType(int type) descr = PyArray_DescrFromType(type); if (descr == NULL) return NULL; - Py_INCREF((PyObject *)descr->typeobj); obj = (PyObject *)descr->typeobj; + Py_INCREF(obj); Py_DECREF(descr); return obj; } diff --git a/numpy/core/src/ufuncobject.c b/numpy/core/src/ufuncobject.c index e09b1ffd5..3083bb461 100644 --- a/numpy/core/src/ufuncobject.c +++ b/numpy/core/src/ufuncobject.c @@ -610,7 +610,7 @@ _lowest_type(char intype) static int select_types(PyUFuncObject *self, int *arg_types, PyUFuncGenericFunction *function, void **data, - char *scalars) + PyArray_SCALARKIND *scalars) { int i=0, j; @@ -663,7 +663,7 @@ select_types(PyUFuncObject *self, int *arg_types, /* If the first argument is a scalar we need to place the start type as the lowest type in the class */ - if (scalars[0] != UFUNC_NOSCALAR) { + if (scalars[0] != PyArray_NOSCALAR) { start_type = _lowest_type(start_type); } @@ -850,7 +850,7 @@ construct_matrices(PyUFuncLoopObject *loop, PyObject *args, PyArrayObject **mps) { int nargs, i, maxsize; int arg_types[MAX_ARGS]; - char scalars[MAX_ARGS]; + PyArray_SCALARKIND scalars[MAX_ARGS]; PyUFuncObject *self=loop->ufunc; Bool allscalars=TRUE; PyTypeObject *subtype=&PyArray_Type; @@ -889,21 +889,17 @@ construct_matrices(PyUFuncLoopObject *loop, PyObject *args, PyArrayObject **mps) at this point */ if (mps[i]->nd > 0) { - scalars[i] = UFUNC_NOSCALAR; + scalars[i] = PyArray_NOSCALAR; allscalars=FALSE; } else scalars[i] = PyArray_ScalarKind(arg_types[i], &(mps[i])); - /* If any input is a big-array */ - if (!PyType_IsSubtype(mps[i]->ob_type, &PyArray_Type)) { - subtype = &PyBigArray_Type; - } } /* If everything is a scalar, then use normal coercion rules */ if (allscalars) { for (i=0; i<self->nin; i++) { - scalars[i] = UFUNC_NOSCALAR; + scalars[i] = PyArray_NOSCALAR; } } @@ -921,7 +917,6 @@ construct_matrices(PyUFuncLoopObject *loop, PyObject *args, PyArrayObject **mps) (loop->ufunc->nin==2) && (loop->ufunc->nout == 1)) { PyObject *_obj = PyTuple_GET_ITEM(args, 1); if (!PyArray_CheckExact(_obj) && \ - !PyBigArray_CheckExact(_obj) && \ PyObject_HasAttrString(_obj, "__array_priority__") && \ _has_reflected_op(_obj, loop->ufunc->name)) { loop->notimplemented = 1; @@ -1716,7 +1711,8 @@ construct_reduce(PyUFuncObject *self, PyArrayObject **arr, int axis, PyArrayObject *aar; intp loop_i[MAX_DIMS]; int arg_types[3] = {otype, otype, otype}; - char scalars[3] = {UFUNC_NOSCALAR, UFUNC_NOSCALAR, UFUNC_NOSCALAR}; + PyArray_SCALARKIND scalars[3] = {PyArray_NOSCALAR, PyArray_NOSCALAR, + PyArray_NOSCALAR}; int i, j; int nd = (*arr)->nd; /* Reduce type is the type requested of the input @@ -2535,7 +2531,7 @@ _find_array_wrap(PyObject *args, PyObject **output_wrap, int nin, int nout) nargs = PyTuple_GET_SIZE(args); for (i=0; i<nin; i++) { obj = PyTuple_GET_ITEM(args, i); - if (PyArray_CheckExact(obj) || PyBigArray_CheckExact(obj) || \ + if (PyArray_CheckExact(obj) || \ PyArray_IsAnyScalar(obj)) continue; wrap = PyObject_GetAttrString(obj, "__array_wrap__"); @@ -2546,6 +2542,7 @@ _find_array_wrap(PyObject *args, PyObject **output_wrap, int nin, int nout) ++np; } else { + Py_DECREF(wrap); wrap = NULL; } } @@ -2594,8 +2591,7 @@ _find_array_wrap(PyObject *args, PyObject **output_wrap, int nin, int nout) obj = PyTuple_GET_ITEM(args, j); if (obj == Py_None) continue; - if (PyArray_CheckExact(obj) || - PyBigArray_CheckExact(obj)) { + if (PyArray_CheckExact(obj)) { output_wrap[i] = Py_None; } else { @@ -2616,7 +2612,8 @@ _find_array_wrap(PyObject *args, PyObject **output_wrap, int nin, int nout) Py_XINCREF(output_wrap[i]); } } - + + Py_XDECREF(wrap); return; } @@ -2691,9 +2688,12 @@ ufunc_generic_call(PyUFuncObject *self, PyObject *args) } res = PyObject_CallFunction(wrap, "O(OOi)", mps[j], self, args, i); - if (res == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { + if (res == NULL && \ + PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_Clear(); - res = PyObject_CallFunctionObjArgs(wrap, mps[j], NULL); + res = PyObject_CallFunctionObjArgs(wrap, + mps[j], + NULL); } Py_DECREF(wrap); if (res == NULL) goto fail; diff --git a/numpy/core/src/umathmodule.c.src b/numpy/core/src/umathmodule.c.src index 11d7c0c7b..0da04e53f 100644 --- a/numpy/core/src/umathmodule.c.src +++ b/numpy/core/src/umathmodule.c.src @@ -222,7 +222,7 @@ static longdouble atanhl(longdouble x) extern double hypot(double, double); #endif #else -double hypot(double x, double y) +static double hypot(double x, double y) { double yx; @@ -243,6 +243,30 @@ double hypot(double x, double y) #endif +#ifndef HAVE_RINT +static double +rint (double x) +{ + double y, r; + + y = floor(x); + r = x - y; + + if (r > 0.5) goto rndup; + + /* Round to nearest even */ + if (r==0.5) { + r = y - 2.0*floor(0.5*y); + if (r==1.0) { + rndup: + y+=1.0; + } + } + return y; +} +#endif + + /* Define isnan, isinf, isfinite, signbit if needed */ /* Use fpclassify if possible */ @@ -287,7 +311,6 @@ double hypot(double x, double y) #include "_signbit.c" #endif - /* Now defined the extended type macros */ #if !defined(isnan) @@ -357,10 +380,10 @@ double hypot(double x, double y) /**begin repeat -#kind=(sin,cos,tan,sinh,cosh,tanh,fabs,floor,ceil,sqrt,log10,log,exp,asin,acos,atan)*2# -#typ=longdouble*16, float*16# -#c=l*16,f*16# -#TYPE=LONGDOUBLE*16, FLOAT*16# +#kind=(sin,cos,tan,sinh,cosh,tanh,fabs,floor,ceil,sqrt,log10,log,exp,asin,acos,atan,rint)*2# +#typ=longdouble*17, float*17# +#c=l*17,f*17# +#TYPE=LONGDOUBLE*17, FLOAT*17# */ #ifndef HAVE_@TYPE@_FUNCS #ifdef @kind@@c@ @@ -659,19 +682,19 @@ nc_pow@c@(c@typ@ *a, c@typ@ *b, c@typ@ *r) } if (bi == 0 && (n=(intp)br) == br) { if (n > -100 && n < 100) { - c@typ@ p, a; + c@typ@ p, aa; intp mask = 1; if (n < 0) n = -n; - a = nc_1@c@; + aa = nc_1@c@; p.real = ar; p.imag = ai; while (1) { if (n & mask) - nc_prod@c@(&a,&p,&a); + nc_prod@c@(&aa,&p,&aa); mask <<= 1; if (n < mask || mask <= 0) break; nc_prod@c@(&p,&p,&p); } - r->real = a.real; r->imag = a.imag; + r->real = aa.real; r->imag = aa.imag; if (bi < 0) nc_quot@c@(&nc_1@c@, r, r); return; } |