-
Notifications
You must be signed in to change notification settings - Fork 56
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
Implement translate_diff
and inv_diff
for all groups at once?
#679
Comments
I think this is a good idea. Right now our definitions are somewhat messy. I will keep this in mind for the next round of group cleanup. |
To me that reads fine as well, we should just be careful, that this is nonbreaking. |
This change is definitely non-breaking. However, if a group stores tangent vectors differently, and the various
|
I would be against the second, since manual error messages have the disadvantage that (compared to a method error) no hints are given in case of a typo. We should then maybe be more careful to minimise the wrong results – for best of cases carefully take into account where that might appear and fix it there? |
The problem here is providing default that work for groups with left-invariant tangent vector representation (basically all our groups except semidirect products), while not giving wrong results for the groups that don't use the left-invariant convention. The alternative to |
There are four solutions, I emphasize the effort to be put and the backward compatibility breaking:
In summary: Solution 1 is the best in the short run. (It is totally ok, as these methods are already missing (and shouldn't), so no one ever uses them anyway. Also: But yes, this is not entirely satisfactory, so one can implement either solutions 2 (very easy) or, solution 3, if one has some extra time to put on this. Solution 4 (or similar) is unavoidable on the very long term, in my opinion: it should be clear and explicit how the tangent vectors are stored. But that is not at all urgent, especially if one chooses solution 2. Does that make sense? |
(In the original post, I forgot about all the various |
More simplifications: when storing tangent vectors as left invariant vector fields, you actually also have the identities, which allow to define log(G, p, q) = log_lie(G, compose(G, inv(G,p), q)) and exp(G, p, X) = compose(G, p, exp_lie(G, X)) (In fact if you look closely at, for instance, the implementation of So the specific implementations of |
This sounds fine to me as well. Could you maybe start implementing this (maybe even implement the idea completely?) and do a PR? |
Sure, I'll give it a shot. |
I think this is a good summary of options. In Manifolds.jl we do consider point and vector storage format as part of the API so (2) would require a breaking release. We just had a breaking release recently so even if we decide to change the representation here, I think in the short term it's better to explore other options. I think (1) is perfectly fine for now. I won't have much time to work on Manifolds.jl for a couple of weeks but I could review your PR. |
the “not having so much time” is also my point here; reviewing a PR is something I can manage – for the rest I am happy if I continue slowly on the PRs I already have started for now. |
I guess another exception to the left-invariance storage is |
I checked to be sure and it looks like we ended up in an inconsistent state somehow. Manifold structure is implemented without left-invariance, but at least part of group code ( |
No until now that was not supposed to be the case. and sure manifold structures are implemented without left invariance in mind, because without a group structure, left invariance is not defined. |
OK. Using a different tangent vector representation for |
Then I am maybe confusing something. As you might have noticed I am not that well-educated yet on Lie groups it seems – I conclude that from the proposal to define |
Sure, I was just asking if you maybe remember something about CircleGroup. Changing implementation of |
No, I do not remember when or what we changed about CircleGroup – and I agree that I prefer the code duplication in favour of also having the manifold without group structure if someone prefers to have that. |
Hang on, |
To me,
The relation between the two is that if you choose any of the Cartan–Schouten connections, then
More generally, the left-invariant storage is exploiting the fact that the Cartan–Schouten connection (the one you call This "storage trick" would in principle work on any manifold equipped with a curvature-free connection: a single vector space is isomorphic to all the tangent spaces, allowing for this efficient storage. |
You're right, this is consistent, I forgot |
The main problem here is, that we do have a trait (decorator) system, and we have a few manifolds where the connection is specified – for this to work consistently and correctly, we would first have to be more rigorous in using a connection trait on all manifolds (and for now we even do not do that completely for the metric). Otherwise this would at least be imprecise behaviour. |
In my opinion, the biggest obstacle is that most connection are not curvature free. This is really a special feature of the Lie groups (and that only works when using either of the two Cartan–Schouten connections, not even a combination of them). |
That is the theoretical one, for sure, but in practice, nearly none of our manifolds has their (default) connection specified, so there it is programatically even worse since you can not check whether you have a metric that fits. |
With regards to solution 4 above, I think it would make sense to set the |
Yes, that would be the most precise (and in my opinion best) way to go :) |
Using |
* Implement `translate_diff` and `inv_diff` for all groups (#679) * implement a general `inv_diff` * fixing the SpecialEuclidean case (mostly) what remains to be fixed is if it is wrapped in a `MetricManifold`, or a `ConnectionManifold`, for instance. In that case, the wrong `translate_diff` methods are called. * changelog * formatting * translate_diff for product/power groups * fix CircleGroup * adjoint_action fallback for all groups * translate_diff is always defined from adjoint_action A vanilla group has no adjoint_action defined * semidirect products: remove specific translate_diff implementations `translate_diff` is now always computed from adjoint_action instead * special_euclidean: implement adjoint action adjoint action was previously not available since not all translate_diff methods were implemented * fix trivial adjoint action for commutative groups implement for LeftAction direction, the other direction is automatic * left invariant storage for special_euclidean this ensures that all group methods are now defined * Generic implementation of exp and log for all groups This is the `exp` and `log` associated to any of the Cartan–Schouten connections. It uses the left-invariant storage of tangent vectors and the specific exp_lie/log_lie implementations. * special_euclidean: Remove specific log/exp implementations These implementations are the one from *group product*, so they are not invariant with respect to the semidirect product. One could put them back in the product_group layer instead. The proper way to invoke them is then `exp(base_manifold(G), ...)` instead of `exp(G, ...)`. Until this is fixed, `exp` now uses more allocations, even when calling it with `base_manifold`. * special_euclidean: Remove some failing tests The failing tests come from using matrices instead of `ArrayPartition`. Using the `ArrayPartition` type (the one returned by `identity_element`) works normally. * special_linear: tighter test points The invariant log fails when points are too far apart. * News update * Formatting * Update NEWS * adjoint_action: more tests more adjoint action methods for CircleGroup * Format * Test: more translate_diff tests * Test: inv_diff! * Tests: adjoint_action - at Identity - remove some unused adjoint_action! implementations * Fromat * Fixup to 402c49b * Redundant method * Doc: adjoint_action direction * Rewrite: avoid inv The implementation is still not optimal * Doc: move code comments to docstrings * Doc: remove allocate TODOs * Doc: storage of tangent vectors on Lie groups * Doc: tangent vector storage -> representation * moving to more weak dependencies * fixes * more fixes * even more fixes * fixes again * turn HybridArrays into an extension * fix path * fix SE exp, log * forgot to add a test dependency * fix for Julia 1.6 * fixing a really weird error * these shouldn't have been re-added * initial support for tangent vector representations in Lie groups * lots of fixes related to vector representation * fix product group * fixing special euclidean * increase coverage * polishing and removing remaining deprecated things * Update NEWS.md Co-authored-by: Ronny Bergmann <git@ronnybergmann.net> * fix a few tests * HybridTangentRepresentation for semidirect product groups, change default for SE(n) * fix allocation issue? * maybe we have fewer ambiguities now * restrict the default left-invariant log and exp on groups to semidirect products for now * improve coverage * rename gvr to vectors * improve coverage * start the group tutorial, remove two `exp` and `log` methods that shouldn't be there * stuff * updates to the group tutorial; exp_inv and log_inv * Update NEWS.md Co-authored-by: Ronny Bergmann <git@ronnybergmann.net> * expand tutorial * fix stuff, improve coverage * fixing tutorial issues and a reference * fixing stuff in groups.qmd * fix table in groups.qmd * remove non-real SymplecticStiefel for now * also remove non-real symplectic Grassmann * Fix qusrto setup and slightly fix alignment in table * yellow circle * Commonmark code stuff no longer necessary. * maybe also enable footnotes * Remove more deprecated things * improve coverage * tests for inv_diff on SE, more robust random point generation on multinomial SPD * exclude line from coverage * improve news and groups tutorial * bump version * would that fix tutorial building? * optimized defaults for inverse_translate_diff! of groups with left-invariant storage * let's solve these ambiguities later --------- Co-authored-by: Olivier Verdier <olivier.verdier@gmail.com> Co-authored-by: Ronny Bergmann <git@ronnybergmann.net>
Here is a suggestion to decrease the amount of code, and improve the user interface of
Manifolds.jl
.I suggest the basic method to be implemented to be the left and right adjoint action. Something like
This has to be implemented for every group (if only the left adjoint action is implemented, there is an easy fallback (can also be made as a test) such as
adjoint_action!(G::MyGroup, Y, p, X, ::RightAction) = adjoint_action!(G, Y, inv(G,p), X, LeftAction())
).Now, the rest is automatic.
adjoint_action(G, p, X)
by allocation and usingadjoin_action!
, something likeThen, remove all the specific instances of
translate_diff
that are implemented (except those with a different convention for storing tangent vectors). That is less code to manage and test.4) and also
(and then all the
apply_diff_group
andapply_diff
for group operation actions come for free, sinceinv_diff
is always defined; it is already implemented this way ingroup.jl
).Benefits:
in the documentation for creating a new group, mention that
adjoint_action
is one of the main method that has to be implemented (with the other main ones, obviously, such ascompose
,lie_bracket
, etc.)People can still overwrite any of the other methods such as
translate_diff
etc. if they want to store tangent vectors in a different wayIf the left invariance seems arbitrary, one can later add a switch (by storing the side of the storage in the
Group
struct). Nothing urgent though, in my opinion.The text was updated successfully, but these errors were encountered: