Skip to content

Commit 9bcc664

Browse files
committed
Improvements to multiter and flatiter types -- give them a few attributes
1 parent 3180d78 commit 9bcc664

4 files changed

Lines changed: 172 additions & 30 deletions

File tree

‎scipy/base/chararray.py‎

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from numerictypes import character, string, unicode_, obj2dtype
2-
from numeric import ndarray
2+
from numeric import ndarray, multiter, empty
33

44
# special sub-class for character arrays (string and unicode_)
55
# This adds equality testing and methods of str and unicode types
66
# which operate on an element-by-element basis
77

8-
class ndchararray(ndarray):
8+
class charndarray(ndarray):
99
def __new__(subtype, shape, itemlen=1, unicode=False, buffer=None,
1010
offset=0, strides=None, swap=0, fortran=0):
1111

@@ -30,28 +30,74 @@ def __reduce__(self):
3030

3131
# these should be moved to C
3232
def __eq__(self, other):
33-
return NotImplemented
33+
b = multiter(self, other)
34+
result = empty(b.shape, dtype=bool)
35+
res = result.flat
36+
for k, val in enumerate(b):
37+
res[k] = (val[0] == val[1])
38+
return result
3439

3540
def __ne__(self, other):
36-
return NotImplemented
41+
b = multiter(self, other)
42+
result = empty(b.shape, dtype=bool)
43+
res = result.flat
44+
for k, val in enumerate(b):
45+
res[k] = (val[0] != val[1])
46+
return result
3747

3848
def __ge__(self, other):
39-
return NotImplemented
40-
49+
b = multiter(self, other)
50+
result = empty(b.shape, dtype=bool)
51+
res = result.flat
52+
for k, val in enumerate(b):
53+
res[k] = (val[0] >= val[1])
54+
return result
55+
4156
def __le__(self, other):
42-
return NotImplemented
57+
b = multiter(self, other)
58+
result = empty(b.shape, dtype=bool)
59+
res = result.flat
60+
for k, val in enumerate(b):
61+
res[k] = (val[0] <= val[1])
62+
return result
4363

4464
def __gt__(self, other):
45-
return NotImplemented
46-
65+
b = multiter(self, other)
66+
result = empty(b.shape, dtype=bool)
67+
res = result.flat
68+
for k, val in enumerate(b):
69+
res[k] = (val[0] > val[1])
70+
return result
71+
4772
def __lt__(self, other):
48-
return NotImplemented
49-
73+
b = multiter(self, other)
74+
result = empty(b.shape, dtype=bool)
75+
res = result.flat
76+
for k, val in enumerate(b):
77+
res[k] = (val[0] < val[1])
78+
return result
79+
5080
def __add__(self, other):
51-
return NotImplemented
81+
b = multiter(self, other)
82+
outitem = max(b.iters[0].base.itemsize,
83+
b.iters[1].base.itemsize)
84+
dtype = self.dtypestr[0] + str(outitem)
85+
result = empty(b.shape, dtype=dtype)
86+
res = result.flat
87+
for k, val in enumerate(b):
88+
res[k] = (val[0] + val[1])
89+
return result
5290

5391
def __radd__(self, other):
54-
return NotImplemented
92+
b = muliter(other, self)
93+
outitem = max(b.iters[0].base.itemsize,
94+
b.iters[1].base.itemsize)
95+
dtype = self.dtypestr[0] + str(outitem)
96+
result = empty(b.shape, dtype=dtype)
97+
res = result.flat
98+
for k, val in enumerate(b):
99+
res[k] = (val[0] + val[1])
100+
return result
55101

56102
def __mul__(self, other):
57103
return NotImplemented
@@ -65,14 +111,6 @@ def __mod__(self, other):
65111
def __rmod__(self, other):
66112
return NotImplemented
67113

68-
69-
def _strmethod(self, *args, **kwds):
70-
name = args[0]
71-
args = args[1:]
72-
73-
for obj in self.flat:
74-
getattr(obj, name)(*args, **kwds)
75-
76114
def capitalize(self):
77115
pass
78116

@@ -208,8 +246,14 @@ def chararray(obj, itemlen=7, copy=True, unicode=False, fortran=False):
208246
obj = obj.copy()
209247

210248
return ndarray.__new__(chararray, obj.shape)
211-
212-
249+
250+
251+
252+
if unicode:
253+
dtype = "U%d" % itemlen
254+
else:
255+
dtype = "S%d" % itemlen
256+
213257
val = asarray(obj).astype(dtype)
214258

215259
return chararray(val.shape, itemlen, unicode, buffer=val,

‎scipy/base/include/scipy/arrayobject.h‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,7 @@ typedef unsigned long ulonglong;
103103
# define ULONGLONG_SUFFIX(x) (x##UL)
104104
#endif
105105

106-
#ifndef Bool
107106
typedef unsigned char Bool;
108-
#endif
109107
#ifndef FALSE
110108
#define FALSE 0
111109
#endif

‎scipy/base/src/arrayobject.c‎

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6571,6 +6571,10 @@ static PyMethodDef iter_methods[] = {
65716571
{NULL, NULL} /* sentinel */
65726572
};
65736573

6574+
static PyMemberDef iter_members[] = {
6575+
{"base", T_OBJECT, offsetof(PyArrayIterObject, ao), RO, NULL},
6576+
{NULL},
6577+
};
65746578

65756579
static PyTypeObject PyArrayIter_Type = {
65766580
PyObject_HEAD_INIT(NULL)
@@ -6603,6 +6607,9 @@ static PyTypeObject PyArrayIter_Type = {
66036607
0, /* tp_iter */
66046608
(iternextfunc)arrayiter_next, /* tp_iternext */
66056609
iter_methods, /* tp_methods */
6610+
iter_members, /* tp_members */
6611+
0, /* tp_getset */
6612+
66066613
};
66076614

66086615
/** END of Array Iterator **/
@@ -7449,6 +7456,95 @@ arraymultiter_dealloc(PyArrayMultiIterObject *multi)
74497456
free(multi);
74507457
}
74517458

7459+
static PyObject *
7460+
arraymultiter_size_get(PyArrayMultiIterObject *self)
7461+
{
7462+
#if SIZEOF_INTP <= SIZEOF_LONG
7463+
return PyInt_FromLong((long) self->size);
7464+
#else
7465+
if (self->size < MAX_LONG)
7466+
return PyInt_FromLong((long) self->size);
7467+
else
7468+
return PyLong_FromLongLong((longlong) self->size);
7469+
#endif
7470+
}
7471+
7472+
static PyObject *
7473+
arraymultiter_index_get(PyArrayMultiIterObject *self)
7474+
{
7475+
#if SIZEOF_INTP <= SIZEOF_LONG
7476+
return PyInt_FromLong((long) self->index);
7477+
#else
7478+
if (self->size < MAX_LONG)
7479+
return PyInt_FromLong((long) self->index);
7480+
else
7481+
return PyLong_FromLongLong((longlong) self->index);
7482+
#endif
7483+
}
7484+
7485+
static PyObject *
7486+
arraymultiter_shape_get(PyArrayMultiIterObject *self)
7487+
{
7488+
return PyArray_IntTupleFromIntp(self->nd, self->dimensions);
7489+
}
7490+
7491+
static PyObject *
7492+
arraymultiter_iters_get(PyArrayMultiIterObject *self)
7493+
{
7494+
PyObject *res;
7495+
int i, n;
7496+
n = self->numiter;
7497+
res = PyTuple_New(n);
7498+
if (res == NULL) return res;
7499+
for (i=0; i<n; i++) {
7500+
Py_INCREF(self->iters[i]);
7501+
PyTuple_SET_ITEM(res, i, (PyObject *)self->iters[i]);
7502+
}
7503+
return res;
7504+
}
7505+
7506+
static PyGetSetDef arraymultiter_getsetlist[] = {
7507+
{"size",
7508+
(getter)arraymultiter_size_get,
7509+
NULL,
7510+
"total size of broadcasted result"},
7511+
{"index",
7512+
(getter)arraymultiter_index_get,
7513+
NULL,
7514+
"current index in broadcasted result"},
7515+
{"shape",
7516+
(getter)arraymultiter_shape_get,
7517+
NULL,
7518+
"shape of broadcasted result"},
7519+
{"iters",
7520+
(getter)arraymultiter_iters_get,
7521+
NULL,
7522+
"tuple of individual iterators"},
7523+
{NULL, NULL, NULL, NULL},
7524+
};
7525+
7526+
static PyMemberDef arraymultiter_members[] = {
7527+
{"numiter", T_INT, offsetof(PyArrayMultiIterObject, numiter),
7528+
RO, NULL},
7529+
{"nd", T_INT, offsetof(PyArrayMultiIterObject, nd), RO, NULL},
7530+
{NULL},
7531+
};
7532+
7533+
static PyObject *
7534+
arraymultiter_reset(PyArrayMultiIterObject *self, PyObject *args)
7535+
{
7536+
if (!PyArg_ParseTuple(args, "")) return NULL;
7537+
7538+
PyArray_MultiIter_RESET(self);
7539+
Py_INCREF(Py_None);
7540+
return Py_None;
7541+
}
7542+
7543+
static PyMethodDef arraymultiter_methods[] = {
7544+
{"reset", (PyCFunction) arraymultiter_reset, METH_VARARGS, NULL},
7545+
{NULL, NULL},
7546+
};
7547+
74527548
static PyTypeObject PyArrayMultiIter_Type = {
74537549
PyObject_HEAD_INIT(NULL)
74547550
0, /* ob_size */
@@ -7479,9 +7575,9 @@ static PyTypeObject PyArrayMultiIter_Type = {
74797575
0, /* tp_weaklistoffset */
74807576
0, /* tp_iter */
74817577
(iternextfunc)arraymultiter_next, /* tp_iternext */
7482-
0, /* tp_methods */
7483-
0, /* tp_members */
7484-
0, /* tp_getset */
7578+
arraymultiter_methods, /* tp_methods */
7579+
arraymultiter_members, /* tp_members */
7580+
arraymultiter_getsetlist, /* tp_getset */
74857581
0, /* tp_base */
74867582
0, /* tp_dict */
74877583
0, /* tp_descr_get */

‎scipy/base/src/multiarraymodule.c‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4034,14 +4034,18 @@ setup_scalartypes(PyObject *dict)
40344034
Py##child##ArrType_Type.tp_bases = \
40354035
Py_BuildValue("(OO)", &Py##parent1##_Type, \
40364036
&Py##parent2##ArrType_Type); \
4037+
Py##child##ArrType_Type.tp_richcompare = \
4038+
Py##parent1##_Type.tp_richcompare; \
4039+
Py##child##ArrType_Type.tp_compare = \
4040+
Py##parent1##_Type.tp_compare; \
4041+
Py##child##ArrType_Type.tp_hash = Py##parent1##_Type.tp_hash; \
40374042
if (PyType_Ready(&Py##child##ArrType_Type) < 0) { \
40384043
PyErr_Print(); \
40394044
PyErr_Format(PyExc_SystemError, \
40404045
"could not initialize Py%sArrType_Type", \
40414046
#child); \
40424047
return -1; \
4043-
}\
4044-
Py##child##ArrType_Type.tp_hash = Py##parent1##_Type.tp_hash;
4048+
}
40454049

40464050
SINGLE_INHERIT(Bool, Generic);
40474051
SINGLE_INHERIT(Byte, SignedInteger);

0 commit comments

Comments
 (0)