Closed kellertuer closed 9 months ago
Defining variant with t
is, for some manifolds, important for performance. So, either the variant with t
is the fallback one or for some manifolds we need to define both variants to make everything work. I don't really mind having to implement both but I think it would be good to be aware of the tradeoff.
I am aware of the performance effects of the t-variant on some manifolds, it is just not so easy for the beginner to directly understand which function to implement (not yet why, just to find the right one).
Maybe we could to the same as for exp? By default retract_method!
with t
falls back to the one without? That way it's easy for the user to implement.
This would mean that an advanced user has to either implement both variants (if the plain one does not yet exist) or add the one with t.
...unless we find a good way to “switch” which functions dispatches on which.
I also would not mind to implement both to get the performance effects, while just implementing the one without t is easy and works?
OK, that would be fine.
Performance aware people could even do
retract_method!(M, q, p, X) = retract_method!(M, q, p, X, t)
(which per se would introduce a circle but then) implement retract_method!(M, q, p, X, t)
. I think this one additional line can be expected of experts already caring much about performance, while this switch makes it much easier for beginners :)
On the other hand this decision means, we have to add layer 2 (the _retract
dispatches) for all retractions and the none-t variants. That is a bit of boilerpplate code, but I think worth it for usability.
I think I now what to do to get this done. But sure this is then breaking and something for 0.15.
as noted in #158, I saw that currently our default dispatch for
exp
andretract
differ, when it comes to treating the last positional argumentt
. Here I would like to give a thorough overview about the state and think/discuss about the solutionexp and retract
exp
follows the scheme “allocate first”, i.e.both with and withoutt
they allocate and “pass over” toexp!
retract
differs asretract(M, p, X, m)
callsretract(M, p, X, 1.0, m)
retractM, p, t, m)
passes to_retract
(level 2) which dispatches on the method andretract_method
allocates and callsretract_method!
– but they do not exist withoutt
.exp! and retract!
We have that
So
exp!
fusest
andX
by default. This is nice for the user since implementingexp!(M, q, p, X)
is all they need to do, no need to think aboutt
.For
retract
this is the other way around.retract!(M, q, p, X, m)
adds1.0
as second to last element, i.e. callsretract!(M::AbstractManifold, q, p, X, t::Number, method)
– and this passes down to level 2 and 3 –_retract!
andretract_method!
, which never exist withoutt
.Summary
exp
it is necessary to implementexp!(M, q, p, X)
and nice (maybe speedup?) to implementexp!(M, q, p, X, t)
, but this method alone is not enough.retract
it is necessary to implementretract_method!(M, q, p, X, t)
, implementing the one withoutt
is not possible.Own opinion
I feel that
exp!
is nice the way it is and an easy entry level. I feel thatretract!
compared to that is a bit unexpected. So I would prefer to keepexp
as is; maybe if there is a way to keep the current state and that alsoexp!(M, q, p, X, t)
alone would suffice, that would be the most neat oneMaybe this would also be the best for retract – but I have no good idea how to accomplish that either of them would suffice. This would at least mean that the “without
t
”variant has to dispatch through level 2 and 3 (a bit more of boiler plate code).