diff options
-rw-r--r-- | scipy/base/_internal.py | 32 | ||||
-rw-r--r-- | scipy/base/function_base.py | 7 | ||||
-rw-r--r-- | scipy/base/getlimits.py | 6 | ||||
-rw-r--r-- | scipy/base/matrix.py | 12 | ||||
-rw-r--r-- | scipy/base/numeric.py | 2 | ||||
-rw-r--r-- | scipy/base/numerictypes.py | 10 | ||||
-rw-r--r-- | scipy/base/src/arrayobject.c | 30 | ||||
-rw-r--r-- | scipy/base/src/multiarraymodule.c | 40 | ||||
-rw-r--r-- | scipy/base/twodim_base.py | 48 | ||||
-rw-r--r-- | scipy/base/type_check.py | 38 |
10 files changed, 143 insertions, 82 deletions
diff --git a/scipy/base/_internal.py b/scipy/base/_internal.py new file mode 100644 index 000000000..205856bac --- /dev/null +++ b/scipy/base/_internal.py @@ -0,0 +1,32 @@ + +from multiarray import _flagdict + +_defflags = _flagdict.keys() + +_setable = ['WRITEABLE', 'NOTSWAPPED', 'UPDATEIFCOPY', 'ALIGNED'] +_setable2 = ['write','swap','uic','align'] + +class flagsobj(dict): + def __init__(self, arr, flags): + self._arr = arr + self._flagnum = flags + for k in _defflags: + num = _flagdict[k] + dict.__setitem__(self, k, flags & num == num) + + def __setitem__(self, item, val): + val = not not val # convert to boolean + if item not in _setable: + raise KeyError, "Cannot set that flag." + dict.__setitem__(self, item, val) # Does this matter? + + kwds = {} + for k, name in enumerate(_setable): + if item == name: + kwds[_setable2[k]] = val + if (item == 'NOTSWAPPED'): + kwds['swap'] = not val + + # now actually update array flags + self._arr.setflags(**kwds) + diff --git a/scipy/base/function_base.py b/scipy/base/function_base.py index 4e88fdba1..4f7e76d82 100644 --- a/scipy/base/function_base.py +++ b/scipy/base/function_base.py @@ -2,6 +2,7 @@ import types import math, operator import numeric as _nx from numeric import ones, zeros, arange, concatenate, array, asarray, empty +from numeric import ScalarType from umath import pi, multiply, add, arctan2, maximum, minimum, frompyfunc, \ isnan from oldnumeric import ravel, nonzero, choose, \ @@ -265,7 +266,11 @@ def piecewise(x, condlist, funclist, *args, **kw): raise ValueError, "function list and condition list must be the same." y = empty(x.shape, x.dtype) for k in range(n): - y[condlist[k]] = funclist[k](x[condlist[k]], *args, **kw) + item = funclist[k] + if not callable(item): + y[condlist[k]] = item + else: + y[condlist[k]] = item(x[condlist[k]], *args, **kw) return y def select(condlist, choicelist, default=0): diff --git a/scipy/base/getlimits.py b/scipy/base/getlimits.py index 93f37954f..839f45dee 100644 --- a/scipy/base/getlimits.py +++ b/scipy/base/getlimits.py @@ -14,7 +14,7 @@ def frz(a): a = a.reshape((1,)) return a -_machar_cache = {numeric.float: \ +_machar_cache = {numeric.afloat: \ MachAr(lambda v:array([v],'d'), lambda v:frz(v.astype('i'))[0], lambda v:array(frz(v)[0],'d'), @@ -27,8 +27,8 @@ class finfo(object): dtype = numeric.obj2dtype(dtype) if not issubclass(dtype, numeric.floating): raise ValueError, "data type not a float" - if dtype is numeric.float: - self.machar = _machar_cache[numeric.float] + if dtype is numeric.afloat: + self.machar = _machar_cache[numeric.afloat] elif dtype is numeric.single: try: self.machar = _machar_cache[numeric.single] diff --git a/scipy/base/matrix.py b/scipy/base/matrix.py index 56fcefb74..2d590c2e6 100644 --- a/scipy/base/matrix.py +++ b/scipy/base/matrix.py @@ -4,6 +4,7 @@ from numeric import ArrayType, concatenate from function_base import binary_repr import types import string as str_ +import sys __all__ = ['matrix', 'bmat', 'mat'] @@ -212,24 +213,27 @@ def _from_string(str,gdict,ldict): rowtup = [] for row in rows: trow = row.split(',') + newrow = [] + for x in trow: + newrow.extend(x.split()) + trow = newrow coltup = [] for col in trow: col = col.strip() try: - thismat = gdict[col] + thismat = ldict[col] except KeyError: try: - thismat = ldict[col] + thismat = gdict[col] except KeyError: raise KeyError, "%s not found" % (col,) coltup.append(thismat) rowtup.append(concatenate(coltup,axis=-1)) return concatenate(rowtup,axis=0) - -def bmat(obj,gdict=None,ldict=None): +def bmat(obj,ldict=None, gdict=None): """Build a matrix object from string, nested sequence, or array. Ex: F = bmat('A, B; C, D') diff --git a/scipy/base/numeric.py b/scipy/base/numeric.py index b095ec800..e0ccf41dc 100644 --- a/scipy/base/numeric.py +++ b/scipy/base/numeric.py @@ -57,6 +57,7 @@ def zeros_like(a): If you don't explicitly need the array to be zeroed, you should instead use empty_like(), which is faster as it only allocates memory.""" + a = asarray(a) return zeros(a.shape,a.dtype,a.flags['FORTRAN'] and a.ndim > 1) def empty_like(a): @@ -66,6 +67,7 @@ def empty_like(a): your array to be initialized, you should use zeros_like(). """ + asarray(a) return empty(a.shape,a.dtype,a.flags['FORTRAN'] and a.ndim > 1) # end Fernando's utilities diff --git a/scipy/base/numerictypes.py b/scipy/base/numerictypes.py index 90b72123f..b52ea5926 100644 --- a/scipy/base/numerictypes.py +++ b/scipy/base/numerictypes.py @@ -318,21 +318,25 @@ def dtype2char(dtype): if dtype is None: raise ValueError, "unrecognized type" return _dtype2char_dict[dtype] - + del _ibytes, _fbytes, multiarray # Create dictionary of casting functions that wrap sequences # indexed by type or type character -cast = {} +# This dictionary allows look up based on any alias for a type +class _castdict(dict): + def __getitem__(self, obj): + return dict.__getitem__(self, obj2dtype(obj)) + +cast = _castdict() ScalarType = [_types.IntType, _types.LongType, _types.FloatType, _types.StringType, _types.UnicodeType, _types.ComplexType, _types.BufferType] ScalarType.extend(_dtype2char_dict.keys()) for key in _dtype2char_dict.keys(): cast[key] = lambda x, k=key : array(x,copy=0).astype(k) - cast[_dtype2char_dict[key]] = cast[key] diff --git a/scipy/base/src/arrayobject.c b/scipy/base/src/arrayobject.c index e07f2f08c..17a9914a8 100644 --- a/scipy/base/src/arrayobject.c +++ b/scipy/base/src/arrayobject.c @@ -3530,26 +3530,17 @@ array_ndim_get(PyArrayObject *self) static PyObject * array_flags_get(PyArrayObject *self) { - PyObject *dict; - - dict = PyDict_New(); - -#define ADDFLAG(flag) \ - PyDict_SetItemString(dict, #flag, \ - self->flags & flag ? Py_True : Py_False) + static PyObject *module=NULL; - ADDFLAG(CONTIGUOUS); - ADDFLAG(OWNDATA); - ADDFLAG(FORTRAN); - ADDFLAG(ALIGNED); - ADDFLAG(NOTSWAPPED); - ADDFLAG(WRITEABLE); - ADDFLAG(UPDATEIFCOPY); - return dict; - /* return PyInt_FromLong(self->flags);*/ -#undef ADDFLAG + if (module==NULL) { + module = PyImport_ImportModule("scipy.base._internal"); + if (module == NULL) return NULL; + } + return PyObject_CallMethod(module, "flagsobj", "Oi", + self, self->flags); } +/* static int array_flags_set(PyArrayObject *self, PyObject *obj) { @@ -3616,6 +3607,7 @@ array_flags_set(PyArrayObject *self, PyObject *obj) "Object must be a dictionary"); return -1; } +*/ static PyObject * @@ -4173,8 +4165,8 @@ static PyGetSetDef array_getsetlist[] = { "number of array dimensions"}, {"flags", (getter)array_flags_get, - (setter)array_flags_set, - "integer value of flags"}, + NULL, + "special dictionary of flags"}, {"shape", (getter)array_shape_get, (setter)array_shape_set, diff --git a/scipy/base/src/multiarraymodule.c b/scipy/base/src/multiarraymodule.c index 532f60ba0..ebb719d38 100644 --- a/scipy/base/src/multiarraymodule.c +++ b/scipy/base/src/multiarraymodule.c @@ -3979,6 +3979,37 @@ setup_scalartypes(PyObject *dict) */ } +/* place a flag dictionary in d */ + +static void +set_flaginfo(PyObject *d) +{ + PyObject *s; + PyObject *newd; + + newd = PyDict_New(); + + PyDict_SetItemString(newd, "OWNDATA", s=PyInt_FromLong(OWNDATA)); + Py_DECREF(s); + PyDict_SetItemString(newd, "FORTRAN", s=PyInt_FromLong(FORTRAN)); + Py_DECREF(s); + PyDict_SetItemString(newd, "CONTIGUOUS", s=PyInt_FromLong(CONTIGUOUS)); + Py_DECREF(s); + PyDict_SetItemString(newd, "ALIGNED", s=PyInt_FromLong(ALIGNED)); + Py_DECREF(s); + + PyDict_SetItemString(newd, "NOTSWAPPED", s=PyInt_FromLong(NOTSWAPPED)); + Py_DECREF(s); + PyDict_SetItemString(newd, "UPDATEIFCOPY", s=PyInt_FromLong(UPDATEIFCOPY)); + Py_DECREF(s); + PyDict_SetItemString(newd, "WRITEABLE", s=PyInt_FromLong(WRITEABLE)); + Py_DECREF(s); + + PyDict_SetItemString(d, "_flagdict", newd); + Py_DECREF(newd); + return; +} + /* Initialization function for the module */ @@ -4038,13 +4069,8 @@ DL_EXPORT(void) initmultiarray(void) { Py_INCREF(&PyArrayMapIter_Type); PyDict_SetItemString(d, "mapiter", (PyObject *)&PyArrayMapIter_Type); - PyDict_SetItemString(d, "NOTSWAPPED", s=PyInt_FromLong(NOTSWAPPED)); - Py_DECREF(s); - PyDict_SetItemString(d, "UPDATEIFCOPY", s=PyInt_FromLong(UPDATEIFCOPY)); - Py_DECREF(s); - PyDict_SetItemString(d, "WRITEABLE", s=PyInt_FromLong(WRITEABLE)); - Py_DECREF(s); - + set_flaginfo(d); + if (set_typeinfo(d) == 0) return; /* otherwise there is an error */ diff --git a/scipy/base/twodim_base.py b/scipy/base/twodim_base.py index a7834d9f7..dbe9115e1 100644 --- a/scipy/base/twodim_base.py +++ b/scipy/base/twodim_base.py @@ -9,48 +9,44 @@ from numeric import * import sys def fliplr(m): - """ returns a 2-d array m with the rows preserved and columns flipped - in the left/right direction. Only works with 2-d arrays. + """ returns an array m with the rows preserved and columns flipped + in the left/right direction. Works on the first two dimensions of m. """ m = asarray(m) - if len(m.shape) != 2: - raise ValueError, "Input must be 2-d." + if m.ndim < 2: + raise ValueError, "Input must be >= 2-d." return m[:, ::-1] def flipud(m): - """ returns a 2-d array with the columns preserved and rows flipped in - the up/down direction. Only works with 2-d arrays. + """ returns an array with the columns preserved and rows flipped in + the up/down direction. Works on the first dimension of m. """ m = asarray(m) - if len(m.shape) != 2: - raise ValueError, "Input must be 2-d." + if m.ndim < 1: + raise ValueError, "Input must be >= 1-d." return m[::-1] -# reshape(x, m, n) is not used, instead use reshape(x, (m, n)) - def rot90(m, k=1): - """ returns the 2-d array found by rotating m by k*90 degrees in the - counterclockwise direction. + """ returns the array found by rotating m by k*90 + degrees in the counterclockwise direction. Works on the first two + dimensions of m. """ m = asarray(m) - if len(m.shape) != 2: - raise ValueError, "Input must be 2-d." + if n.ndim < 2: + raise ValueError, "Input must >= 2-d." k = k % 4 if k == 0: return m elif k == 1: return transpose(fliplr(m)) elif k == 2: return fliplr(flipud(m)) else: return fliplr(transpose(m)) # k==3 -def eye(N, M=None, k=0, dtype=float): +def eye(N, M=None, k=0, dtype=aint): """ eye returns a N-by-M 2-d array where the k-th diagonal is all ones, and everything else is zeros. """ if M is None: M = N m = equal(subtract.outer(arange(N), arange(M)),-k) - if dtype is None: - return m+0 - else: - return m.astype(dtype) + return m.astype(dtype) def diag(v, k=0): """ returns the k-th diagonal if v is a array or returns a array @@ -84,21 +80,13 @@ def diag(v, k=0): raise ValueError, "Input must be 1- or 2-d." -def tri(N, M=None, k=0, dtype=None): +def tri(N, M=None, k=0, dtype=aint): """ returns a N-by-M array where all the diagonals starting from lower left corner up to the k-th are all ones. """ - if M is None: M = N - if type(M) == type('d'): - #pearu: any objections to remove this feature? - # As tri(N,'d') is equivalent to tri(N,dtype='d') - dtype = M - M = N + if M is None: M = N m = greater_equal(subtract.outer(arange(N), arange(M)),-k) - if dtype is None: - return m - else: - return m.astype(dtype) + return m.astype(dtype) def tril(m, k=0): """ returns the elements on and below the k-th diagonal of m. k=0 is the diff --git a/scipy/base/type_check.py b/scipy/base/type_check.py index 5d8b5651c..155d685de 100644 --- a/scipy/base/type_check.py +++ b/scipy/base/type_check.py @@ -5,8 +5,8 @@ import numeric as _nx from numeric import ndarray, array, isinf, isnan, isfinite, signbit, \ ufunc, ScalarType -__all__ = ['ScalarType','iscomplexobj','isrealobj','imag','iscomplex', - 'isscalar','isneginf','isposinf','isinf','isfinite', +__all__ = ['iscomplexobj','isrealobj','imag','iscomplex', + 'isscalar','isneginf','isposinf', 'isreal','nan_to_num','real','real_if_close', 'typename','common_type', 'asfarray','mintypecode'] @@ -59,7 +59,7 @@ def imag(val): aval = asarray(val).imag def iscomplex(x): - return imag(x) != _nx.zeros(asarray(x).shape) + return imag(x) != _nx.zeros_like(x) def isreal(x): return imag(x) == _nx.zeros(asarray(x).shape) @@ -96,9 +96,9 @@ def nan_to_num(x): y = nan_to_num(x.real) + 1j * nan_to_num(x.imag) else: y = array(x) - are_inf = isposinf(x) - are_neg_inf = isneginf(x) - are_nan = isnan(x) + are_inf = isposinf(y) + are_neg_inf = isneginf(y) + are_nan = isnan(y) maxf, minf = _getmaxmin(y.dtype) y[are_nan] = 0 y[are_inf] = maxf @@ -107,9 +107,15 @@ def nan_to_num(x): #----------------------------------------------------------------------------- -def real_if_close(a,tol=1e-13): +def real_if_close(a,tol=100): a = asarray(a) - if a.dtypechar in ['F','D','G'] and _nx.allclose(a.imag, 0, atol=tol): + if not a.dtypechar in 'FDG': + return a + if tol > 1: + import getlimits + f = getlmits.finfo(a.dtype) + tol = f.epsilon * tol + if _nx.allclose(a.imag, 0, atol=tol): a = a.real return a @@ -126,12 +132,14 @@ _namefromtype = {'S1' : 'character', 'I' : 'unsigned integer', 'l' : 'long integer', 'L' : 'unsigned long integer', - 'f' : 'single', - 'd' : 'float', - 'g' : 'longfloat', - 'F' : 'complex single', - 'D' : 'complex float', - 'G' : 'complex longfloat', + 'q' : 'long long integer', + 'Q' : 'unsigned long long integer', + 'f' : 'single precision', + 'd' : 'double precision', + 'g' : 'long precision', + 'F' : 'complex single precision', + 'D' : 'complex double precision', + 'G' : 'complex long double precision', 'S' : 'string', 'U' : 'unicode', 'V' : 'void', @@ -139,7 +147,7 @@ _namefromtype = {'S1' : 'character', } def typename(char): - """Return an english name for the given typecode character. + """Return an english description for the given typecode character. """ return _namefromtype[char] |