1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
""" Machine limits for Float32 and Float64 and (long double) if available...
"""
__all__ = ['finfo']
from machar import MachAr
import numeric
from numeric import array
def _frz(a):
"""fix rank-0 --> rank-1"""
if a.ndim == 0: a.shape = (1,)
return a
_convert_to_float = {
numeric.csingle: numeric.single,
numeric.complex_: numeric.float_,
numeric.clongfloat: numeric.longfloat
}
class finfo(object):
_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 %r not inexact" % (dtype)
obj = cls._finfo_cache.get(dtype,None)
if obj is not None:
return obj
if not issubclass(dtype, numeric.floating):
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_:
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:
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:
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','iexp',
'maxexp','minexp','epsneg','negep',
'machep']:
setattr(self,word,getattr(machar, word))
self.max = machar.huge
self.min = -self.max
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.eps
print 'single tiny:',f.tiny
f = finfo(numeric.float)
print 'float epsilon:',f.eps
print 'float tiny:',f.tiny
f = finfo(numeric.longfloat)
print 'longfloat epsilon:',f.eps
print 'longfloat tiny:',f.tiny
|