-
Notifications
You must be signed in to change notification settings - Fork 3
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
Add prolate spheroidal coordinates #220
Conversation
Tests are failing for two reasons that might be related:
One approach could be to allow a default |
That's a good question! We don't have a mechanism for that. This is complicated, essentially each value of
So writing this out, (2) might be technically / mathematically better, but (1) seems best to do now. Order of events: 😓
|
@nstarman I think this is ready for a look! Tests are failing with a gnarly recursion error in |
OK it turns out the recursion error was because one of the tests was calling the fallback |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #220 +/- ##
==========================================
+ Coverage 97.00% 97.04% +0.03%
==========================================
Files 115 116 +1
Lines 3473 3617 +144
==========================================
+ Hits 3369 3510 +141
- Misses 104 107 +3 ☔ View full report in Codecov by Sentry. |
@nstarman OK tests are passing, so take a look at how I handled |
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.
Looks really good. Small comments only. Then should be ready 🚀
Hm, not sure about the failing test. Adding the converter to @eqx.filter_jit
def func(q):
return q.represent_as(cx.ProlateSpheroidalPos, Delta=Quantity(1.0, "kpc"))
q = cx.CartesianPos3D.from_([1, 2, 3], "kpc")
func(q) |
Can you try removing the parametrization in the converter? Maybe just |
But also Happy Thanksgiving 🦃! For after the holidays :) |
Hm, removing the "length" parametrization didn't fix it! No rush to respond (but I'll be working on and off this weekend) |
Then remove and flag in an Issue for followup! Let's get this in. Looks great otherwise. |
I realized one other issue with this PR! Velocity transforms aren't working at the moment - I can look into it tomorrow: pos = cx.CartesianPos3D.from_([1., 2., 3.], "kpc")
vel = cx.CartesianVel3D.from_([1., 2., 3.], "km/s")
vel.represent_as(cx.ProlateSpheroidalVel, pos, Delta=Quantity(0.1, "kpc")) ---------------------------------------------------------------------------
EquinoxTracetimeError Traceback (most recent call last)
Cell In[3], line 3
1 pos = cx.CartesianPos3D.from_([1., 2., 3.], "kpc")
2 vel = cx.CartesianVel3D.from_([1., 2., 3.], "km/s")
----> 3 vel.represent_as(cx.ProlateSpheroidalVel, pos, Delta=Quantity(0.1, "kpc"))
[... skipping hidden 2 frame]
File ~/projects/coordinax/.venv/lib/python3.10/site-packages/jaxtyping/_decorator.py:449, in jaxtyped.<locals>.wrapped_fn_impl(args, kwargs, bound, memos)
446 raise TypeCheckError(msg) from e
448 # Actually call the function.
--> 449 out = fn(*args, **kwargs)
451 if full_signature.return_annotation is not inspect.Signature.empty:
452 # Now type-check the return value. We need to include the
453 # parameters in the type-checking here in case there are any
(...)
464 # checking of the parameters. Unfortunately there doesn't seem
465 # to be a way around that, so c'est la vie.
466 kwargs[output_name] = out
File ~/projects/coordinax/src/coordinax/_src/vectors/base/base.py:203, in AbstractVector.represent_as(self, target, *args, **kwargs)
153 def represent_as(self, target: type, *args: Any, **kwargs: Any) -> "AbstractVector":
154 """Represent the vector as another type.
155
156 This just forwards to `coordinax.represent_as`.
(...)
201
202 """
--> 203 return represent_as(self, target, *args, **kwargs)
[... skipping hidden 2 frame]
File ~/projects/coordinax/.venv/lib/python3.10/site-packages/jaxtyping/_decorator.py:449, in jaxtyped.<locals>.wrapped_fn_impl(args, kwargs, bound, memos)
446 raise TypeCheckError(msg) from e
448 # Actually call the function.
--> 449 out = fn(*args, **kwargs)
451 if full_signature.return_annotation is not inspect.Signature.empty:
452 # Now type-check the return value. We need to include the
453 # parameters in the type-checking here in case there are any
(...)
464 # checking of the parameters. Unfortunately there doesn't seem
465 # to be a way around that, so c'est la vie.
466 kwargs[output_name] = out
File ~/projects/coordinax/src/coordinax/_src/vectors/transform/differentials.py:130, in represent_as(current, target, position, **kwargs)
115 current_pos = replace(
116 current_pos,
117 **{
(...)
121 },
122 )
124 # Takes the Jacobian through the representation transformation function. This
125 # returns a representation of the target type, where the value of each field the
126 # corresponding row of the Jacobian. The value of the field is a Quantity with
127 # the correct numerator unit (of the Jacobian row). The value is a Vector of the
128 # original type, with fields that are the columns of that row, but with only the
129 # denomicator's units.
--> 130 jac_nested_vecs = jac_rep_as(current_pos, target.integral_cls)
132 # This changes the Jacobian to be a dictionary of each row, with the value
133 # being that row's column as a dictionary, now with the correct units for
134 # each element: {row_i: {col_j: Quantity(value, row.unit / column.unit)}}
135 jac_rows = {
136 f"d_{k}": {
137 kk: Quantity(vv.value, unit=v.unit / vv.unit)
(...)
140 for k, v in field_items(jac_nested_vecs)
141 }
[... skipping hidden 27 frame]
File ~/projects/coordinax/src/coordinax/_src/vectors/d3/transform.py:801, in represent_as(current, target, **kwargs)
765 @dispatch
766 def represent_as(
767 current: AbstractPos3D,
(...)
770 **kwargs: Any,
771 ) -> ProlateSpheroidalPos:
772 """AbstractPos3D -> ProlateSpheroidalPos.
773
774 Examples
(...)
799
800 """
--> 801 Delta = eqx.error_if(
802 kwargs.get("Delta"),
803 "Delta" not in kwargs,
804 "Delta must be provided for ProlateSpheroidalPos.",
805 )
806 cyl = represent_as(current, CylindricalPos)
807 return represent_as(cyl, target, Delta=Delta)
[... skipping hidden 2 frame]
File ~/projects/coordinax/.venv/lib/python3.10/site-packages/equinox/_errors.py:313, in branched_error_if_impl(x, pred, index, msgs, on_error)
311 assert type(index) is int
312 if on_error == "raise":
--> 313 raise EquinoxTracetimeError(msgs[index])
314 elif on_error == "breakpoint":
315 print(msgs[index])
EquinoxTracetimeError: Delta must be provided for ProlateSpheroidalPos. |
Looks like |
Yes exactly - but the way it is vmap'd, I think the kwargs get batched alone axis=0 which would obviously fail for a scalar |
If it's enforced scalar, then |
Co-authored-by: Nathaniel Starkman <[email protected]> Signed-off-by: Adrian Price-Whelan <[email protected]>
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'm gearing up to add the Staeckel Fudge to Galax, so it would be useful to have a representation of prolate spheroidal coordinates. Transformations to this coordinate system need to specify a focal length parameter,
Delta
, so it's a bit different from other d3 representations. Thoughts on this approach?