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

Probabilistically correct SO(3) sampling #286

Merged
merged 1 commit into from
Aug 31, 2022

Conversation

brentyi
Copy link
Contributor

@brentyi brentyi commented Aug 29, 2022

Motivation and Context

The current uniform sampling procedure for SO(3) works by:

  1. Uniformly sampling in log/tangent space.
  2. Applying the exponential map.

This would produce a uniform output if the exponential operation were linear, but it's unfortunately not.

As intuition for why there might be something funky afoot:

  • If we consider a subset of the domain of exp_map(omega) where l2_norm(omega) = 2 * pi, all inputs maps to a singleton.
  • If we consider a subset of the domain of exp_map(omega) where l2_norm(omega) = pi /2, the function is injective, and produces a unique rotation for each unique tangent vector.

How Has This Been Tested

Unit tests still pass!

The implementation is also battle-tested:

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have completed my CLA (see CONTRIBUTING)
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 29, 2022
@mhmukadam mhmukadam added the refactor Refactor library components label Aug 30, 2022
Copy link
Contributor

@fantaosha fantaosha left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks for this nice feature!

Copy link
Contributor

@luisenp luisenp left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the nice contribution @brentyi! I have a question for you and @fantaosha. Do we need similar procedures for our other sampling methods? In thinking in particular of randn() and also those in SO2 class.

@fantaosha
Copy link
Contributor

Thanks a lot for the nice contribution @brentyi! I have a question for you and @fantaosha. Do we need similar procedures for our other sampling methods? In thinking in particular of randn() and also those in SO2 class.

No, we don't. This problem only happens to SO3 and SE3. Since SE3.rand() depends on SO3.rand(), we only need to refactor SO3.rand()

@brentyi
Copy link
Contributor Author

brentyi commented Aug 30, 2022

Appreciate the fast review!!

Can confirm that SO2.rand also looks fine, this is much simpler than sampling on SO(3).

I'm wondering for SO2.randn and SO3.randn: these look correct if the goal is to sample from some zero-mean unit-covariance tangent-space Gaussians, but what is that actually used for? With Gaussians in Euclidean spaces randn ~ N(0, I) is a reasonable abstraction because a mean/covariance can be imposed by scaling shifting/scaling sampled vectors, but this doesn't seem to extend in a principled way to the SO2/SO3 cases.

Copy link
Member

@mhmukadam mhmukadam left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution, @brentyi.

@mhmukadam
Copy link
Member

for SO2.randn and SO3.randn ... what is that actually used for?

Good question. For now I think we mostly use it in unit tests but I imagine it could be used to sample say a random (group) trajectory as input to some optimization problem. You are right the current Gaussian sampling is in tangent space. Maybe @fantaosha can expand on any other general use case where what we have currently is insufficient.

@fantaosha
Copy link
Contributor

fantaosha commented Aug 30, 2022

for SO2.randn and SO3.randn ... what is that actually used for?

Good question. For now I think we mostly use it in unit tests but I imagine it could be used to sample say a random (group) trajectory as input to some optimization problem. You are right the current Gaussian sampling is in tangent space. Maybe @fantaosha can expand on any other general use case where what we have currently is insufficient.

Hi @brentyi, as @mhmukadam said, rand() and randn() originally referred to the random generators used to sample the tangent space of the identity. Honestly, we didn't consider any specific geometric meaning of uniform or normal distribution on Lie groups. However, we are happy to refactor randn() as what you have contributed to rand(). Thanks!

@mhmukadam mhmukadam merged commit cca7362 into facebookresearch:main Aug 31, 2022
suddhu pushed a commit to suddhu/theseus that referenced this pull request Jan 21, 2023
@empet
Copy link

empet commented Aug 22, 2023

Searching the web to find out where the Shoemake method of sampling uniformly from the group of unit quaternions is implemented, I stumpled upon this thread, "Probabilistically correct SO(3) sampling". On math.stackexchange there is an unanswered question related to the correctness of the Shoemake algorithm that was implemented here by @brentyi. We'd be grateful if you could explain what led you to admit that the algorithm samples uniformly a unit quaternion (and as a consequence an element in SO(3)).

@brentyi
Copy link
Contributor Author

brentyi commented Aug 23, 2023

Hi!

Two links that might be of interest to you are:

@empet
Copy link

empet commented Aug 23, 2023

The presentation from the web archive link refers to the Shoemake paper, [883], which is incriminated on math.stackexchange.
In addition, it is explained in a blog style what Hopf fibration is, without shedding more light on Shoemake's approach.

EIGEN just implements operations on quaternions, including the Shoemake method of uniform sampling from SO(3).
Unfortunately a rigurous explanation of this method is still lacking. Just read the quoted text from math.stackexchange and try to understand it and perform the product of the two quaternions involved there. Comparing with the Shoemake result you'll see that it was considered that the sum of two independent uniform random variables is also uniformly distributed, which is FALSE.
Thank you for trying to give links you considered to be more convincing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. refactor Refactor library components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants