-
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
Inconsistency with switch_direction
?
#637
Comments
Could you provide a MWE demonstrating the inconsistent behavior? |
Sure: check_action(A::AbstractGroupAction, a, x) = apply(switch_direction(A), a, x) ≈ apply(A, inv(a), x)
rand_check_action(A::AbstractGroupAction) = check_action(A, rand(base_group(A)), rand(group_manifold(A)))
AR = RotationAction(Euclidean(4), SpecialOrthogonal(4))
AG = GroupOperationAction(G)
rand_check_action(AR) # true
rand_check_action(AG) # false |
It's a broader problem than In fact, for |
Good point, I haven't thought about distinguishing all four actions for |
FYI, I will make a PR addressing this issue later this week. |
Brilliant, thank you! |
You would also have to change But, another more interesting possibility is to make
It is even possible to maintain backward compatibility: introduce, say, |
I would like to discuss the design a bit before committing to it. Currently the most reasonable option seems to be to define four actions: abstract type ActionDirection end
struct LeftForwardAction <: ActionDirection end
struct RightForwardAction <: ActionDirection end
struct LeftBackwardAction <: ActionDirection end
struct RightBackwardAction <: ActionDirection end and then for compatibility const LeftAction = Union{LeftForwardAction,LeftBackwardAction}
LeftAction() = LeftForwardAction()
const RightAction = Union{RightForwardAction,RightBackwardAction}
RightAction() = RightBackwardAction() Does it sound good? |
To me that looks good. |
I'm sorry, I have to react to this change. This change makes little sense to me (sorry).
But now there are there four action directions? What would that even mean? For any action other than on a group from itself, the distinction Forward/Backward simply makes no sense at all, does it? Consider this code: V = Euclidean(3)
G = SpecialOrthogonal(3)
A = RotationAction(V,G, RightAction()) Now |
Now you lost me. The change does exactly what you proposed on June 29, so then your post from June 29 does not make sense? And by @mateuszbaran s post |
Hm, it was just easier to keep using
Good point, this is indeed problematic. We previously used |
(Thank you all for your quick responses!)
struct LeftAction <: ActionDirection end
struct RightAction <: ActionDirection end
abstract type GroupActionSide end
struct LeftSide <: GroupActionSide end
struct RightSide <: GroupActionSide end
struct GroupOperationAction{G,AD,SD} <: AbstractGroupAction{AD}
group::G
end
ForwardGroupAction(G::TM, ::TAD=LeftAction()) = GroupOperationAction{TM,TAD,LeftSide}(G)
BackwardGroupAction(G::TM, ::TAD=LeftAction()) = GroupOperationAction{TM,TAD,RightSide}(G)
GroupOperationAction(G, ::LeftAction) = ForwardGroupAction(G, LeftAction())
# possibly deprecate the following call
@deprecate GroupOperationAction(G, ::RightAction) BackwardGroupAction(G, RightAction())
switch_side(::RightSide) = LeftSide
switch_side(::LeftSide) = RightSide
switch_side(A::GroupOperationAction{TM,TAD,RightSide}) = ...
I believe that is not even breaking backward compatibility. Although, personnally, I would go ahead and break compatibility by removing the current What do you think? |
I think it makes sense. I will try to do it as a part of #642 and see if there are any problems. |
Yes, I had missed that, thank you. But look at this simple example: A = RotationAction(Euclidean(3), SpecialOrthogonal(3), RightAction())
A_ = switch_direction(A) Now (Actually, and it pains me to say that, 😭 I would even suggest to roll back this change (#639) for now. The change makes using |
I don't think we can just roll back that change as it would be breaking. I'm going to reduce the scope of #642 a bit though to make it happen sooner. The rigid body dynamics part is very complicated so I will leave it out for later. |
I am not sure it was, since we usually care that we do not have to fix any tests. But what I currently read from this thread, it seems like you do not like the group parts here anyways. And sure, we are not-so-much group experts and the current active team of 2 developers can also only do a finite amount of work. |
Yes, I'm sorry that it takes so long but I'd like to fix this properly and bundle all breaking changes in one release. #642 is essentially in a polishing phase so hopefully it won't take too long. I think it's reasonable to keep using the old version in the meantime. |
I just need to fix some inconsistencies in fiber bundles pointed out by @kellertuer and check docs & code coverage. |
Don't get me wrong, this library is amazing 🤩, and I absolutely ✨love✨ the Lie group part! Besides, as @mateuszbaran says, As to the backward compatibility breaking, here is a very concrete example (and this seriously breaks my code): A = RotationAction(Euclidean(3), SpecialOrthogonal(3), RightAction())
A_ = switch_direction(A)
is_left = A_ isa RotationAction{<:Any, <:Any, LeftAction} Now, (I'm pretty sure this can be quickly fixed, but I would prefer a more robust solution to the underlying problem). |
Thanks for the feedback – with so many errors reported at least I sometimes do confuse a lot of critical feedback with the toolbox not being good (so interprete the critical sometimes as negative – sorry for that). So yes, sorry, I understood you wrong there. Concerning the error – I would not consider that breaking, because you rely heavily on the parameter types and their order of the RotationAction. Sure we should maybe start to export a few things less – but |
We may be misunderstanding each other again: I do not use I just have functions that behave differently if given a left or a right action, and I use multiple dispatch for that. Personal opinion: multiple dispatch should be allowed, and not considered as using an internal API. (Should I really be using Finally, I'm totally, absolutely fine with breaking changes, as long as they make the library better. In my opinion, #639 didn't, hence my reaction. Keep up the good work!! 💪 |
Ah, ok. Well then it might still be something one could consider having a function for to “hide implementation / design detail” or abstract from it. I am also fine with breaking changes, but it should not happen in patch versions (0.8.x) but only when increasing the middle SemVer number (while we are in the 0.x phase). That is what I am not so happy about, that it was breaking in a patch release. |
Let me first clarify a point about left and right actions. From a left action on a manifold, (g,x) ↦ L(g,x), one can always construct a right action, namely: L'(g,x) := L(g⁻¹,x). (A right action can also be transformed into a left action in this manner.)
Now, on a group, there are two distinct actions, stemming from multiplying on the left, or on the right. Put differently, one can say that there are two distinct left actions, L₁, and L₂ defined by L₁(g,g') := g g' and L₂(g,g') := g' g⁻¹. Now, according to the process above, both each give rise to two distinct right actions, namely L₁', and L₂'.
Here comes the inconsistency.
For the
RotationAction
, the result ofswitch_direction
on the action is to map L to L' (whereL
is the rotation action).But for the
GroupOperationAction
, the result ofswitch_direction
is to map L₁ to L₂', instead of mapping L₁ to L₁'.It would perhaps be nice if it was better documented, or, better, fixed to make it consistent?
The text was updated successfully, but these errors were encountered: