Skip to content

Commit

Permalink
Further debugging, tests on recaster
Browse files Browse the repository at this point in the history
  • Loading branch information
matthew-brett committed Nov 30, 2006
1 parent de9fec3 commit 1669305
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 34 deletions.
2 changes: 1 addition & 1 deletion Lib/io/__init__.py
Expand Up @@ -8,7 +8,7 @@
from numpyio import packbits, unpackbits, bswap, fread, fwrite, \
convert_objectarray
from mio import *
from recaster import Recaster
from recaster import sctype_attributes, Recaster
from array_import import *
from data_store import *
from pickler import *
Expand Down
54 changes: 30 additions & 24 deletions Lib/io/recaster.py
Expand Up @@ -205,15 +205,20 @@ def smallest_same_kind(self, arr):
dti = dtp.itemsize
sctypes = self.sized_sctypes[dtp.kind]
sctypes = [t[0] for i, t in enumerate(sctypes) if t[1] < dti]
return self.smallest_from_sctypes(arr, sctypes)
return self._smallest_from_sctypes(arr, sctypes)

def smallest_from_sctypes(self, arr, sctypes):
def _smallest_from_sctypes(self, arr, sctypes):
''' Returns array recast to smallest possible type from list
Inputs
arr - array to recast
sctypes - list of scalar types to try
sctypes is expected to be ordered by size with largest first,
and to all be of the same type. It would not usually be
sensible to use this routine for integers (see
smallest_int_sctype method)
Returns None if no recast is within tolerance
'''
dt = arr.dtype.type
Expand Down Expand Up @@ -248,26 +253,6 @@ def smallest_int_sctype(self, mx, mn):
sz = tsz
return sct

def recast(self, arr):
''' Try arr downcast, upcast if necesary to get compatible type '''
dt = arr.dtype.type
ret_arr = self.downcast(arr)
if ret_arr is not None:
return ret_arr
# Could not downcast, arr dtype not in known list
# Try upcast to larger dtype of same kind
udt = self.capable_dtype[dt]
if udt is not None:
return arr.astype(udt)
# We are stuck for floats and complex now
# Can try casting integers to floats
if arr.dt.kind in ('i', 'u'):
sctypes = self.sized_sctypes['f']
arr = self.smallest_from_sctypes(arr, sctypes)
if arr is not None:
return arr
raise ValueError, 'Could not recast array within precision'

def downcast(self, arr):
dtk = arr.dtype.kind
if dtk == 'c':
Expand Down Expand Up @@ -313,3 +298,24 @@ def downcast_integer(self, arr):
if idt:
return arr.astype(idt)
return None

def recast(self, arr):
''' Try arr downcast, upcast if necesary to get compatible type '''
dt = arr.dtype.type
ret_arr = self.downcast(arr)
if ret_arr is not None:
return ret_arr
# Could not downcast, arr dtype not in known list
# Try upcast to larger dtype of same kind
udt = self.capable_dtype[dt]
if udt is not None:
return arr.astype(udt)
# We are stuck for floats and complex now
# Can try casting integers to floats
if arr.dt.kind in ('i', 'u'):
sctypes = self.sized_sctypes['f']
arr = self._smallest_from_sctypes(arr, sctypes)
if arr is not None:
return arr
raise ValueError, 'Could not recast array within precision'

72 changes: 63 additions & 9 deletions Lib/io/tests/test_recaster.py
Expand Up @@ -12,7 +12,8 @@

class test_recaster(ScipyTestCase):
def setUp(self):
self.recaster = Recaster([N.int32, N.complex64, N.float32])
self.valid_types = [N.int32, N.complex128, N.float64]
self.recaster = Recaster(self.valid_types)

def test_init(self):
# Setting sctype_list
Expand All @@ -35,11 +36,64 @@ def test_init(self):
# Integer sizes
# Cabable types

def test_methods(self):
A = N.array(1, N.float64)
B = A.astype(N.float32)
# smallest from sctypes
C = self.recaster.smallest_from_sctypes(A, [N.float32])
# smaller same kind
C = self.recaster.smallest_same_kind(A)
assert C.dtype == N.dtype(N.float32), 'Dtype was not downcast'
def test_smallest_same_kind(self):
R = self.recaster
value = 1
# smallest same kind
# Define expected type output from same kind downcast of value
required_types = {'complex': N.complex128,
'float': N.float64,
'int': N.int32,
'uint': None}
for kind, req_type in required_types.items():
if req_type is not None:
rdtsz = N.dtype(req_type).itemsize
for T in N.sctypes[kind]:
tdtsz = N.dtype(T).itemsize
ok_T = T in R.sctype_list
expect_none = ((req_type is None) or
((tdtsz < rdtsz) and not ok_T))
A = N.array(value, T)
C = R.smallest_same_kind(A)
if expect_none:
assert C is None, 'Expecting None for %s' % T
else:
assert C.dtype.type == req_type, \
'Expected %s type, got %s type' % \
(C.dtype.type, req_type)

def test_smallest_int_sctype(self):
# Smallest int sctype with testing recaster
params = sctype_attributes()
mmax = params[N.int32]['max']
mmin = params[N.int32]['min']
for kind in ('int', 'uint'):
for T in N.sctypes[kind]:
mx = params[T]['max']
mn = params[T]['min']
rt = self.recaster.smallest_int_sctype(mx, mn)
if mx <= mmax and mn >= mmin:
assert rt == N.int32, 'Expected int32 type'
else:
assert rt is None, 'Expected None, got %s for %s' % (T, rt)

# Smallest int sctype with full recaster
RF = Recaster()
test_triples = [(N.uint8, 0, 255),
(N.int8, -128, 0),
(N.uint16, 0, params[N.uint16]['max']),
(N.int16, params[N.int16]['min'], 0),
(N.uint32, 0, params[N.uint32]['max']),
(N.int32, params[N.int32]['min'], 0),
(N.uint64, 0, params[N.uint64]['max']),
(N.int64, params[N.int64]['min'], 0)]
for T, mn, mx in test_triples:
rt = RF.smallest_int_sctype(mx, mn)
assert rt == T, 'Expected %s, got %s type' % (T, rt)

def test_downcasts(self):
value = 1
R = self.recaster
A = N.array(value, N.complex128)
B = R.downcast_complex(A)
assert B.dtype.type == N.int32

0 comments on commit 1669305

Please sign in to comment.