Skip to content
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

Merged
merged 30 commits into from
Sep 26, 2019
Merged

Vectorize #5

merged 30 commits into from
Sep 26, 2019

Conversation

jeanconn
Copy link
Contributor

Redo vectorized approach.

Quaternion/Quaternion.py Outdated Show resolved Hide resolved
Quaternion/Quaternion.py Outdated Show resolved Hide resolved
Quaternion/Quaternion.py Outdated Show resolved Hide resolved
Quaternion/Quaternion.py Outdated Show resolved Hide resolved
@jeanconn
Copy link
Contributor Author

jeanconn commented Dec 8, 2016

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.

@jeanconn
Copy link
Contributor Author

jeanconn commented Dec 8, 2016

Needs updated tests.

@jeanconn
Copy link
Contributor Author

jeanconn commented Sep 4, 2019

Move to explicit keywords for the input types (but still supporting the old API for single values supplied as arguments).

@jeanconn
Copy link
Contributor Author

jeanconn commented Sep 7, 2019

Does this also need rebase?

@javierggt
Copy link
Contributor

or merge. What I did in my local copy for now is to merge into master. Otherwise the test does not work.

@taldcroft
Copy link
Member

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.

@javierggt
Copy link
Contributor

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.

@javierggt
Copy link
Contributor

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?

@jeanconn
Copy link
Contributor Author

jeanconn commented Sep 7, 2019

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.

@taldcroft
Copy link
Member

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.

@javierggt
Copy link
Contributor

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.

@taldcroft
Copy link
Member

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.

@javierggt javierggt changed the title Vectorize WIP: Vectorize Sep 7, 2019
Copy link
Member

@taldcroft taldcroft left a 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.

Quaternion/Quaternion.py Show resolved Hide resolved
Quaternion/Quaternion.py Outdated Show resolved Hide resolved
Quaternion/Quaternion.py Outdated Show resolved Hide resolved
Quaternion/Quaternion.py Show resolved Hide resolved
Quaternion/Quaternion.py Outdated Show resolved Hide resolved
Quaternion/Quaternion.py Show resolved Hide resolved
Quaternion/Quaternion.py Show resolved Hide resolved
Quaternion/Quaternion.py Show resolved Hide resolved
@javierggt
Copy link
Contributor

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/Quaternion.py Outdated Show resolved Hide resolved
@javierggt
Copy link
Contributor

javierggt commented Sep 17, 2019

I do not intend to make more changes in this branch. All remaining issues are reported in #10, #11, #12, #13 and #14.

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)
Copy link
Member

Choose a reason for hiding this comment

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

What is this testing?

Copy link
Contributor

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():
Copy link
Member

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)

Copy link
Contributor

@javierggt javierggt Sep 18, 2019

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.

Copy link
Contributor

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)

Copy link
Contributor

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.

Copy link
Member

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 ?

Copy link
Contributor

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.


def test_normalize():
a = [[[1., 0., 0., 1.]]]
_ = Quat(q=normalize(a))
Copy link
Member

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

fixed

Quaternion/tests/test_all.py Outdated Show resolved Hide resolved
Copy link
Member

@taldcroft taldcroft left a 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
Copy link
Contributor

@javierggt javierggt left a 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 :)

@taldcroft
Copy link
Member

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.

@taldcroft
Copy link
Member

Will review on Monday (trying to make time for "science" today).

javierggt and others added 2 commits September 20, 2019 11:51
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)


Copy link
Contributor

@javierggt javierggt Sep 26, 2019

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:

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.

Copy link
Member

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.

Copy link
Contributor

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.

@taldcroft
Copy link
Member

@javierggt - is the flipping thing something you can address in a post-merge fix? From my perspective this looks good to merge now.

@javierggt
Copy link
Contributor

I'm ok with merging

@taldcroft taldcroft merged commit 5b2053f into master Sep 26, 2019
@taldcroft taldcroft deleted the vector branch September 26, 2019 15:12
@taldcroft
Copy link
Member

Woohoo! Now on to the docs PR?

@javierggt javierggt mentioned this pull request Sep 30, 2019
@jeanconn jeanconn mentioned this pull request Oct 11, 2019
@jeanconn jeanconn mentioned this pull request Jan 16, 2020
22 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants