Obsolete FloatMatrix type draft
Draft of FloatMatrix functionality. The special methods (__eq__ etc.) would need looking at, they might not be necessary.
Size 4.0 kB - File type text/python-sourceFile contents
from operator import mul as multiply
class FloatMatrix:
""" Ccpn nD Float matrix, behaving as a nested set of tuples.
Initialise with either:
A sequence of values and a matching shape tuple of dimension lengths
or:
A matrix implemented as nested sequences. In this case:
NB shape is set from 0th element in each dim
NB missing elements in any dimensin will throw an error
NB Excess elements in any internal sequence are ignored
NB A mapping with keys 0,1,...dimlength-1 will work in input
NB element values are coerced to float.
"""
__slots__ = ('_shape', '_data')
# Mandatory type for contents.
useType = float
#__slots__ = ('_shape')
def __init__(self, value, shape=None):
if isinstance(value, FloatMatrix):
value = value._data
if shape:
# check that data and shape conform
if len(value) != reduce(multiply, shape):
raise Exception("length of data do not match shape %s" % shape)
else:
# get shape.
# NB, uses 0th element to get lengths
# NB would work for sequence OR for mapping with key == 0
shape = []
val = value
while not isinstance(val, basestring):
try:
length = len(val)
val = val[0]
shape.append(length)
except TypeError:
break
# get flattened data
# NB will work correctly for maping with keys 0,1,...step
# NB will skip excess elements in any row or column that is too long
size = shape[0]
for step in shape[1:]:
size *= step
newval = [None] * size
indices = range(step)
ii = 0
for vv in value:
for jj in indices:
newval[ii] = vv[jj]
ii += 1
value = newval
# set shape attribute
self._shape = tuple(shape)
# set nested tuple value
value = tuple(self.useType(x) for x in value) # coerce to type (for testing)
for step in reversed(shape[1:]):
newval = tuple(tuple(value[x:x+step])
for x in range(0, len(value), step))
value = newval
# set value
self._data = value
def __getattr__(self, name):
return getattr(self._data, name)
def __lt__(self,other):
if isinstance(other, FloatMatrix):
return (self._data < other._data)
else:
return NotImplemented
def __le__(self,other):
if isinstance(other, FloatMatrix):
return (self._data <= other._data)
else:
return NotImplemented
def __gt__(self,other):
if isinstance(other, FloatMatrix):
return (self._data > other._data)
else:
return NotImplemented
def __ge__(self,other):
if isinstance(other, FloatMatrix):
return (self._data >= other._data)
else:
return NotImplemented
def __eq__(self,other):
if isinstance(other, FloatMatrix):
return (self._data == other._data)
else:
return NotImplemented
def __ne__(self,other):
if isinstance(other, FloatMatrix):
return (self._data != other._data)
else:
return NotImplemented
def __cmp__(self,other):
if isinstance(other, FloatMatrix):
return cmp(self._data, other._data)
else:
return NotImplemented
def getSize(self):
return reduce(multiply, self._shape)
size = property(getSize, None, None, "Number of elements in the matrix")
def getNdim(self):
return len(self._shape)
ndim = property(getNdim, None, None, "Number of dimensions in the matrix")
def getShape(self):
return self._shape
shape = property(getShape, None, None, "Matrix dimensions")
def getData(self):
"""get data flattened into single tuple"""
value = self._data
# flatten data
for step in self._shape[1:]:
newval = []
for vv in value:
newval.extend(vv)
value = newval
#
return tuple(value)
data = property(getData, None, None, "Data packed into single tuple")