diff options
-rw-r--r-- | scipy/base/getlimits.py | 17 | ||||
-rw-r--r-- | scipy/base/info_scipy_base.py | 6 | ||||
-rw-r--r-- | scipy/base/machar.py | 3 | ||||
-rw-r--r-- | scipy/base/src/arraytypes.inc.src | 10 | ||||
-rw-r--r-- | scipy/base/src/ufuncobject.c | 23 | ||||
-rw-r--r-- | scipy/base/type_check.py | 66 |
6 files changed, 59 insertions, 66 deletions
diff --git a/scipy/base/getlimits.py b/scipy/base/getlimits.py index c8287ed57..6445e1b28 100644 --- a/scipy/base/getlimits.py +++ b/scipy/base/getlimits.py @@ -14,13 +14,21 @@ def frz(a): a = a.reshape((1,)) return a +_convert_to_float = { + numeric.csingle: numeric.single, + numeric.acomplex: numeric.afloat, + numeric.clongfloat: numeric.longfloat + } + _machar_cache = {} class finfo(object): def __init__(self, dtype): dtype = numeric.obj2dtype(dtype) + if not issubclass(dtype, numeric.inexact): + raise ValueError, "data type not inexact" if not issubclass(dtype, numeric.floating): - raise ValueError, "data type not a float" + dtype = _convert_to_float[dtype] if dtype is numeric.afloat: try: self.machar = _machar_cache[numeric.afloat] @@ -56,10 +64,15 @@ class finfo(object): "point number") _machar_cache[numeric.longfloat] = self.machar - for word in ['epsilon', 'tiny', 'precision', 'resolution']: + for word in ['tiny', 'precision', 'resolution', + 'ngrd','maxexp','minexp','epsneg','negep', + 'machep']: setattr(self,word,getattr(self.machar, word)) self.max = self.machar.huge self.min = -self.max + self.eps = self.machar.epsilon + self.nexp = self.machar.iexp + self.nmant = self.machar.it if __name__ == '__main__': f = finfo(numeric.single) diff --git a/scipy/base/info_scipy_base.py b/scipy/base/info_scipy_base.py index 836e6f191..571f21d21 100644 --- a/scipy/base/info_scipy_base.py +++ b/scipy/base/info_scipy_base.py @@ -103,7 +103,6 @@ isinf -- Tests for infinity | isfinite -- Tests for finite numbers ---| isscalar -- True if argument is a scalar nan_to_num -- Replaces NaN's with 0 and infinities with large numbers -typename -- Return english name for given typecode character cast -- Dictionary of functions to force cast to each type common_type -- Determine the 'minimum common type code' for a group of arrays @@ -115,11 +114,6 @@ mgrid -- Method which allows easy construction of N-d 'mesh-grids' r_ -- Append and construct arrays: turns slice objects into ranges and concatenates them, for 2d arrays appends rows. -c_ -- Append and construct arrays: for 2d arrays appends - columns. -row -- Like r_ except ensure (row) Matrix return -col -- Like c_ except ensure (column) Matrix return - index_exp -- Konrad Hinsen's index_expression class instance which can be useful for building complicated slicing syntax. diff --git a/scipy/base/machar.py b/scipy/base/machar.py index 06f407e0f..0541e4a22 100644 --- a/scipy/base/machar.py +++ b/scipy/base/machar.py @@ -66,6 +66,7 @@ class MachAr: two = one + one zero = one - one + # Do we really need to do this? Aren't they 2 and 2.0? # Determine ibeta and beta a = one while 1: @@ -85,7 +86,7 @@ class MachAr: beta = float_conv(ibeta) # Determine it and irnd - it = 0 + it = -1 b = one while 1: it = it + 1 diff --git a/scipy/base/src/arraytypes.inc.src b/scipy/base/src/arraytypes.inc.src index 45dbb4ba2..85fe00eb2 100644 --- a/scipy/base/src/arraytypes.inc.src +++ b/scipy/base/src/arraytypes.inc.src @@ -302,7 +302,7 @@ VOID_getitem(char *ip, PyArrayObject *ap) return u; } - args = Py_BuildValue("O",u); + args = Py_BuildValue("OO",u, ap); Py_DECREF(u); if (args==0) goto fail; pyres = PyObject_CallObject(meth, args); @@ -341,10 +341,10 @@ VOID_setitem(PyObject *op, char *ip, PyArrayObject *ap) } u = PyBuffer_FromReadWriteMemory(ip, itemsize); if (u==NULL) goto fail; - args = Py_BuildValue("OO",op, u); + args = Py_BuildValue("OOO",u, op, ap); pyres = PyObject_CallObject(meth, args); if (pyres==NULL) goto fail; - res = PyInt_AsLong(pyres); + res = 0; if (PyErr_Occurred()) goto fail; Py_DECREF(meth); @@ -1124,7 +1124,7 @@ VOID_nonzero (char *ip, PyArrayObject *ap) u = PyBuffer_FromMemory(ip, len); if ((u==NULL)) {Py_DECREF(meth); return FALSE;} - args = Py_BuildValue("O",u); + args = Py_BuildValue("OO",u, ap); pyres = PyObject_CallObject(meth, args); Py_DECREF(args); Py_DECREF(u); @@ -1256,7 +1256,7 @@ VOID_compare(void *ip1, void *ip2, PyArrayObject *ap) v = PyBuffer_FromMemory(ip2, itemsize); if ((u==NULL) || (v==NULL)) goto fail; - args = Py_BuildValue("OO",u,v); + args = Py_BuildValue("OOO",u,v,ap); pyres = PyObject_CallObject(meth, args); if (pyres==NULL) goto fail; diff --git a/scipy/base/src/ufuncobject.c b/scipy/base/src/ufuncobject.c index 35e421628..7bcbe4016 100644 --- a/scipy/base/src/ufuncobject.c +++ b/scipy/base/src/ufuncobject.c @@ -736,33 +736,12 @@ _getfuncfromvar(char *str, PyObject *deflt) static char _scalar_kind(int typenum, PyArrayObject **arr) { - PyObject *zero, *ozero, *new; - if (PyTypeNum_ISSIGNED(typenum)) { - if (!PyArray_ISBEHAVED(*arr)) { - new = PyArray_Copy(*arr); - Py_DECREF(*arr); - *arr = (PyArrayObject *)new; - } - ozero = PyInt_FromLong((long) 0); - if (ozero == NULL) goto fail; - zero = PyArray_FromAny(ozero, NULL, 0, 0, CARRAY_FLAGS); - Py_DECREF(ozero); - if (zero == NULL) goto fail; - if ((*arr)->descr->compare(PyArray_DATA(*arr), - PyArray_DATA(zero), NULL) < 0) - return UFUNC_INTNEG_SCALAR; - else - return UFUNC_INTPOS_SCALAR; - } + if (PyTypeNum_ISSIGNED(typenum)) return UFUNC_INTNEG_SCALAR; if (PyTypeNum_ISFLOAT(typenum)) return UFUNC_FLOAT_SCALAR; if (PyTypeNum_ISCOMPLEX(typenum)) return UFUNC_COMPLEX_SCALAR; if (PyTypeNum_ISUNSIGNED(typenum)) return UFUNC_INTPOS_SCALAR; if (PyTypeNum_ISBOOL(typenum)) return UFUNC_BOOL_SCALAR; return UFUNC_OBJECT_SCALAR; - - fail: - PyErr_Clear(); - return UFUNC_NOSCALAR; } diff --git a/scipy/base/type_check.py b/scipy/base/type_check.py index e26e169d0..abc9b057f 100644 --- a/scipy/base/type_check.py +++ b/scipy/base/type_check.py @@ -3,33 +3,36 @@ import types import numeric as _nx from numeric import ndarray, array, isinf, isnan, isfinite, signbit, \ - ufunc, ScalarType + ufunc, ScalarType, asarray __all__ = ['iscomplexobj','isrealobj','imag','iscomplex', 'isscalar','isneginf','isposinf', 'isreal','nan_to_num','real','real_if_close', - 'typename','common_type', - 'asfarray','mintypecode'] - -_typecodes_by_elsize = 'GDFgdfQqLlIiHhBb' - -def mintypecode(typecodes,typeset='DFdf',default='d',savespace=0): - """ Return a typecode in typeset such that for each - t in typecodes - array(typecode=typecode)[:] = array(typecode=t) - is valid, loses no information, and array(typecode=typecode) - element size is minimal unless when typecodes does not - intersect with typeset then default is returned. - As a special case, if savespace is False then 'D' is returned - whenever typecodes contain 'F' and 'd'. - If t in typecodes is not a string then t=t.dtypechar is applied. + 'typename','asfarray','mintypecode'] + +_typecodes_by_elsize = 'GDFgdfQqLlIiHhBb?' + +def mintypecode(typechars,typeset='GDFgdf',default='d'): + """ Return a minimum data type character from typeset that + handles all typechars given + + The returned type character must be the smallest size such that + an array of the returned type can handle the data from an array of + type t for each t in typechars (or if typechars is an array, + then its dtypechar). + + If the typechars does not intersect with the typeset, then default + is returned. + + If t in typechars is not a string then t=asarray(t).dtypechar is + applied. """ typecodes = [(type(t) is type('') and t) or asarray(t).dtypechar\ for t in typecodes] intersection = [t for t in typecodes if t in typeset] if not intersection: return default - if not savespace and 'F' in intersection and 'd' in intersection: + if 'F' in intersection and 'd' in intersection: return 'D' l = [] for t in intersection: @@ -38,11 +41,12 @@ def mintypecode(typecodes,typeset='DFdf',default='d',savespace=0): l.sort() return l[0][1] -def asfarray(a, dtype=None): +def asfarray(a, dtype=_nx.afloat): """asfarray(a,dtype=None) returns a as a float array.""" - a = asarray(a,dtype) - if dtype is None and a.dtypechar not in 'GDFgfd': - return a.astype('d') + dtype = _nx.obj2dtype(dtype) + if not issubclass(dtype, _nx.inexact): + dtype = _nx.afloat + a = asarray(a,dtype=dtype) return a def isscalar(num): @@ -52,16 +56,16 @@ def isscalar(num): return type(num) in ScalarType def real(val): - aval = asarray(val).real + return asarray(val).real def imag(val): - aval = asarray(val).imag + return asarray(val).imag def iscomplex(x): return imag(x) != _nx.zeros_like(x) def isreal(x): - return imag(x) == _nx.zeros(asarray(x).shape) + return imag(x) == _nx.zeros_like(x) def iscomplexobj(x): return issubclass( asarray(x).dtype, _nx.complexfloating) @@ -108,11 +112,11 @@ def nan_to_num(x): def real_if_close(a,tol=100): a = asarray(a) - if not a.dtypechar in 'FDG': + if a.dtypechar not in 'FDG': return a if tol > 1: import getlimits - f = getlmits.finfo(a.dtype) + f = getlmits.finfo(a.dtypechar.lower()) tol = f.epsilon * tol if _nx.allclose(a.imag, 0, atol=tol): a = a.real @@ -146,16 +150,18 @@ _namefromtype = {'S1' : 'character', } def typename(char): - """Return an english description for the given typecode character. + """Return an english description for the given data type character. """ return _namefromtype[char] #----------------------------------------------------------------------------- #determine the "minimum common type code" for a group of arrays. -array_kind = {'i':0, 'l': 0, 'f': 0, 'd': 0, 'F': 1, 'D': 1} -array_precision = {'i': 1, 'l': 1, 'f': 0, 'd': 1, 'F': 0, 'D': 1} -array_type = [['f', 'd'], ['F', 'D']] +array_kind = {'i':0, 'l': 0, 'f': 0, 'd': 0, 'g':0, 'F': 1, 'D': 1, 'G':1} +array_precision = {'i': 1, 'l': 1, + 'f': 0, 'd': 1, 'g':2, + 'F': 0, 'D': 1, 'G':2} +array_type = [['f', 'd', 'g'], ['F', 'D', 'G']] def common_type(*arrays): kind = 0 precision = 0 |