-
Notifications
You must be signed in to change notification settings - Fork 13
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
Simplify angle_between
+ refactor quadrilateral_area
#65
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes to angle_between
look good, but not sure if you intended to use the random vector generation in the test or not?
somehow the tests are failing tho... I'll figure it out |
Yeah, it looks like that function is actually being called with some kind of array of vectors, so it needs to be multidimension-aware? |
OK, I see the issue... It's that How can I make it broadcast over the 2nd and 3rd dimension? I don't remember how to do it in python... :( |
I guess we could do |
This nv, nx, ny = np.shape(c0)
c0 = np.reshape(c0, (nx, ny, nv))
c1 = np.reshape(c1, (nx, ny, nv))
c2 = np.reshape(c2, (nx, ny, nv))
c3 = np.reshape(c3, (nx, ny, nv)) reshapes the inputs... But then how do I ask the |
I think if you write it in such a way that the dot products and cross products are computed over the last axis, it'll just work as expected. I think that's the case for the cross product, from https://numpy.org/doc/stable/reference/generated/numpy.cross.html#numpy.cross:
But I'm not sure what to do for the dot product... |
So at the moment I suggest we change it so that def quadilateral_area(v1, v2, v3, v4):
"""Returns area of a spherical quadrilateral on the unit sphere that
has vertices on 3-vectors `v1`, `v2`, `v3`, `v4` (counter-clockwise
orientation is implied). The area is computed as the excess of the
sum of the spherical angles of the quadrilateral from 2π."""
a1 = angle_between(v1, v2, v4)
a2 = angle_between(v2, v3, v1)
a3 = angle_between(v3, v4, v2)
a4 = angle_between(v4, v1, v3)
return a1 + a2 + a3 + a4 - 2.0 * np.pi that gives the area of a single quadrilateral. Then we have def quadilateral_areas(lat, lon):
.... that uses How do you like that? |
angle_between
angle_between
+ refactor quadrilateral_area
OK, I did it but it's not using broadcasting but it's doing the dreaded for-loop. See regional-mom6/regional_mom6/regional_mom6.py Lines 322 to 329 in 30254bd
@angus-g or @ashjbarnes can you convert it to broadcasting or something more efficient? |
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #65 +/- ##
==========================================
+ Coverage 15.42% 15.81% +0.39%
==========================================
Files 2 3 +1
Lines 428 430 +2
==========================================
+ Hits 66 68 +2
Misses 362 362
☔ View full report in Codecov by Sentry. |
Yeah, I'll take a look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it - very verbose and readable
OK, just the optimization of the for-loop with broadcasting and we are ready to merge then :) |
Here's an attempt at doing the broadcasting: dccdede It's a little ugly to have to |
We need to define a vecdot function (which is available in the Array API but not the main numpy API, sadly), which will compute the dot product of the last axis of two arrays.
Uses a more geometrically-inspired definition for the
angle_between
. Also refactorsquadrilateral_area
. Nowquadrilateral_area
computes the area of one quadrilateral andquadrilateral_areas
computes the areas of all quadrilaterals on a lat-lon grid.Closes #39