[Numpy-discussion] question about ufuncs

Darren Dale dsdale24 at gmail.com
Fri Feb 6 16:25:42 EST 2009


On Sun, Feb 1, 2009 at 7:39 PM, Darren Dale <dsdale24 at gmail.com> wrote:

> On Sun, Feb 1, 2009 at 7:33 PM, Pierre GM <pgmdevlist at gmail.com> wrote:
>
>>
>> On Feb 1, 2009, at 6:32 PM, Darren Dale wrote:
>> >
>> >
>> > Is there an analog to __array_wrap__ for preprocessing arrays on
>> > their way *into* a ufunc? For example, it would be nice if one could
>> > do something like:
>> >
>> > numpy.sin([1,2,3]*arcseconds)
>> >
>> > where we have the opportunity to inspect the context, convert the
>> > Quantity to units of radians, and then actually call the ufunc. Is
>> > this possible, or does one have to reimplement such functions?
>>
>> Just an idea: look at the code for numpy.ma ufuncs (in numpy.ma.core).
>> By defining a few classes for unary, binary and domained functions,
>> you could probably do what you want, without having to recode all the
>> functions by hand.
>> Another idea would be to define some specific __mul__ or __rmul__
>> rules for your units, so that the list would be transformed into a
>> UnitArray...
>
>
> I have pretty good implementations of the arithmetic operators, so
> ([1,2,3]*m)*([4,5,6]*J) already works. numpy.multiply and numpy.sqrt needed
> help with array_wrap. I'll study your stuff in ma, thanks for the pointer.
>

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__(). 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?

As I understand it, the point of __array_wrap__ is to provide a mechanism
such that ndarray subclasses could work with numpy's built-in ufuncs. In my
case, I had been planning to use the calling ufunc as a key to find the
appropriate way to propagate whatever metadata is associated with the
subclass, for example:

    def __array_wrap__(self, obj, context):
        try:
            result =
super(Quantity,self).__array_wrap__(obj,context).view(type(self))
        except:
            result = obj.view(type(self))

        ufunc, objs, huh = context
        result._dimensionality = self._propagate_dimensionality[ufunc](objs)
        return result

Where self._propagate_dimensionality is a dictionary of functions operating
on Dimensionality objects.

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. 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.

Darren
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20090206/33696421/attachment.html>


More information about the NumPy-Discussion mailing list