~jtaylor/ubuntu/precise/python-numpy/multiarch-fix-818867

« back to all changes in this revision

Viewing changes to numpy/core/getlimits.py

  • Committer: Bazaar Package Importer
  • Author(s): Sandro Tosi
  • Date: 2010-10-07 10:19:13 UTC
  • mfrom: (7.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20101007101913-8b1kmt8ho4upcl9s
Tags: 1:1.4.1-5
* debian/patches/10_use_local_python.org_object.inv_sphinx.diff
  - fixed small typo in description
* debian/patches/changeset_r8364.diff
  - fix memory corruption (double free); thanks to Joseph Barillari for the
    report and to Michael Gilbert for pushing resolution; Closes: #581058

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
""" Machine limits for Float32 and Float64 and (long double) if available...
 
2
"""
 
3
 
 
4
__all__ = ['finfo','iinfo']
 
5
 
 
6
from machar import MachAr
 
7
import numeric
 
8
import numerictypes as ntypes
 
9
from numeric import array
 
10
 
 
11
def _frz(a):
 
12
    """fix rank-0 --> rank-1"""
 
13
    if a.ndim == 0: a.shape = (1,)
 
14
    return a
 
15
 
 
16
_convert_to_float = {
 
17
    ntypes.csingle: ntypes.single,
 
18
    ntypes.complex_: ntypes.float_,
 
19
    ntypes.clongfloat: ntypes.longfloat
 
20
    }
 
21
 
 
22
class finfo(object):
 
23
    """
 
24
    finfo(dtype)
 
25
 
 
26
    Machine limits for floating point types.
 
27
 
 
28
    Attributes
 
29
    ----------
 
30
    eps : floating point number of the appropriate type
 
31
        The smallest representable number such that ``1.0 + eps != 1.0``.
 
32
    epsneg : floating point number of the appropriate type
 
33
        The smallest representable number such that ``1.0 - epsneg != 1.0``.
 
34
    iexp : int
 
35
        The number of bits in the exponent portion of the floating point
 
36
        representation.
 
37
    machar : MachAr
 
38
        The object which calculated these parameters and holds more detailed
 
39
        information.
 
40
    machep : int
 
41
        The exponent that yields ``eps``.
 
42
    max : floating point number of the appropriate type
 
43
        The largest representable number.
 
44
    maxexp : int
 
45
        The smallest positive power of the base (2) that causes overflow.
 
46
    min : floating point number of the appropriate type
 
47
        The smallest representable number, typically ``-max``.
 
48
    minexp : int
 
49
        The most negative power of the base (2) consistent with there being
 
50
        no leading 0's in the mantissa.
 
51
    negep : int
 
52
        The exponent that yields ``epsneg``.
 
53
    nexp : int
 
54
        The number of bits in the exponent including its sign and bias.
 
55
    nmant : int
 
56
        The number of bits in the mantissa.
 
57
    precision : int
 
58
        The approximate number of decimal digits to which this kind of float
 
59
        is precise.
 
60
    resolution : floating point number of the appropriate type
 
61
        The approximate decimal resolution of this type, i.e.
 
62
        ``10**-precision``.
 
63
    tiny : floating point number of the appropriate type
 
64
        The smallest-magnitude usable number.
 
65
 
 
66
    Parameters
 
67
    ----------
 
68
    dtype : floating point type, dtype, or instance
 
69
        The kind of floating point data type to get information about.
 
70
 
 
71
    See Also
 
72
    --------
 
73
    MachAr : The implementation of the tests that produce this information.
 
74
    iinfo : The equivalent for integer data types.
 
75
 
 
76
    Notes
 
77
    -----
 
78
    For developers of NumPy: do not instantiate this at the module level. The
 
79
    initial calculation of these parameters is expensive and negatively impacts
 
80
    import times. These objects are cached, so calling ``finfo()`` repeatedly
 
81
    inside your functions is not a problem.
 
82
 
 
83
    """
 
84
 
 
85
    _finfo_cache = {}
 
86
 
 
87
    def __new__(cls, dtype):
 
88
        try:
 
89
            dtype = numeric.dtype(dtype)
 
90
        except TypeError:
 
91
            # In case a float instance was given
 
92
            dtype = numeric.dtype(type(dtype))
 
93
 
 
94
        obj = cls._finfo_cache.get(dtype,None)
 
95
        if obj is not None:
 
96
            return obj
 
97
        dtypes = [dtype]
 
98
        newdtype = numeric.obj2sctype(dtype)
 
99
        if newdtype is not dtype:
 
100
            dtypes.append(newdtype)
 
101
            dtype = newdtype
 
102
        if not issubclass(dtype, numeric.inexact):
 
103
            raise ValueError, "data type %r not inexact" % (dtype)
 
104
        obj = cls._finfo_cache.get(dtype,None)
 
105
        if obj is not None:
 
106
            return obj
 
107
        if not issubclass(dtype, numeric.floating):
 
108
            newdtype = _convert_to_float[dtype]
 
109
            if newdtype is not dtype:
 
110
                dtypes.append(newdtype)
 
111
                dtype = newdtype
 
112
        obj = cls._finfo_cache.get(dtype,None)
 
113
        if obj is not None:
 
114
            return obj
 
115
        obj = object.__new__(cls)._init(dtype)
 
116
        for dt in dtypes:
 
117
            cls._finfo_cache[dt] = obj
 
118
        return obj
 
119
 
 
120
    def _init(self, dtype):
 
121
        self.dtype = numeric.dtype(dtype)
 
122
        if dtype is ntypes.double:
 
123
            itype = ntypes.int64
 
124
            fmt = '%24.16e'
 
125
            precname = 'double'
 
126
        elif dtype is ntypes.single:
 
127
            itype = ntypes.int32
 
128
            fmt = '%15.7e'
 
129
            precname = 'single'
 
130
        elif dtype is ntypes.longdouble:
 
131
            itype = ntypes.longlong
 
132
            fmt = '%s'
 
133
            precname = 'long double'
 
134
        else:
 
135
            raise ValueError, repr(dtype)
 
136
 
 
137
        machar = MachAr(lambda v:array([v], dtype),
 
138
                        lambda v:_frz(v.astype(itype))[0],
 
139
                        lambda v:array(_frz(v)[0], dtype),
 
140
                        lambda v: fmt % array(_frz(v)[0], dtype),
 
141
                        'numpy %s precision floating point number' % precname)
 
142
 
 
143
        for word in ['precision', 'iexp',
 
144
                     'maxexp','minexp','negep',
 
145
                     'machep']:
 
146
            setattr(self,word,getattr(machar, word))
 
147
        for word in ['tiny','resolution','epsneg']:
 
148
            setattr(self,word,getattr(machar, word).squeeze())
 
149
        self.max = machar.huge.flat[0]
 
150
        self.min = -self.max
 
151
        self.eps = machar.eps.flat[0]
 
152
        self.nexp = machar.iexp
 
153
        self.nmant = machar.it
 
154
        self.machar = machar
 
155
        self._str_tiny = machar._str_xmin.strip()
 
156
        self._str_max = machar._str_xmax.strip()
 
157
        self._str_epsneg = machar._str_epsneg.strip()
 
158
        self._str_eps = machar._str_eps.strip()
 
159
        self._str_resolution = machar._str_resolution.strip()
 
160
        return self
 
161
 
 
162
    def __str__(self):
 
163
        return '''\
 
164
Machine parameters for %(dtype)s
 
165
---------------------------------------------------------------------
 
166
precision=%(precision)3s   resolution= %(_str_resolution)s
 
167
machep=%(machep)6s   eps=        %(_str_eps)s
 
168
negep =%(negep)6s   epsneg=     %(_str_epsneg)s
 
169
minexp=%(minexp)6s   tiny=       %(_str_tiny)s
 
170
maxexp=%(maxexp)6s   max=        %(_str_max)s
 
171
nexp  =%(nexp)6s   min=        -max
 
172
---------------------------------------------------------------------
 
173
''' % self.__dict__
 
174
 
 
175
 
 
176
class iinfo:
 
177
    """
 
178
    iinfo(type)
 
179
 
 
180
    Machine limits for integer types.
 
181
 
 
182
    Attributes
 
183
    ----------
 
184
    min : int
 
185
        The smallest integer expressible by the type.
 
186
    max : int
 
187
        The largest integer expressible by the type.
 
188
 
 
189
    Parameters
 
190
    ----------
 
191
    type : integer type, dtype, or instance
 
192
        The kind of integer data type to get information about.
 
193
 
 
194
    See Also
 
195
    --------
 
196
    finfo : The equivalent for floating point data types.
 
197
 
 
198
    Examples
 
199
    --------
 
200
    With types:
 
201
 
 
202
    >>> ii16 = np.iinfo(np.int16)
 
203
    >>> ii16.min
 
204
    -32768
 
205
    >>> ii16.max
 
206
    32767
 
207
    >>> ii32 = np.iinfo(np.int32)
 
208
    >>> ii32.min
 
209
    -2147483648
 
210
    >>> ii32.max
 
211
    2147483647
 
212
 
 
213
    With instances:
 
214
 
 
215
    >>> ii32 = np.iinfo(np.int32(10))
 
216
    >>> ii32.min
 
217
    -2147483648
 
218
    >>> ii32.max
 
219
    2147483647
 
220
 
 
221
    """
 
222
 
 
223
    _min_vals = {}
 
224
    _max_vals = {}
 
225
 
 
226
    def __init__(self, int_type):
 
227
        try:
 
228
            self.dtype = numeric.dtype(int_type)
 
229
        except TypeError:
 
230
            self.dtype = numeric.dtype(type(int_type))
 
231
        self.kind = self.dtype.kind
 
232
        self.bits = self.dtype.itemsize * 8
 
233
        self.key = "%s%d" % (self.kind, self.bits)
 
234
        if not self.kind in 'iu':
 
235
            raise ValueError("Invalid integer data type.")
 
236
 
 
237
    def min(self):
 
238
        """Minimum value of given dtype."""
 
239
        if self.kind == 'u':
 
240
            return 0
 
241
        else:
 
242
            try:
 
243
                val = iinfo._min_vals[self.key]
 
244
            except KeyError:
 
245
                val = int(-(1L << (self.bits-1)))
 
246
                iinfo._min_vals[self.key] = val
 
247
            return val
 
248
 
 
249
    min = property(min)
 
250
 
 
251
    def max(self):
 
252
        """Maximum value of given dtype."""
 
253
        try:
 
254
            val = iinfo._max_vals[self.key]
 
255
        except KeyError:
 
256
            if self.kind == 'u':
 
257
                val = int((1L << self.bits) - 1)
 
258
            else:
 
259
                val = int((1L << (self.bits-1)) - 1)
 
260
            iinfo._max_vals[self.key] = val
 
261
        return val
 
262
 
 
263
    max = property(max)
 
264
 
 
265
    def __str__(self):
 
266
        """String representation."""
 
267
        return '''\
 
268
Machine parameters for %(dtype)s
 
269
---------------------------------------------------------------------
 
270
min = %(min)s
 
271
max = %(max)s
 
272
---------------------------------------------------------------------
 
273
''' % {'dtype': self.dtype, 'min': self.min, 'max': self.max}
 
274
 
 
275
 
 
276
if __name__ == '__main__':
 
277
    f = finfo(ntypes.single)
 
278
    print 'single epsilon:',f.eps
 
279
    print 'single tiny:',f.tiny
 
280
    f = finfo(ntypes.float)
 
281
    print 'float epsilon:',f.eps
 
282
    print 'float tiny:',f.tiny
 
283
    f = finfo(ntypes.longfloat)
 
284
    print 'longfloat epsilon:',f.eps
 
285
    print 'longfloat tiny:',f.tiny