[Numpy-discussion] question about ufuncs

Darren Dale dsdale24@gmail....
Fri Feb 6 17:55:39 CST 2009


On Fri, Feb 6, 2009 at 6:11 PM, Darren Dale <dsdale24@gmail.com> wrote:

> On Fri, Feb 6, 2009 at 5:18 PM, Pierre GM <pgmdevlist@gmail.com> wrote:
>
>>
>> On Feb 6, 2009, at 4:25 PM, Darren Dale wrote:
>>
>> >
>> > I've been looking at how ma implements things like multiply() and
>> > MaskedArray.__mul__. I'm surprised that MaskedArray.__mul__ actually
>> > calls ma.multiply() rather than calling
>> > super(MaskedArray,self).__mul__().
>>
>> There's some under-the-hood machinery to deal with the data, and we
>> need to be able to manipulate it *before* the operation takes place.
>> The super() approach calls __array_wrap__ on the result, so *after*
>> the operation took place, and that's not what we wanted...
>>
>
> It looks like there are enough cases where manipulation needs to happen on
> the way in that it might be useful to consider a mechanism for doing so. It
> could avoid the need for lots of wrappers and decorators down the road.
>
>
>>
>> > Maybe that is the way ndarray does it, but I don't think this is the
>> > right approach for my quantity subclasses. If I want to make a
>> > MaskedQuantity (someday), MaskedQuantity.__mul__ should be calling
>> > super(MaskedQuantity,self).__mul__(), not reimplementations of
>> > numpy.multiply or ma.multiply, right?
>>
>> You'll end up calling ma.multiply anyway
>> (super(MaskedQuantity,self).__mul__ will call MaskedArray.__mul__
>> which calls ma.multiply... So yes, I think you can stick to the
>> super() approach in your case
>>
>> >
>> > There are some cases where the default numpy function expects
>> > certain units on the way in, like the trig functions, which I think
>> > would have to be reimplemented.
>>
>> And you can probably define a generic class to deal with that instead
>> of reimplementing the functions individually (and we're back to the
>> initial advice).
>>
>>
>> > But aside from that, is there anything wrong with taking this
>> > approach? It seems to allow quantities to integrate pretty well with
>> > the numpy builtins.
>>
>> Go and try, the problems (if any) will show up...
>>
>
> Oh boy...
>

Well, without an analog to __array_wrap__ on the way in, the out parameter
for ufuncs poses a serious downside:

q1=1*m
q2=1*ft
numpy.add(q1,q2,q1)

I can raise an error complaining that you cant add meters and feet, but if I
catch it in __array_wrap__ it is too late to prevent overwriting q1 with
meaningless data. Also:

q1=[[1,1],[1,1]]*m
q2=[[2,2],[2,2]]*m
numpy.multiply(q1[0],q2[0],q1[0])

This will again raise an error, since quantities will not allow you to
attempt to change the units of a view. But numpy.multiply would have already
modified the data.

It seems like integrating quantities with existing numpy and scipy routines
would be greatly simplified if I could take advantage of __array_wrap__, but
I don't think I can use it if I can't raise errors in time to avoid
corrupting data in place. I guess for the purposes of demonstrating the
packages usefulness, for now I should wrap or reimplement numpy's ufuncs and
defer using __array_wrap__ unless it becomes possible for subclasses to
manipulate data on the way in to ufuncs.

Darren
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://projects.scipy.org/pipermail/numpy-discussion/attachments/20090206/0e8dc7e2/attachment-0001.html 


More information about the Numpy-discussion mailing list