diff options
author | Pearu Peterson <pearu.peterson@gmail.com> | 2005-10-19 14:00:32 +0000 |
---|---|---|
committer | Pearu Peterson <pearu.peterson@gmail.com> | 2005-10-19 14:00:32 +0000 |
commit | e421eb9e41bde5579e097cd7b7ec1b6f1a6b10bb (patch) | |
tree | acbadb1eeca9c3fda9dfbf81a9053b960345cb41 /scipy/base/getlimits.py | |
parent | f4f9be767a9eb4ef90d6f1920e391593eaaa3a0c (diff) | |
download | numpy-e421eb9e41bde5579e097cd7b7ec1b6f1a6b10bb.tar.gz |
Impl. finfo as a new-style singleton class. Added singleton tests.
Diffstat (limited to 'scipy/base/getlimits.py')
-rw-r--r-- | scipy/base/getlimits.py | 131 |
1 files changed, 82 insertions, 49 deletions
diff --git a/scipy/base/getlimits.py b/scipy/base/getlimits.py index b7bda6ffd..aeea5f191 100644 --- a/scipy/base/getlimits.py +++ b/scipy/base/getlimits.py @@ -8,7 +8,7 @@ from machar import MachAr import numeric from numeric import array -def frz(a): +def _frz(a): """fix rank-0 --> rank-1""" if len(a.shape) == 0: a = a.reshape((1,)) @@ -20,68 +20,101 @@ _convert_to_float = { numeric.clongfloat: numeric.longfloat } -_machar_cache = {} - class finfo(object): - def __init__(self, dtype): - dtype = numeric.obj2dtype(dtype) + + _finfo_cache = {} + + def __new__(cls, dtype): + obj = cls._finfo_cache.get(dtype,None) + if obj is not None: + return obj + dtypes = [dtype] + newdtype = numeric.obj2dtype(dtype) + if newdtype is not dtype: + dtypes.append(newdtype) + dtype = newdtype if not issubclass(dtype, numeric.inexact): - raise ValueError, "data type not inexact" + raise ValueError, "data type %r not inexact" % (dtype) + obj = cls._finfo_cache.get(dtype,None) + if obj is not None: + return obj if not issubclass(dtype, numeric.floating): - dtype = _convert_to_float[dtype] + newdtype = _convert_to_float[dtype] + if newdtype is not dtype: + dtypes.append(newdtype) + dtype = newdtype + obj = cls._finfo_cache.get(dtype,None) + if obj is not None: + return obj + obj = object.__new__(cls)._init(dtype) + for dt in dtypes: + cls._finfo_cache[dt] = obj + return obj + + def _init(self, dtype): + self.dtype = dtype if dtype is numeric.float_: - try: - self.machar = _machar_cache[numeric.float_] - except KeyError: - self.machar = MachAr(lambda v:array([v],'d'), - lambda v:frz(v.astype('i'))[0], - lambda v:array(frz(v)[0],'d'), - lambda v:'%24.16e' % array(frz(v)[0],'d'), - 'scipy float precision floating point '\ - 'number') - _machar_cache[numeric.float_] = self.machar - + machar = MachAr(lambda v:array([v],'d'), + lambda v:_frz(v.astype('i'))[0], + lambda v:array(_frz(v)[0],'d'), + lambda v:'%24.16e' % array(_frz(v)[0],'d'), + 'scipy float precision floating point '\ + 'number') elif dtype is numeric.single: - try: - self.machar = _machar_cache[numeric.single] - except KeyError: - self.machar = MachAr(lambda v:array([v],'f'), - lambda v:frz(v.astype('i'))[0], - lambda v:array(frz(v)[0],'f'), # - lambda v:'%15.7e' % array(frz(v)[0],'f'), - "scipy single precision floating "\ - "point number") - _machar_cache[numeric.single] = self.machar + machar = MachAr(lambda v:array([v],'f'), + lambda v:_frz(v.astype('i'))[0], + lambda v:array(_frz(v)[0],'f'), # + lambda v:'%15.7e' % array(_frz(v)[0],'f'), + "scipy single precision floating "\ + "point number") elif dtype is numeric.longfloat: - try: - self.machar = _machar_cache[numeric.longfloat] - except KeyError: - self.machar = MachAr(lambda v:array([v],'g'), - lambda v:frz(v.astype('i'))[0], - lambda v:array(frz(v)[0],'g'), # - lambda v:str(array(frz(v)[0],'g')), - "scipy longfloat precision floating "\ - "point number") - _machar_cache[numeric.longfloat] = self.machar + machar = MachAr(lambda v:array([v],'g'), + lambda v:_frz(v.astype('i'))[0], + lambda v:array(_frz(v)[0],'g'), # + lambda v:str(array(_frz(v)[0],'g')), + "scipy longfloat precision floating "\ + "point number") + else: + raise ValueError,`dtype` - for word in ['tiny', 'precision', 'resolution', - 'ngrd','maxexp','minexp','epsneg','negep', + for word in ['tiny', 'precision', 'resolution','iexp', + 'maxexp','minexp','epsneg','negep', 'machep']: - setattr(self,word,getattr(self.machar, word)) - self.max = self.machar.huge + setattr(self,word,getattr(machar, word)) + self.max = machar.huge self.min = -self.max - self.eps = self.machar.epsilon - self.nexp = self.machar.iexp - self.nmant = self.machar.it + self.eps = machar.epsilon + self.nexp = machar.iexp + self.nmant = machar.it + self.machar = machar + self._str_tiny = machar._str_xmin + self._str_max = machar._str_xmax + self._str_epsneg = machar._str_epsneg + self._str_eps = machar._str_eps + self._str_resolution = machar._str_resolution + return self + + def __str__(self): + return '''\ +Machine parameters for %(dtype)s +--------------------------------------------------------------------- +precision=%(precision)3s resolution=%(_str_resolution)s +machep=%(machep)6s eps= %(_str_eps)s +negep =%(negep)6s epsneg= %(_str_epsneg)s +minexp=%(minexp)6s tiny= %(_str_tiny)s +maxexp=%(maxexp)6s max= %(_str_max)s +nexp =%(nexp)6s min= -max +--------------------------------------------------------------------- +''' % self.__dict__ if __name__ == '__main__': f = finfo(numeric.single) - print 'single epsilon:',f.epsilon + print 'single epsilon:',f.eps print 'single tiny:',f.tiny f = finfo(numeric.float) - print 'float epsilon:',f.epsilon - print 'float tiny:',f.tiney + print 'float epsilon:',f.eps + print 'float tiny:',f.tiny f = finfo(numeric.longfloat) - print 'longfloat epsilon:',f.epsilon + print 'longfloat epsilon:',f.eps print 'longfloat tiny:',f.tiny |