-
Notifications
You must be signed in to change notification settings - Fork 7
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
Vectorize #5
Conversation
For a bunch of current work, it would probably be helpful to have the one, vectorized Quaternion approach instead of a mix of current Quaternion and mica.quaternion whenever vectors are needed. I'm not sure if there are any showstoppers in this implementation. |
Needs updated tests. |
Move to explicit keywords for the input types (but still supporting the old API for single values supplied as arguments). |
Does this also need rebase? |
or merge. What I did in my local copy for now is to merge into master. Otherwise the test does not work. |
Our workflow (inherited from astropy) is always rebase to get rid of conflicts, never merge master. I'm not precisely sure of the reason, but in astropy anyway whenever contributors accidentally do a merge it tends to be a disaster and they get like 50 unrelated commits showing up in their PR. |
but one should not rebase a branch that was already pushed. I have done merges to branches without problem. In any case, I did the merge after pushing, so it should not be in github. Right now gitk kills my OSX session, so I can't inspect the index before pushing, which I normally do. Hopefully I did not break anything. |
by the way, I understand about not merging master, I am not advocating it. I suppose cherry-picking from master is the right way. If we rebase on a branch that was pushed already, shouldn't one then create a whole new branch? |
Given that is is just us with this branch and we're likely to have one developer at a time working in the branch, I'm good with force pushing the branch after rebase. |
Agreed with @jeanconn. Even in the wild world of astropy we rebase and force push branches all the time. Reviewers can just delete their local version and re-fetch as needed. The only hard rule is never force push to master or a release branch. |
ok. Force-pushed. When making the changes for arbitrary shapes, there was some juggling with axes, because the transpose function does not do what we want. I used np.moveaxis. I think I can go over the code once again to see if that can be written better. |
Yeah, the axis juggling was why I had thought about numba + simple loops on the outside. But if you are able to get it right with axes then that's great. |
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.
Mostly trivial except the _is_scalar
issue. I just got 2/3 way through but have to quit for now.
I added a _shape data member (instead of _is_scalar). I figure it is more explicit. Then I replaced the if+squeeze statements by a reshape operation. If anyone has strong feelings about it, I can introduce the squeeze statements instead. |
Quaternion/tests/test_all.py
Outdated
t = [[9.25416578e-01, -3.18795778e-01, -2.04874129e-01], | ||
[1.63175911e-01, 8.23172945e-01, -5.43838142e-01], | ||
[3.42020143e-01, 4.69846310e-01, 8.13797681e-01]] | ||
_ = Quat(t) |
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.
What is this testing?
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.
No idea. I am removing it. A few lines above there is a test for this interface.
q2 = Quat(q=q1.q) | ||
|
||
|
||
def test_from_eq_vectorized(): |
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.
The unrolled tests below are excellent. Can you also add the tests like below, that are the most simple way for my brain to be sure that everything works as expected. You might need to remove the dec=90 values from the input, not sure. These are at least partially redundant, but not entirely (I think).
atol = 1e-12 # Hopefully this works?
# Compare vectorized computations for all possible input/output combos
# with the same for the scalar calculation.
q = Quat(equatorial=equatorial23)
assert np.all(q.q == q23)
assert np.all(q.equatorial == equatorial23)
assert np.all(q.transform == transform23)
q = Quat(q=q23)
assert np.all(q.q == q23)
assert np.allclose(q.equatorial, equatorial23, rtol=0, atol=atol)
assert np.allclose(q.transform, transform23, rtol=0, atol=atol)
q = Quat(transform=transform23)
assert np.allclose(q.q, q23, rtol=0, atol=atol)
assert np.allclose(q.equatorial, equatorial23, rtol=0, atol=atol)
assert np.all(q.transform == transform23)
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.
This test fails because of the points I chose, which are gimbal locks:
assert np.allclose(q.equatorial, equatorial_23)
Then I changed the points to some pseudo-random values and it also fails because q.equatorial can return, for example, roll=-30 or roll=330 depending on I don't know what. Angles are not supposed to be normalized? If not, I can check that they are the same module 360 or something like that.
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.
and this one fails because some rows in q_23 have negative scalar component, which gets flipped in setter:
assert np.all(q.q == q23)
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.
so... I added a helper function to deal with roll values out of the (0, 360) interval. Perhaps this should be fixed in the class.
I am also checking that q gets flipped when needed.
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 added this test and it is passing. Look OK @javierggt ?
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.
reply to this is below.
Quaternion/tests/test_all.py
Outdated
|
||
def test_normalize(): | ||
a = [[[1., 0., 0., 1.]]] | ||
_ = Quat(q=normalize(a)) |
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.
Need to check the result.
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.
fixed
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.
Mostly there, looks great! I added a few more comments and there were a couple of leftover ones.
- removed gimbal lock values from test quaternions (these might fail for now) - added normalize_angles function to deal with the fact that roll does not appear to be normalized - testing all possibilities of conversions - minor fixes
… code swaped the axes TWICE, once using transform.swapaxes and one with a minus sign in all antisymetric terms
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.
Well, I decided to approve it :)
Sadly, developer is not allowed to review. 😄 I think there is a way to enforce this in GitHub, but we just do this procedurally. You can instead apply the "Ready for final review" label when you think it is finally done. |
Will review on Monday (trying to make time for "science" today). |
Tests updated accordingly. Also improved error reporting in __init__ and make sure argument can be an array of float, not just an array.
assert np.allclose(q.equatorial, eq_23, rtol=0, atol=atol) | ||
assert np.all(q.transform == transform_23) | ||
|
||
|
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.
all these tests were already there:
- The first three assert are in line 131 and on
- the next three (including the angle normalization) are in line 224 and on
- the last three are in line 195 and on
Having them together means the angle normalization is done only once.
While checking them, I realized that these values now do not check for the q flipping any more.
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.
Ah I see, excellent. But it doesn't hurt to have redundant tests, and these are organized in a way that works for my brain. As long as you agree these tests are valid then I'd like to keep them in.
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 ok with that.
@javierggt - is the flipping thing something you can address in a post-merge fix? From my perspective this looks good to merge now. |
I'm ok with merging |
Woohoo! Now on to the docs PR? |
Redo vectorized approach.