summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2005-11-30 09:30:51 +0000
committerTravis Oliphant <oliphant@enthought.com>2005-11-30 09:30:51 +0000
commit8dfbf5d48d60c741a066c2e86ee9b4aed5d370a1 (patch)
treed87b93b538b149f8c390fb4695495de9db7e283d
parent0376164cffd1b64f276f2a04c922e1c1727f57d4 (diff)
downloadnumpy-8dfbf5d48d60c741a066c2e86ee9b4aed5d370a1.tar.gz
Fixed up ndchararray a bit. Fixed up use of registered data types.
-rw-r--r--scipy/base/chararray.py289
-rw-r--r--scipy/base/matrix.py3
-rw-r--r--scipy/base/numeric.py4
-rw-r--r--scipy/base/records.py12
-rw-r--r--scipy/base/src/arrayobject.c59
-rw-r--r--scipy/base/src/multiarraymodule.c11
-rw-r--r--scipy/base/src/scalartypes.inc.src35
-rw-r--r--scipy/base/src/ufuncobject.c13
8 files changed, 241 insertions, 185 deletions
diff --git a/scipy/base/chararray.py b/scipy/base/chararray.py
index d81c2fffd..510d4bf8c 100644
--- a/scipy/base/chararray.py
+++ b/scipy/base/chararray.py
@@ -1,240 +1,277 @@
from numerictypes import character, string, unicode_, obj2dtype, integer
-from numeric import ndarray, multiter, empty
+from numeric import ndarray, broadcast, empty
+import sys
# special sub-class for character arrays (string and unicode_)
# This adds equality testing and methods of str and unicode types
# which operate on an element-by-element basis
+
class ndchararray(ndarray):
def __new__(subtype, shape, itemlen=1, unicode=False, buffer=None,
offset=0, strides=None, swap=0, fortran=0):
if unicode:
- dtype = 'U%d' % itemlen
+ dtype = unicode_
else:
- dtype = 'U%d' % itemlen
+ dtype = string
swap = 0
-
if buffer is None:
- self = ndarray.__new__(subtype, shape, dtype, fortran=fortran)
+ self = ndarray.__new__(subtype, shape, dtype, itemlen, fortran=fortran)
else:
- self = ndarray.__new__(subtype, shape, dtype, buffer=buffer,
+ self = ndarray.__new__(subtype, shape, dtype, itemlen, buffer=buffer,
offset=offset, strides=strides,
swap=swap, fortran=fortran)
return self
-
def __reduce__(self):
pass
- # these should be moved to C
- def __eq__(self, other):
- b = multiter(self, other)
+ def _richcmpfunc(self, other, op):
+ b = broadcast(self, other)
result = empty(b.shape, dtype=bool)
res = result.flat
for k, val in enumerate(b):
- res[k] = (val[0] == val[1])
+ r1 = val[0].strip('\x00')
+ r2 = val[1]
+ res[k] = eval("r1 %s r2" % op, {'r1':r1,'r2':r2})
return result
+
+ # these should probably be moved to C
+ def __eq__(self, other):
+ return self._richcmpfunc(other, '==')
def __ne__(self, other):
- b = multiter(self, other)
- result = empty(b.shape, dtype=bool)
- res = result.flat
- for k, val in enumerate(b):
- res[k] = (val[0] != val[1])
- return result
+ return self._richcmpfunc(other, '!=')
def __ge__(self, other):
- b = multiter(self, other)
- result = empty(b.shape, dtype=bool)
- res = result.flat
- for k, val in enumerate(b):
- res[k] = (val[0] >= val[1])
- return result
-
+ return self._richcmpfunc(other, '>=')
+
def __le__(self, other):
- b = multiter(self, other)
- result = empty(b.shape, dtype=bool)
- res = result.flat
- for k, val in enumerate(b):
- res[k] = (val[0] <= val[1])
- return result
+ return self._richcmpfunc(other, '<=')
def __gt__(self, other):
- b = multiter(self, other)
- result = empty(b.shape, dtype=bool)
- res = result.flat
- for k, val in enumerate(b):
- res[k] = (val[0] > val[1])
- return result
+ return self._richcmpfunc(other, '>')
def __lt__(self, other):
- b = multiter(self, other)
- result = empty(b.shape, dtype=bool)
- res = result.flat
- for k, val in enumerate(b):
- res[k] = (val[0] < val[1])
- return result
+ return self._richcmpfunc(other, '<')
def __add__(self, other):
- b = multiter(self, other)
+ b = broadcast(self, other)
arr = b.iters[1].base
outitem = self.itemsize + arr.itemsize
- dtype = self.dtypestr[1:2] + str(outitem)
- result = empty(b.shape, dtype=dtype)
+ result = ndchararray(b.shape, outitem, self.dtype is unicode_)
res = result.flat
for k, val in enumerate(b):
res[k] = (val[0] + val[1])
return result
def __radd__(self, other):
- b = multiter(other, self)
+ b = broadcast(other, self)
outitem = b.iters[0].base.itemsize + \
b.iters[1].base.itemsize
- dtype = self.dtypestr[1:2] + str(outitem)
- result = empty(b.shape, dtype=dtype)
+ result = ndchararray(b.shape, outitem, self.dtype is unicode_)
res = result.flat
for k, val in enumerate(b):
res[k] = (val[0] + val[1])
return result
def __mul__(self, other):
- b = multiter(self, other)
+ b = broadcast(self, other)
arr = b.iters[1].base
if not issubclass(arr.dtype, integer):
raise ValueError, "Can only multiply by integers"
outitem = b.iters[0].base.itemsize * arr.max()
- dtype = self.dtypestr[1:2] + str(outitem)
- result = empty(b.shape, dtype=dtype)
+ result = ndchararray(b.shape, outitem, self.dtype is unicode_)
res = result.flat
for k, val in enumerate(b):
res[k] = val[0]*val[1]
return result
def __rmul__(self, other):
- b = multiter(self, other)
+ b = broadcast(self, other)
arr = b.iters[1].base
if not issubclass(arr.dtype, integer):
raise ValueError, "Can only multiply by integers"
outitem = b.iters[0].base.itemsize * arr.max()
- dtype = self.dtypestr[1:2] + str(outitem)
- result = empty(b.shape, dtype=dtype)
+ result = ndchararray(b.shape, outitem, self.dtype is unicode_)
res = result.flat
for k, val in enumerate(b):
res[k] = val[0]*val[1]
return result
def __mod__(self, other):
- return NotImplemented
-
+ b = broadcast(self, other)
+ res = [None]*b.size
+ maxsize = -1
+ for k,val in enumerate(b):
+ newval = val[0] % val[1]
+ maxsize = max(len(newval), maxsize)
+ res[k] = newval
+ newarr = ndchararray(b.shape, maxsize, self.dtype is unicode_)
+ nearr[:] = res
+ return newarr
+
def __rmod__(self, other):
return NotImplemented
- def capitalize(self):
- pass
-
- def center(self):
- pass
-
- def count(self):
- pass
-
- def decode(self):
- pass
-
- def encode(self):
- pass
+ def _generalmethod(self, name, myiter):
+ res = [None]*myiter.size
+ maxsize = -1
+ for k, val in enumerate(myiter):
+ newval = []
+ for chk in val[1:]:
+ if chk is None:
+ break
+ newval.append(chk)
+ newitem = getattr(val[0],name)(*newval)
+ maxsize = max(len(newitem), maxsize)
+ res[k] = newval
+ newarr = ndchararray(myiter.shape, maxsize, self.dtype is unicode_)
+ newarr[:] = res
+ return newarr
+
+ def _typedmethod(self, name, myiter, dtype):
+ result = empty(myiter.shape, dtype=dtype)
+ res = result.flat
+ for k, val in enumerate(myiter):
+ newval = []
+ for chk in val[1:]:
+ if chk is None:
+ break
+ newval.append(chk)
+ newitem = getattr(val[0],name)(*newval)
+ res[k] = newval
+ return res
+
+ def _samemethod(self, name):
+ result = self.copy()
+ res = result.flat
+ for k, val in enumerate(self.flat):
+ res[k] = getattr(val, name)()
+ return result
- def endswith(self):
- pass
+ def capitalize(self):
+ return self._samemethod('capitalize')
+
+ if sys.version[:3] >= '2.4':
+ def center(self, width, fillchar=' '):
+ return self._generalmethod('center', broadcast(self, width, fillchar))
+ def ljust(self, width, fillchar=' '):
+ return self._generalmethod('ljust', broadcast(self, width, fillchar))
+ def rjust(self, width, fillchar=' '):
+ return self._generalmethod('rjust', broadcast(self, width, fillchar))
+ def rsplit(self, sep=None, maxsplit=None):
+ return self._generalmethod2('rsplit', broadcast(self, sep, maxsplit))
+ else:
+ def ljust(self, width):
+ return self._generalmethod('ljust', broadcast(self, width))
+ def rjust(self, width):
+ return self._generalmethod('rjust', broadcast(self, width))
+ def center(self, width):
+ return self._generalmethod('center', broadcast(self, width))
+
+ def count(self, sub, start=None, end=None):
+ return self._typedmethod('count', broadcast(self, sub, start, end), int)
+
+ def decode(self,encoding=None,errors=None):
+ return self._generalmethod('decode', broadcast(self, encoding, errors))
+
+ def encode(self,encoding=None,errors=None):
+ return self._generalmethod('encode', broadcast(self, encoding, errors))
+
+ def endswith(self, suffix, start=None, end=None):
+ return self._typedmethod('endswith', broadcast(self, suffix, start, end), bool)
+
+ def expandtabs(self, tabsize=None):
+ return self._generalmethod('endswith', broadcast(self, tabsize))
- def expandtabs(self):
- pass
+ def find(self, sub, start=None, end=None):
+ return self._typedmethod('find', broadcast(self, sub, start, end), int)
- def find(self):
- pass
+ def index(self, sub, start=None, end=None):
+ return self._typedmethod('index', broadcast(self, sub, start, end), int)
- def index(self):
- pass
+ def _ismethod(self, name):
+ result = empty(self.shape, dtype=bool)
+ res = result.flat
+ for k, val in enumerate(self.flat):
+ res[k] = getattr(val, name)()
+ return result
def isalnum(self):
- pass
+ return self._ismethod('isalnum')
def isalpha(self):
- pass
+ return self._ismethod('isalpha')
def isdigit(self):
- pass
+ return self._ismethod('isdigit')
def islower(self):
- pass
-
+ return self._ismethod('islower')
+
def isspace(self):
- pass
+ return self._ismethod('isspace')
def istitle(self):
- pass
+ return self._ismethod('istitle')
def isupper(self):
- pass
-
- def join(self):
- pass
-
- def ljust(self):
- pass
+ return self._ismethod('isupper')
+ def join(self, seq):
+ return self._generalmethod('join', broadcast(self, seq))
+
def lower(self):
- pass
+ return self._samemethod('lower')
- def lstrip(self):
- pass
+ def lstrip(self, chars):
+ return self._generalmethod('lstrip', broadcast(self, chars))
- def replace(self):
- pass
-
- def rfind(self):
- pass
+ def replace(self, old, new, count=None):
+ return self._generalmethod('replace', broadcast(self, old, new, count))
- def rindex(self):
- pass
+ def rfind(self, sub, start=None, end=None):
+ return self._typedmethod('rfind', broadcast(self, sub, start, end), int)
- def rjust(self):
- pass
+ def rindex(self, sub, start=None, end=None):
+ return self._typedmethod('rindex', broadcast(self, sub, start, end), int)
- def rsplit(self):
- pass
+ def rstrip(self, chars=None):
+ return self._generalmethod('rstrip', broadcast(self, chars))
- def rstrip(self):
- pass
-
- def split(self):
- pass
-
- def splitlines(self):
- pass
+ def split(self, sep=None, maxsplit=None):
+ return self._typedmethod('split', broadcast(self, sep, maxsplit), object)
- def startswith(self):
- pass
+ def splitlines(self, keepends=None):
+ return self._typedmethod('splitlines', broadcast(self, keepends), object)
+
+ def startswith(self, prefix, start=None, end=None):
+ return self._typedmethod('startswith', broadcast(self, prefix, start, end), bool)
- def strip(self):
- pass
+ def strip(self, chars=None):
+ return self._generalmethod('strip', broadcast(self, chars))
def swapcase(self):
- pass
+ return self._samemethod('swapcase')
def title(self):
- pass
-
- def translate(self):
- pass
+ return self._samemethod('title')
+ #deletechars not accepted for unicode objects
+ def translate(self, table, deletechars=None):
+ if self.dtype is unicode_:
+ return self._generalmethod('translate', broadcast(self, table))
+ else:
+ return self._generalmethod('translate', broadcast(self, table, deletechars))
+
def upper(self):
- pass
+ return self._samemethod('upper')
- def zfill(self):
- pass
+ def zfill(self, width):
+ return self._generalmethod('zfill', broadcast(self, width))
def chararray(obj, itemlen=7, copy=True, unicode=False, fortran=False):
diff --git a/scipy/base/matrix.py b/scipy/base/matrix.py
index eaebafeec..63743be9b 100644
--- a/scipy/base/matrix.py
+++ b/scipy/base/matrix.py
@@ -88,7 +88,8 @@ class matrix(N.ndarray):
if not (fortran or arr.flags.contiguous):
arr = arr.copy()
- ret = N.ndarray.__new__(subtype, shape, arr.dtype, buffer=arr,
+ ret = N.ndarray.__new__(subtype, shape, arr.dtype, arr.itemsize,
+ buffer=arr,
fortran=fortran,
swap=arr.flags.swapped)
return ret
diff --git a/scipy/base/numeric.py b/scipy/base/numeric.py
index ce3c7a758..f3837f201 100644
--- a/scipy/base/numeric.py
+++ b/scipy/base/numeric.py
@@ -1,5 +1,5 @@
__all__ = ['newaxis', 'ndarray', 'bigndarray', 'flatiter', 'ufunc',
- 'arange', 'array', 'zeros', 'empty', 'multiter',
+ 'arange', 'array', 'zeros', 'empty', 'broadcast',
'fromstring', 'fromfile', 'frombuffer','newbuffer','getbuffer',
'where', 'concatenate', 'fastCopyAndTranspose',
'register_dtype', 'set_numeric_ops', 'can_cast',
@@ -47,7 +47,7 @@ newaxis = None
ndarray = multiarray.ndarray
bigndarray = multiarray.bigndarray
flatiter = multiarray.flatiter
-multiter = multiarray.multiter
+broadcast = multiarray.broadcast
ufunc = type(sin)
arange = multiarray.arange
diff --git a/scipy/base/records.py b/scipy/base/records.py
index 34c255a56..c80e76676 100644
--- a/scipy/base/records.py
+++ b/scipy/base/records.py
@@ -1,4 +1,5 @@
import numeric as sb
+import numerictypes as nt
import sys
import types
import re
@@ -139,10 +140,12 @@ class format_parser:
# This pads record so next record is aligned if self._rec_align is true.
# Otherwise next the record starts right after the end of the last one.
self._total_itemsize = (self._stops[-1]/maxalign + 1) * maxalign
-
-class RecArray(sb.ndarray):
+class record(nt.void):
+ pass
+
+class ndrecarray(sb.ndarray):
def __new__(self, *args, **kwds):
buf = args[0]
formats = args[1]
@@ -159,15 +162,14 @@ class RecArray(sb.ndarray):
else:
raise NameError, "Illegal shape %s" % `shape`
- typecode = 'V%d' % itemsize
if buf is None:
- this = sb.ndarray.__new__(RecArray, shape, typecode)
+ this = sb.ndarray.__new__(self, shape, record, itemsize)
else:
byteorder = kwds.get('byteorder', sys.byteorder)
swapped = 0
if (byteorder != sys.byteorder):
swapped = 1
- this = sb.ndarray.__new__(RecArray, shape, typecode, buffer=buf,
+ this = sb.ndarray.__new__(self, shape, record, itemsize, buffer=buf,
swapped=swapped)
this.parsed = parsed
return this
diff --git a/scipy/base/src/arrayobject.c b/scipy/base/src/arrayobject.c
index f8833c9e6..ac6814ac3 100644
--- a/scipy/base/src/arrayobject.c
+++ b/scipy/base/src/arrayobject.c
@@ -804,7 +804,7 @@ PyArray_Scalar(void *data, int type_num, int itemsize, int swap)
else
obj = type->tp_alloc(type, 0);
if (obj == NULL) return NULL;
- if PyTypeNum_ISFLEXIBLE(type_num) {
+ if PyTypeNum_ISEXTENDED(type_num) {
if (type_num == PyArray_STRING) {
destptr = PyString_AS_STRING(obj);
((PyStringObject *)obj)->ob_shash = -1;
@@ -895,6 +895,7 @@ static int
PyArray_RegisterDataType(PyTypeObject *type)
{
PyArray_Descr *descr;
+ PyObject *obj;
int typenum;
int i;
@@ -915,7 +916,14 @@ PyArray_RegisterDataType(PyTypeObject *type)
sizeof(PyArray_Descr));
typenum = PyArray_USERDEF + PyArray_NUMUSERTYPES;
descr->type_num = typenum;
- descr->typeobj = type;
+ descr->typeobj = type;
+ obj = PyObject_GetAttrString((PyObject *)type,"itemsize");
+ if (obj) {
+ i = PyInt_AsLong(obj);
+ if ((i < 0) && (PyErr_Occurred())) PyErr_Clear();
+ else descr->elsize = i;
+ }
+ Py_INCREF(type);
userdescrs = realloc(userdescrs,
(PyArray_NUMUSERTYPES+1)*sizeof(void *));
if (userdescrs == NULL) {
@@ -2763,7 +2771,7 @@ array_repr_builtin(PyArrayObject *self)
free(string); return NULL;
}
- if (PyArray_ISFLEXIBLE(self)) {
+ if (PyArray_ISEXTENDED(self)) {
char buf[100];
snprintf(buf, sizeof(buf), "%d", self->itemsize);
sprintf(string+n, ", '%c%s')", self->descr->type, buf);
@@ -3242,23 +3250,18 @@ PyArray_New(PyTypeObject *subtype, int nd, intp *dims, int type_num,
}
}
else self->flags = (flags & ~UPDATEIFCOPY);
-
- if (PyTypeNum_ISFLEXIBLE(type_num)) {
+
+ self->itemsize = descr->elsize;
+ if (self->itemsize == 0) {
if (itemsize < 1) {
PyErr_SetString(PyExc_ValueError,
- "type must provide an itemsize");
+ "data type must provide an itemsize");
self->ob_type->tp_free((PyObject *)self);
return NULL;
}
self->itemsize = itemsize;
- /* Guarantee that these kind of arrays are never byteswapped
- unknowingly.
- */
- if (type_num != PyArray_UNICODE)
- self->flags |= NOTSWAPPED;
}
- else self->itemsize = descr->elsize;
-
+
sd = self->itemsize;
if (nd > 0) {
@@ -3532,9 +3535,9 @@ PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj)
static PyObject *
array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
{
- static char *kwlist[] = {"shape", "dtype", "buffer", "offset",
+ static char *kwlist[] = {"shape", "dtype", "itemlen", "buffer", "offset",
"strides", "swap", "fortran", NULL};
- int itemsize = 0;
+ int itemsize = -1;
PyArray_Typecode typecode = {PyArray_NOTYPE, 0, 0};
int type_num = PyArray_NOTYPE;
PyArray_Dims dims = {NULL, 0};
@@ -3554,11 +3557,12 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
array of a specific type and shape.
*/
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&LO&ii",
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&iO&LO&ii",
kwlist, PyArray_IntpConverter,
&dims,
PyArray_TypecodeConverter,
&typecode,
+ &itemsize,
PyArray_BufferConverter,
&buffer,
&offset,
@@ -3571,6 +3575,13 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
typecode.type_num = PyArray_DOUBLE;
typecode.itemsize = sizeof(double);
}
+ /* An itemlen is used only if the typecode.itemsize is 0 */
+ if ((itemsize != -1) && typecode.itemsize==0) {
+ if (typecode.type_num == PyArray_UNICODE) {
+ itemsize *= sizeof(Py_UNICODE);
+ }
+ typecode.itemsize = itemsize;
+ }
type_num = typecode.type_num;
itemsize = typecode.itemsize;
@@ -3977,7 +3988,7 @@ array_nbytes_get(PyArrayObject *self)
static PyObject *
array_typechar_get(PyArrayObject *self)
{
- if PyArray_ISFLEXIBLE(self)
+ if PyArray_ISEXTENDED(self)
return PyString_FromFormat("%c%d", (self->descr->type),
self->itemsize);
else
@@ -4637,8 +4648,8 @@ _array_small_type(int chktype, int mintype, int chksize, int minsize,
PyArray_Typecode *outtype)
{
outtype->type_num = MAX(chktype, mintype);
- if (PyTypeNum_ISFLEXIBLE(outtype->type_num) && \
- (PyTypeNum_ISFLEXIBLE(mintype) || mintype==0)) {
+ if (PyTypeNum_ISEXTENDED(outtype->type_num) && \
+ (PyTypeNum_ISEXTENDED(mintype) || mintype==0)) {
/* Handle string->unicode case separately
because string itemsize is twice as large */
if (outtype->type_num == PyArray_UNICODE &&
@@ -4858,7 +4869,7 @@ Array_FromScalar(PyObject *op, PyArray_Typecode *typecode)
itemsize = typecode->itemsize;
type = typecode->type_num;
- if (itemsize == 0 && PyTypeNum_ISFLEXIBLE(type)) {
+ if (itemsize == 0 && PyTypeNum_ISEXTENDED(type)) {
itemsize = PyObject_Length(op);
}
@@ -4912,7 +4923,7 @@ Array_FromSequence(PyObject *s, PyArray_Typecode *typecode, int min_depth,
if(discover_dimensions(s,nd,d, !stop_at_string) == -1) {
return NULL;
}
- if (itemsize == 0 && PyTypeNum_ISFLEXIBLE(type)) {
+ if (itemsize == 0 && PyTypeNum_ISEXTENDED(type)) {
if (discover_itemsize(s, nd, &itemsize) == -1) {
return NULL;
}
@@ -5598,7 +5609,7 @@ array_fromattr(PyObject *op, PyArray_Typecode *typecode, int flags)
PyObject *obj;
descr = PyArray_DescrFromType(typecode->type_num);
- if (PyTypeNum_ISFLEXIBLE(typecode->type_num)) {
+ if (PyTypeNum_ISEXTENDED(typecode->type_num)) {
obj = PyString_FromFormat("%c%d", descr->type,
typecode->itemsize);
}
@@ -7340,7 +7351,7 @@ PyArray_MultiIterNew(int n, ...)
"array objects (inclusive).", MAX_DIMS);
}
- fprintf(stderr, "multi new...");
+ /* fprintf(stderr, "multi new...");*/
multi = PyObject_New(PyArrayMultiIterObject, &PyArrayMultiIter_Type);
if (multi == NULL)
return NULL;
@@ -7548,7 +7559,7 @@ static PyMethodDef arraymultiter_methods[] = {
static PyTypeObject PyArrayMultiIter_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
- "scipy.multiter", /* tp_name */
+ "scipy.broadcast", /* tp_name */
sizeof(PyArrayMultiIterObject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
diff --git a/scipy/base/src/multiarraymodule.c b/scipy/base/src/multiarraymodule.c
index fd8cf4339..fdefb54e4 100644
--- a/scipy/base/src/multiarraymodule.c
+++ b/scipy/base/src/multiarraymodule.c
@@ -124,7 +124,7 @@ PyArray_View(PyArrayObject *self, PyArray_Typecode *type)
PyArray_BASE(new) = (PyObject *)self;
if ((type_num != PyArray_NOTYPE) && \
(type_num != self->descr->type_num)) {
- if (!PyTypeNum_ISFLEXIBLE(type_num)) {
+ if (!PyTypeNum_ISEXTENDED(type_num)) {
v = PyArray_TypeObjectFromType(type_num);
}
else {
@@ -460,11 +460,13 @@ PyArray_Std(PyArrayObject *self, int axis, int rtype, int variance)
if (n<=0) n=1;
obj2 = PyFloat_FromDouble(1.0/((double )n));
if (obj2 == NULL) {Py_DECREF(obj1); return NULL;}
- ret = PyArray_EnsureArray(PyNumber_Multiply(obj1, obj2));
+ ret = PyNumber_Multiply(obj1, obj2);
Py_DECREF(obj1);
Py_DECREF(obj2);
- if (variance) return PyArray_Return(ret);
+ if (variance) return ret;
+
+ ret = PyArray_EnsureArray(ret);
/* sqrt() */
obj1 = PyArray_GenericUnaryFunction((PyAO *)ret, n_ops.sqrt);
@@ -2087,6 +2089,7 @@ PyArray_Correlate(PyObject *op1, PyObject *op2, int mode)
return NULL;
}
+
static PyObject *
PyArray_ArgMin(PyArrayObject *ap, int axis)
{
@@ -4210,7 +4213,7 @@ DL_EXPORT(void) initmultiarray(void) {
Py_INCREF(&PyArrayIter_Type);
PyDict_SetItemString(d, "flatiter", (PyObject *)&PyArrayIter_Type);
Py_INCREF(&PyArrayMultiIter_Type);
- PyDict_SetItemString(d, "multiter", (PyObject *)&PyArrayMultiIter_Type);
+ PyDict_SetItemString(d, "broadcast", (PyObject *)&PyArrayMultiIter_Type);
/* Doesn't need to be exposed to Python
Py_INCREF(&PyArrayMapIter_Type);
diff --git a/scipy/base/src/scalartypes.inc.src b/scipy/base/src/scalartypes.inc.src
index 884d87aab..4945f130a 100644
--- a/scipy/base/src/scalartypes.inc.src
+++ b/scipy/base/src/scalartypes.inc.src
@@ -50,14 +50,14 @@ PyArray_ScalarAsCtype(PyObject *scalar, void *ctypeptr)
PyArray_Typecode typecode;
PyArray_TypecodeFromScalar(scalar, &typecode);
- if (PyTypeNum_ISFLEXIBLE(typecode.type_num)) {
+ if (PyTypeNum_ISEXTENDED(typecode.type_num)) {
void **newptr = (void **)ctypeptr;
switch(typecode.type_num) {
case PyArray_STRING:
*newptr = (void *)PyString_AS_STRING(scalar);
case PyArray_UNICODE:
*newptr = (void *)PyUnicode_AS_DATA(scalar);
- case PyArray_VOID:
+ default:
*newptr = ((PyVoidScalarObject *)scalar)->obval;
}
return;
@@ -81,8 +81,8 @@ PyArray_CastScalarToCtype(PyObject *scalar, void *ctypeptr,
PyArray_TypecodeFromScalar(scalar, &incode);
descr = PyArray_DescrFromType(incode.type_num);
- if (PyTypeNum_ISFLEXIBLE(incode.type_num) ||
- PyTypeNum_ISFLEXIBLE(outcode->type_num)) {
+ if (PyTypeNum_ISEXTENDED(incode.type_num) ||
+ PyTypeNum_ISEXTENDED(outcode->type_num)) {
PyArrayObject *ain, *aout;
ain = (PyArrayObject *)PyArray_FromScalar(scalar, NULL);
@@ -129,11 +129,13 @@ PyArray_FromScalar(PyObject *scalar, PyArray_Typecode *outcode)
case PyArray_UNICODE:
memptr = (char *)PyUnicode_AS_DATA(scalar);
break;
- case PyArray_VOID:
- memptr = (((PyVoidScalarObject *)scalar)->obval);
- break;
default:
- memptr = _SOFFSET_(scalar, typecode.type_num);
+ if (PyTypeNum_ISEXTENDED(typecode.type_num)) {
+ memptr = (((PyVoidScalarObject *)scalar)->obval);
+ }
+ else {
+ memptr = _SOFFSET_(scalar, typecode.type_num);
+ }
break;
}
@@ -147,7 +149,7 @@ PyArray_FromScalar(PyObject *scalar, PyArray_Typecode *outcode)
return r;
if (outcode->type_num == typecode.type_num) {
- if (!PyTypeNum_ISFLEXIBLE(typecode.type_num))
+ if (!PyTypeNum_ISEXTENDED(typecode.type_num))
return r;
if (outcode->itemsize == typecode.itemsize)
return r;
@@ -1672,11 +1674,11 @@ PyArray_TypenumFromTypeObject(PyObject *type)
i++;
}
- /* Seacrh any registered types */
+ /* Search any registered types */
i = 0;
while (i < PyArray_NUMUSERTYPES) {
if (type == (PyObject *)(userdescrs[i]->typeobj)) {
- typenum = i;
+ typenum = i + PyArray_USERDEF;
break;
}
i++;
@@ -1699,7 +1701,7 @@ PyArray_TypenumFromTypeObject(PyObject *type)
return PyArray_ULONG;
else if (type == (PyObject *) &PyCharacterArrType_Type)
return PyArray_STRING;
- else if (type == (PyObject *) &PyFlexibleArrType_Type)
+ else if (PyType_IsSubtype((PyTypeObject *)type, &PyFlexibleArrType_Type))
return PyArray_VOID;
else if (type == (PyObject *)&PyBool_Type)
typenum = PyArray_BOOL;
@@ -1728,10 +1730,7 @@ PyArray_TypecodeFromTypeObject(PyObject *type, PyArray_Typecode *typecode) {
type_num = PyArray_TypenumFromTypeObject(type);
typecode->type_num = type_num;
- if (PyTypeNum_ISFLEXIBLE(type_num)) {
- itemsize = 0;
- }
- else {
+ if (!PyTypeNum_ISFLEXIBLE(type_num)) {
PyArray_Descr *descr;
descr = PyArray_DescrFromType(type_num);
if (descr != NULL)
@@ -1754,8 +1753,8 @@ PyArray_TypecodeFromScalar(PyObject *sc, PyArray_Typecode *typecode)
typecode->itemsize = PyString_GET_SIZE(sc);
else if (type_num == PyArray_UNICODE)
typecode->itemsize = PyUnicode_GET_DATA_SIZE(sc);
- else if (type_num == PyArray_VOID) {
- typecode->itemsize = \
+ else {
+ typecode->itemsize = \
((PyVoidScalarObject *)sc)->ob_size;
}
}
diff --git a/scipy/base/src/ufuncobject.c b/scipy/base/src/ufuncobject.c
index ea3cf266c..ea1ec3bd4 100644
--- a/scipy/base/src/ufuncobject.c
+++ b/scipy/base/src/ufuncobject.c
@@ -602,11 +602,14 @@ select_types(PyUFuncObject *self, int *arg_types,
for (i=self->nin; i<self->nargs; i++) {
arg_types[i] = arg_types[0];
}
-
- key = PyInt_FromLong((long) arg_types[0]);
- if (key == NULL) return -1;
- obj = PyDict_GetItem(self->userloops, key);
- Py_DECREF(key);
+
+ obj = NULL;
+ if (self->userloops) {
+ key = PyInt_FromLong((long) arg_types[0]);
+ if (key == NULL) return -1;
+ obj = PyDict_GetItem(self->userloops, key);
+ Py_DECREF(key);
+ }
if (obj == NULL) {
PyErr_SetString(PyExc_TypeError,
"no registered loop for this " \