[Numpy-discussion] numarray unfriendly to user defined types
Tim Hochberg
tim.hochberg at ieee.org
Thu Sep 18 16:20:02 CDT 2003
I've run into another issue in my attempt to transition over to
numarray: it's less friendly to user defined types than Numeric. I think
this is mainly accidental friednliness on Numeric's part, but it's handy
nonetheless. The attached file illustrates the issue. Given some object,
in this case *zero*, that a numarray array does not now how to handle,
it ends up raising an exception instead of giving the object a chance to
try. Thus ``zero + numarray.arange(5)`` works while ``numarray.arange(5)
+ zero`` fails, since in the first case Zero.__add__ is called first,
while in the second NumArray.__add__ is called first.
This should probably be fixed, but it's not clear what the best way is.
My first thought was to always give the other object a chance to use
__rop__ first. This is simple and easy to explain, but fails miserably
in the common case of multiplying a list and an array. Just to be
concrete, __mul__ would be replaced by::
def __mul__(self, operand):
try:
return operand.__rmul__(self)
except:
return ufunc.multiply(self, operand)
Next thought is to catch exceptions when they occur in numarray and then
give the other operand a chance::
def __mul__(self, operand):
try:
return ufunc.multiply(self, operand)
except:
return operand.__rmul__(self)
This appears like it would fix my particular problem, but still is not
ideal. Since numarray is the base of libraries that it will know nothing
about, it should defer to classes it doesn't know about whenever
possible. Otherewise it's not possible (or maybe just hard) to create
new classes that try to be clever, but still interact with numarray in a
reasonable way. In my case I'm thinking of proxy objects that don't do
some computations till they are actually required. So my current
thinking is that __mul__ and friends would be best implemented as::
def __mul__(self, operand):
if not isinstance(operand, knownTypes):
try:
return ufunc.multiply(self, operand)
except:
pass
return operand.__rmul__(self)
Where knownTypes is something like (int, long, float, complex, tuple, list).
Anyway, that's my excessively long two cents on this.
-tim
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: unfriendly.py
Url: http://projects.scipy.org/pipermail/numpy-discussion/attachments/20030918/b12aebe9/attachment.pl
More information about the Numpy-discussion
mailing list