Skip to content

Use np.hypot wherever possible.#10322

Merged
WeatherGod merged 1 commit into
matplotlib:masterfrom
anntzer:hypot
Oct 7, 2018
Merged

Use np.hypot wherever possible.#10322
WeatherGod merged 1 commit into
matplotlib:masterfrom
anntzer:hypot

Conversation

@anntzer

@anntzer anntzer commented Jan 25, 2018

Copy link
Copy Markdown
Contributor

Clearer IMO, although perhaps not for the examples?

PR Summary

PR Checklist

  • Has Pytest style unit tests
  • Code is PEP 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@anntzer anntzer force-pushed the hypot branch 2 times, most recently from c86fbc7 to e097aaf Compare January 25, 2018 22:41

@afvincent afvincent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure that np.hypot is clearer for most users (I personally remember that I had to have a look at Numpy's doc the first time I saw it in a commit). But maybe it is better known than what I think.

One small typo (I think).

Comment thread examples/mplot3d/surface3d.py Outdated
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
R = np.sqrt(X, Y)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

np.hypot(X, Y)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

y

Comment thread lib/matplotlib/patches.py
xm = x1 + self.frac * r * math.cos(theta)
ym = y1 + self.frac * r * math.sin(theta)
xm = x1 + self.frac * (x2 - x1)
ym = y1 + self.frac * (y2 - y1)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch :).

@anntzer

anntzer commented Jan 25, 2018

Copy link
Copy Markdown
Contributor Author

That's why I said "perhaps not for the examples".

@timhoffm

Copy link
Copy Markdown
Member

Oh, I wasn't aware of hypot either. Maybe not in the examples?

@jklymak

jklymak commented Jan 25, 2018

Copy link
Copy Markdown
Member

Not particularly a fan of this suggestion. Its a tiny bit shorter, and substantially less readable. I'd have to go a google to figure out exactly what np.hypot means as well.

@anntzer

anntzer commented Jan 25, 2018

Copy link
Copy Markdown
Contributor Author

I'll revert the examples. Vote on this message w.r.t. the lib itself (+1 to use hypot, -1 to not use it). IMO once you know the function (whose name is not completely silly) it does make things more readable (plus it should be a tiny bit more efficient as it will avoid allocating a bunch of intermediate temporary arrays).

@QuLogic

QuLogic commented Jan 26, 2018

Copy link
Copy Markdown
Member

Pretty sure you had another PR with something similar and we thought it'd be best not to add hypot in examples.

@anntzer

anntzer commented Jan 26, 2018

Copy link
Copy Markdown
Contributor Author

You were actually suggesting the other way round :p #7562 (comment)

@anntzer

anntzer commented Jan 26, 2018

Copy link
Copy Markdown
Contributor Author

reverted the examples

@QuLogic

QuLogic commented Jan 26, 2018

Copy link
Copy Markdown
Member

That's why I said "we" 😉

Comment thread lib/matplotlib/bezier.py

def _f(xy):
x, y = xy
return (x - cx) ** 2 + (y - cy) ** 2 < r2

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that this change is an improvement. The original is probably faster, since there is a square-root computation inside hypot.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the real cost is actually setting up the numpy ufunc, but sure.

@jkseppan

Copy link
Copy Markdown
Member

I think the point of hypot is to avoid numerical problems if one of the arguments is big or small. Perhaps it is slightly easier to read as well, so I think replacing sqrt(x**2+y**2) or the equivalents to use hypot is usually a good idea. I wouldn't replace comparisons of x**2+y**2 against r**2 with a call to hypot, because that's a common performance optimization that avoids computing a square root.

@anntzer

anntzer commented Jan 27, 2018

Copy link
Copy Markdown
Contributor Author

The real cost is not the square root (~40ns, by timing x**2+y**2 vs math.sqrt(x**2+y**2)), but actually the ufunc machinery (~1us, by timing math.hypot(x, y) vs np.hypot(x, y)). In any case I restored the explicit calculation in these cases.

@anntzer anntzer force-pushed the hypot branch 3 times, most recently from 5a00e0d to 13cb849 Compare March 29, 2018 18:48

@WeatherGod WeatherGod left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most everything looks good, just one spot that I think is wrong.

Comment thread lib/matplotlib/projections/geo.py Outdated
clat = self._center_latitude
p = np.sqrt(x*x + y*y)
p = np.where(p == 0.0, 1e-9, p)
p = np.max(np.hypot(x, y), 1e-9)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be np.maximum()?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit scary that we don't error on this, but heh, fixed.

@WeatherGod

Copy link
Copy Markdown
Member

travis is failing on a streamplot test in all python versions. RMS of 0.0009. Possibly a tiny numerical precision change somewhere?

@anntzer

anntzer commented Oct 6, 2018

Copy link
Copy Markdown
Contributor Author

Indeed, looks like an accuracy issue on streamplot, can repro locally. Switched the relevant line back to sqrt(x**2+y**2) as I don't think it's worth a baseline image update.

Except examples, where it may be too obscure?

Also added -T to CI sphinx-build invocation, to help troubleshooting
e.g. https://circleci.com/gh/anntzer/matplotlib/2505?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link
(show traceback on sphinx failure).
@WeatherGod WeatherGod merged commit ea031c2 into matplotlib:master Oct 7, 2018
@QuLogic QuLogic added this to the v3.1 milestone Oct 7, 2018
@anntzer anntzer deleted the hypot branch October 7, 2018 02:01
@QuLogic QuLogic changed the title Use np.hypot whereever possible. Use np.hypot wherever possible. Apr 18, 2020
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

Successfully merging this pull request may close these issues.

7 participants