summaryrefslogtreecommitdiff
path: root/numpy/core/src
diff options
context:
space:
mode:
authorcookedm <cookedm@localhost>2006-03-07 22:02:23 +0000
committercookedm <cookedm@localhost>2006-03-07 22:02:23 +0000
commitc9d2cdc913171d079eabb6b71405d7101041356b (patch)
treea66f5fe7b0d197b434e83fe3e17dbd87076f3839 /numpy/core/src
parente3a1d502e5d08a755dd1d91eb74341c7617adbdd (diff)
parent5bb7342c6c2fa9757edc28df0dbbc8d433ac50d8 (diff)
downloadnumpy-c9d2cdc913171d079eabb6b71405d7101041356b.tar.gz
Merge trunk (r2142:2204) to power_optimization branch
Diffstat (limited to 'numpy/core/src')
-rw-r--r--numpy/core/src/arraymethods.c142
-rw-r--r--numpy/core/src/arrayobject.c365
-rw-r--r--numpy/core/src/arraytypes.inc.src41
-rw-r--r--numpy/core/src/multiarraymodule.c138
-rw-r--r--numpy/core/src/scalartypes.inc.src30
-rw-r--r--numpy/core/src/ufuncobject.c34
-rw-r--r--numpy/core/src/umathmodule.c.src43
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;
}