[Scipy-svn] r2243 - trunk/Lib/io
scipy-svn at scipy.org
scipy-svn at scipy.org
Sat Oct 7 09:34:11 EDT 2006
Author: matthew.brett at gmail.com
Date: 2006-10-07 08:34:06 -0500 (Sat, 07 Oct 2006)
New Revision: 2243
Modified:
trunk/Lib/io/mio4.py
trunk/Lib/io/mio5.py
trunk/Lib/io/miobase.py
Log:
First draft of downcasting machinery
Modified: trunk/Lib/io/mio4.py
===================================================================
--- trunk/Lib/io/mio4.py 2006-10-06 18:25:18 UTC (rev 2242)
+++ trunk/Lib/io/mio4.py 2006-10-07 13:34:06 UTC (rev 2243)
@@ -321,9 +321,12 @@
if scipy.sparse.issparse(arr):
return Mat4SparseWriter(stream, arr, name)
arr = array(arr)
- if arr.dtype.hasobject:
+ dtt = arr.dtype.type
+ if dtt is object_:
raise TypeError, 'Cannot save object arrays in Mat4'
- if arr.dtype.kind in ('U', 'S'):
+ elif dtt is void:
+ raise TypeError, 'Cannot save void type arrays'
+ elif dtt in (unicode_, string_):
return Mat4CharWriter(stream, arr, name)
else:
return Mat4NumericWriter(stream, arr, name)
Modified: trunk/Lib/io/mio5.py
===================================================================
--- trunk/Lib/io/mio5.py 2006-10-06 18:25:18 UTC (rev 2242)
+++ trunk/Lib/io/mio5.py 2006-10-07 13:34:06 UTC (rev 2243)
@@ -33,6 +33,11 @@
from miobase import *
+try: # Python 2.3 support
+ from sets import Set as set
+except:
+ pass
+
miINT8 = 1
miUINT8 = 2
miINT16 = 3
Modified: trunk/Lib/io/miobase.py
===================================================================
--- trunk/Lib/io/miobase.py 2006-10-06 18:25:18 UTC (rev 2242)
+++ trunk/Lib/io/miobase.py 2006-10-07 13:34:06 UTC (rev 2243)
@@ -370,3 +370,129 @@
''' Base class for Mat file writers '''
def __init__(self, file_stream):
self.file_stream = file_stream
+
+
+class DownCaster(object):
+ ''' Downcasts arrays '''
+
+ def __init__(self,
+ type_list=None,
+ rtol=1.0000000000000001e-05,
+ atol=1e-08):
+ ''' Set types for which we are attempting to downcast '''
+ def_dict = self.default_dt_dict()
+ if type_list is None:
+ self.dt_dict = def_dict
+ else:
+ dt_dict = {}
+ for T in type_list:
+ T = dtype(T).type
+ dt_dict[T] = def_dict[T]
+ self.dt_dict = dt_dict
+ self.rtol = rtol
+ self.atol = atol
+
+ def default_dt_dict(self):
+ d_dict = {}
+ for sc_type in ('complex','float'):
+ t_list = sctypes[sc_type]
+ for T in t_list:
+ dt = dtype(T)
+ d_dict[T] = {
+ 'kind': dt.kind,
+ 'size': dt.itemsize}
+ for T in sctypes['int']:
+ dt = dtype(T)
+ sz = dt.itemsize
+ bits = sz*8-1
+ end = 2**bits
+ d_dict[T] = {
+ 'kind': dt.kind,
+ 'size': sz,
+ 'min': -end,
+ 'max': end-1
+ }
+ for T in sctypes['uint']:
+ dt = dtype(T)
+ sz = dt.itemsize
+ bits = sz*8
+ end = 2**bits
+ d_dict[T] = {
+ 'kind': dt.kind,
+ 'size': sz,
+ 'min': 0,
+ 'max': end
+ }
+ return d_dict
+
+ def storage_criterion(self, maxstorage, kinds, cmp_func=lambda x, y: x <= y):
+ D = {}
+ for k, v in self.dt_dict.items():
+ if v['kind'] in kinds:
+ sz = v['size']
+ if cmp_func(sz, maxstorage):
+ D[k] = sz
+ I = D.items()
+ I.sort(lambda x, y: cmp(x[1], y[1]))
+ return I
+
+ def smaller_same_kind(self, arr):
+ dts = self.storage_criterion(arr.dtype.itemsize,
+ (arr.dtype.kind,),
+ lambda x, y: x < y)
+ ret_arr = arr
+ for T in dts:
+ test_arr = arr.astype(T)
+ if allclose(test_arr, arr, self.rtol, self.atol):
+ ret_arr = test_arr
+ else:
+ break
+ return ret_arr
+
+
+ def smallest_int_type(self, mx, mn):
+ dt = None
+ for k, v in self.dt_dict.items():
+ if v['kind'] in ('i', 'u'):
+ if v['max'] >= mx and v['min'] <= mn:
+ c_sz = v['size']
+ if dt is None or c_sz < sz:
+ dt = k
+ sz = c_sz
+ return dt
+
+ def downcast(self, arr):
+ dtk = arr.dtype.kind
+ if dtk == 'c':
+ return self.downcast_complex(arr)
+ elif dtk == 'f':
+ return self.downcast_float(arr)
+ elif dtk in ('u', 'i'):
+ return self.downcast_integer(arr)
+ else:
+ raise TypeError, 'Do not recognize array kind %s' % dtk
+
+ def downcast_complex(self, arr):
+ # can we downcast to float?
+ flts = self.storage_criterion(arr.dtype.itemsize / 2,
+ ('f'),
+ lambda x, y: x <=y)[0]
+ test_arr = arr.astype(flt)
+ if allclose(arr, test_arr, self.rtol, self.atol):
+ return self.downcast_float(test_arr)
+ # try downcasting to another complex type
+ return self.smaller_same_kind(arr)
+
+ def downcast_float(self, arr):
+ # Try integer
+ test_arr = self.downcast_integer(arr)
+ if allclose(arr, test_arr, self.rtol, self.atol):
+ return test_arr
+ # Otherwise descend the float types
+ return self.smaller_same_kind(arr)
+
+ def downcast_integer(self, arr):
+ mx = amax(arr)
+ mn = amin(arr)
+ idt = self.smallest_int_type(mx, mn)
+ return arr.astype(idt)
More information about the Scipy-svn
mailing list