Skip to content

Missing ufuncs: np.divmod and np.positive #8932

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
shoyer opened this issue Apr 12, 2017 · 14 comments
Closed

Missing ufuncs: np.divmod and np.positive #8932

shoyer opened this issue Apr 12, 2017 · 14 comments

Comments

@shoyer
Copy link
Member

shoyer commented Apr 12, 2017

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., for NDArrayOperatorsMixin, charris#19).

Currently ndarray implements __divmod__ and __pos__ in terms of other helper functions that aren't exposed in the API:

NPY_NO_EXPORT PyNumberMethods array_as_number = {

@charris
Copy link
Member

charris commented Apr 12, 2017

Hmm, divmod is already a Python builtin function, so we don't want to shadow that. OTOH, it would add some efficiency to the current implementation of ndarray.__divmod__. + might be a bit weird if we let it overwrite itself using the out argument...

@njsmith
Copy link
Member

njsmith commented Apr 12, 2017 via email

@shoyer
Copy link
Member Author

shoyer commented Apr 12, 2017

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.

@shoyer
Copy link
Member Author

shoyer commented Apr 12, 2017

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.

@eric-wieser
Copy link
Member

eric-wieser commented Apr 12, 2017

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.

@charris
Copy link
Member

charris commented Apr 12, 2017

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

@eric-wieser
Copy link
Member

eric-wieser commented Apr 12, 2017

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?

@shoyer
Copy link
Member Author

shoyer commented Apr 21, 2017

See #8967 for a ufunc for np.positive. The PR currently also uses it in ndarray.__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.

@eric-wieser
Copy link
Member

Nobody really uses divmod

I'd wager that more people use divmod than __pos__, but whatever - I'd only use that as an argument for shipping with neither being an option too

@mhvk
Copy link
Contributor

mhvk commented May 5, 2017

Bit late to the game, but we do have Quantity.__divmod__ in astropy -- and I use divmod quite a bit myself in my baseband code (e.g., https://github.com/mhvk/baseband/blob/master/baseband/vlbi_base/base.py#L86)

@shoyer
Copy link
Member Author

shoyer commented May 5, 2017

@mhvk if you're up for turning np.divmod into 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 with np.abs, which maps to <ufunc 'absolute'>.

@shoyer
Copy link
Member Author

shoyer commented May 5, 2017

I actually might give np.divmod a shot. It looks pretty straightforward.

@mhvk
Copy link
Contributor

mhvk commented May 5, 2017

@shoyer - that would be great!

@shoyer shoyer mentioned this issue May 6, 2017
3 tasks
@shoyer
Copy link
Member Author

shoyer commented May 6, 2017

See #9063

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants