[SciPy-user] Sub-classing NumArray
Colin J. Williams
cjw at sympatico.ca
Wed Aug 6 16:19:58 EDT 2003
Todd,
Thanks, your suggestions would likely deliver a Matrix class, I'll think
some more about it
The basic problems, as I see them, are:
(1) I would like to handle real and complex matrices.
(2) There are a number of things left out on the counter (as functions)
which would probably be better hidden within the class instance.
I wonder whether the NumArray could carry an extra attribute
(_modeOfStorage).
This could be set within NumArray.__init__, once the type of data has been
determined. modeOfStorage might be interleaved or regular. Or, even
simpler,
_modeOfStorage could be determined from the elementType (now called type).
If this were feasible, then there could probably be a NumArray class which
handles real or complex data (and possibly bit data for Booleans).
A scheme along the following lines might work:
class NumArray(_numarray._numarray, _gen.NDArray):
'''Fundamental Numeric Array
shape The shape of the resulting NumArray.
elementType The numerictype of each data element, e.g. Int32
'''
def __init__(self, data, shape=(), elementType=_nt.Any):
#
Choose the method for conversion, based on type(data):
fromFile
fromSimpleValue - this is passed on to fromList
from List
fromString
fromArray - possibly this is
deprecated, or will be when numarray is fully
operational.
Each of these would either raise an exception,
indicating grief
of some sort, or would return a 4tuple:
i. memoryBuffer - a MemoryType,
containing data
ii. elementType - detemined either from
data. or as specified to the constructor
iii. shape - detemined either
from data. or as specified to the constructor
iv. itemSize - this may be
redundant as it is probably deteminable from the
memoryBuffer, since it is known to MemoryType.__repr__
_genNDArray.__init__(self, shape, itemsize)
self._data= memoryBuffer
self._type= elementType
self._shape= shape
self._itemsize= itemsize - this is probably
redundant as it is given by elementType.bytes
_validate(self)
def _validate(self):
" Primarily to validate sub-classes. "
pass
# An example of what validate might be for a Matrix sub-class
def _validate(self):
s= self.shape
if len(s) == 1: # treat as a row vector
s= (1, s[0])
self.resize(s)
elif len(s) == 2:
pass
else:
raise ValueError, 'data not compatible with Matrix -
data:\n'+ self.__repr__()
if \ # isinstance(self.shape, types.IntType) or \
len(self.shape) in (1, 2):
return
else:
raise TypeError, 'Not a valid matrix'
I've suggested dropping some parameters:
buffer=None -
this could, with a fromBuffer method, probably be
entered as data.
byteoffset=0 -
perhaps there is a need for values other than zero
bytestride=None - this
apears to be calculable.
byteorder=_sys.byteorder - this
appears to be system related and thus the default
would probably do.
aligned=1 -
I'm not sure what this indicates, is it also system related?
Much of the code needed is likely already in numarraycore. Thus, basing
NumArray more firmly on
the Python class would appear to be feasible.
Colin W.
Todd Miller wrote:
>On Tue, 2003-08-05 at 14:35, Colin J. Williams wrote:
>
>[snip]
>
>
>
>>Incidentally, I am exploring the feasibility of basing a Matrix class on
>>NumArray, but
>>find it difficult, in view of the use of factory functions, rather than
>>the conventional
>>instance constructors.
>>
>>
>
>Well, subclassing is a little tricky, and we haven't done it that much
>yet ourselves. What's wrong with:
>
>import numarray.numarraycore as _nc
>import numarray.generic as _gen
>import numarray.linear_algebra as _la
>
>def _matrixize(result):
> return result
>
>def array(*args, **keys):
> return _matrixize(_nc.array(*args, **keys))
>
>def fromlist(*args, **keys):
> return _matrixize(_nc.fromlist(*args, **keys))
>
>def fromfile(*args, **keys):
> return _matrixize(_nc.fromfile(*args, **keys))
>
>class Matrix(_nc.NumArray):
>
> def _reclassify(self, a):
> a.__class__ = self.__class__
> return a
>
> def __mul__(self, other):
> return self._reclassify(_nc.dot(self, other))
>
> def determinant(self):
> return _la.determinant(self)
>
> def inverse(self):
> return self._reclassify(_la.inverse(self))
>
>
>Todd
>
>_______________________________________________
>SciPy-user mailing list
>SciPy-user at scipy.net
>http://www.scipy.net/mailman/listinfo/scipy-user
>
>
>
More information about the SciPy-User
mailing list