Week-9 Ufunc Overrides
This week I'm still working on the pull request for ufunc overrides, however I think it is finally nearing completion. The implementation is working as described and all tests are passing. I'm looking forward to working on SciPy again.
The main aspects I've been working on are ufunc overrides method resolution order, and argument normalization.
Method Resolution Order (MRO)¶
Python functions in certain cases have a special MRO which is a bit more
complicated than the default left to right. Whenever ther right argument is a
subtype of the left argument its special method corresponding to the calling
function is called first. So for example, add(a, b)
would normally call
a.__add__(b)
but if b
is a subtype of a
, then b.__radd__(a)
is called.
However there are no examples in the Python standard library of a ternary or
greater function from which we can copy. So we have tried to generalize this
concept to a higher order.
The MRO algorithm is succinctly stated by @njsmith as:
While there remain untried inputs, pick the leftmost one which does not have a proper subtype still remaining to be checked.
Where inputs are the inputs to the ufunc. Trying an input refers to calling
its __numpy_ufunc__
method (if it has one) and seeing that it does not return
NotImplemented
.
So Basically if a ufunc has three inputs (a, b, as
) in that order, where as
is a subtype of a
. They will be tried in the order b > as > a
.
Argument Normalization¶
Many of NumPy's ufuncs can take a out
argument, which specifies where the
output of the ufunc is assigned. The out
argument can be passed as either a
positional, or keyword argument. So naïvely checking a ufuncs arguments for
__numpy_ufunc__
and then passing said arguments unaltered is not always
sensible. So given nargs
- the number of args, and nin
- the number of
inputs, we can check for an out
positional argument and move it to the
keyword arguments. The normalized arguments are then passed the
__numpy_ufunc__
method.
Comments
Comments powered by Disqus