Repository navigation
Missing ufuncs: np.divmod and np.positive #8932
Description
Activity
Hmm,
divmodis already a Python builtin function, so we don't want to shadow that. OTOH, it would add some efficiency to the current implementation ofndarray.__divmod__.+might be a bit weird if we let it overwrite itself using the out argument...- divmod ends up dispatching to the div and mod ufuncs, doesn't it? And pos is a unary operation that just returns a copy so a workaround would be for the mixin class to define __pos__ to call self.copy(). (Not expressing an opinion on the best solution, just thinking about the space of options.)
Hmm, divmod is already a Python builtin function, so we don't want to shadow that
Right, because some people still do
from numpy import *... sigh...So probably
np.divmod_it is, then.divmod ends up dispatching to the div and mod ufuncs, doesn't it?
That's right. So it probably does the right thing most of the time.
And pos is a unary operation that just returns a copy so a workaround would be for
the mixin class to define pos to call self.copy().Yes, that would certainly work.
One downside of the current unary
+operation is that it's defined on all array dtypes, so+np.array('foo')works even though+'foo'raises TypeError.Also, it would make sense to have a ufunc loop for
dtype=object, so that custom types that do something with__pos__don't get ignored in object arrays.divmod ends up dispatching to the div and mod ufuncs, doesn't it?
Yes, and each of those calls the relevant divmod function defined in
npy_math;) So two calls where one would do. Hey, it was the easy way...It should be pretty straightforward to add loops for both of these, right?
On the note of adding loops - it seems that we have two different methods of defining inner loops - one with a scalar function and an existing loop that calls it through the data pointer, and one that uses macros to instantiate a full loop containing that operation.
Which one is preferable?
is my approach in #8774 (gcd) the right one? Or was the approach in #8820 (heaviside) better?
Reacted by Stephan HoyerSee #8967 for a ufunc for
np.positive. The PR currently also uses it inndarray.__pos__, but that's probably premature.Nobody really uses
divmod, so I'm OK leaving__divmod__out from NDArrayOperatorsMixin. But it would be an shame to need to omit__pos__, too.Reacted by Eric WieserNobody really uses divmod
I'd wager that more people use
divmodthan__pos__, but whatever - I'd only use that as an argument for shipping with neither being an option tooBit late to the game, but we do have
Quantity.__divmod__in astropy -- and I usedivmodquite a bit myself in my baseband code (e.g., https://github.com/mhvk/baseband/blob/master/baseband/vlbi_base/base.py#L86)@mhvk if you're up for turning
np.divmodinto a single ufunc, that would be awesome! I think this would actually be quite straightforward and offer a 2x performance boost.Hmm, divmod is already a Python builtin function, so we don't want to shadow that.
If someone is using
from numpy import *, they deserve it! But honestly, they probably won't even notice, given that it works nearly equivalently to the builtin. We already do this sort of thing withnp.abs, which maps to<ufunc 'absolute'>.I actually might give
np.divmoda shot. It looks pretty straightforward.@shoyer - that would be great!
See #9063
These are not terribly useful, but would be nice to have for completeness, so we can implement every binary operation between arrays by calling
__array_ufunc__(e.g., forNDArrayOperatorsMixin, charris#19).Currently ndarray implements
__divmod__and__pos__in terms of other helper functions that aren't exposed in the API:numpy/numpy/core/src/multiarray/number.c
Line 1120 in f368286