JuliaManifolds / Manifolds.jl

Manifolds.jl provides a library of manifolds aiming for an easy-to-use and fast implementation.
https://juliamanifolds.github.io/Manifolds.jl
MIT License
376 stars 55 forks source link

DomainError with ExponentialRetraction with `mean` of SE2 #483

Closed Affie closed 2 years ago

Affie commented 2 years ago

Hi, I'm upgrading code to v0.8 and get a DomainError, here is a minimum example:

julia> using Manifolds

julia> p1 = ProductRepr([0.0,0.0], [1.0 0.0; 0.0 1.0])
ProductRepr with 2 submanifold components:
 Component 1 =
  2-element Vector{Float64}:
   0.0
   0.0
 Component 2 =
  2×2 Matrix{Float64}:
   1.0  0.0
   0.0  1.0

julia> p2 = ProductRepr([0.0,0.0], [0.0 -1.0; 1.0 0.0])
ProductRepr with 2 submanifold components:
 Component 1 =
  2-element Vector{Float64}:
   0.0
   0.0
 Component 2 =
  2×2 Matrix{Float64}:
   0.0  -1.0
   1.0   0.0

julia> M = SpecialEuclidean(2)
SpecialEuclidean(2)

julia> mean(M, [p1,p2])
ERROR: DomainError with ExponentialRetraction():
You can not use the exponential map as an inner method to solve the ode for the exponential map.
Stacktrace:
  [1] ODEExponentialRetraction(r::ExponentialRetraction, #unused#::DefaultOrthonormalBasis{ℝ, ManifoldsBase.TangentSpaceType})
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/L10sL/src/retractions.jl:93
  [2] ODEExponentialRetraction(r::ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/L10sL/src/retractions.jl:82
  [3] exp!(#unused#::ManifoldsBase.TraitList{IsMetricManifold, ManifoldsBase.TraitList{HasBiinvariantMetric, ManifoldsBase.TraitList{HasLeftInvariantMetric, ManifoldsBase.TraitList{HasRightInvariantMetric, ManifoldsBase.TraitList{IsDefaultMetric{EuclideanMetric}, ManifoldsBase.TraitList{IsMetricManifold, ManifoldsBase.TraitList{IsDefaultConnection{LeviCivitaConnection}, ManifoldsBase.TraitList{IsConnectionManifold, ManifoldsBase.TraitList{ManifoldsBase.IsExplicitDecorator, ManifoldsBase.EmptyTrait}}}}}}}}}, M::TranslationGroup{Tuple{2}, ℝ}, q::Vector{Float64}, p::Vector{Float64}, X::Vector{Float64})
    @ Manifolds ~/.julia/packages/Manifolds/wpEil/src/manifolds/MetricManifold.jl:257
  [4] exp! (repeats 2 times)
    @ ~/.julia/packages/ManifoldsBase/L10sL/src/nested_trait.jl:282 [inlined]
  [5] exp!
    @ ~/.julia/packages/ManifoldsBase/L10sL/src/nested_trait.jl:275 [inlined]
  [6] map
    @ ./tuple.jl:266 [inlined]
  [7] exp!(M::ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, q::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, p::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, X::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}})
    @ Manifolds ~/.julia/packages/Manifolds/wpEil/src/manifolds/ProductManifold.jl:394
  [8] _retract!(M::ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, q::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, p::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, X::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, #unused#::ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/L10sL/src/retractions.jl:636
  [9] retract!(M::ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, q::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, p::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, X::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, m::ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/L10sL/src/retractions.jl:619
 [10] retract!
    @ ~/.julia/packages/ManifoldsBase/L10sL/src/nested_trait.jl:308 [inlined]
 [11] retract! (repeats 2 times)
    @ ~/.julia/packages/ManifoldsBase/L10sL/src/nested_trait.jl:282 [inlined]
 [12] retract!
    @ ~/.julia/packages/ManifoldsBase/L10sL/src/nested_trait.jl:275 [inlined]
 [13] retract!
    @ ~/.julia/packages/ManifoldsBase/L10sL/src/nested_trait.jl:291 [inlined]
 [14] retract! (repeats 3 times)
    @ ~/.julia/packages/ManifoldsBase/L10sL/src/nested_trait.jl:282 [inlined]
 [15] retract!
    @ ~/.julia/packages/ManifoldsBase/L10sL/src/nested_trait.jl:275 [inlined]
 [16] retract!
    @ ~/.julia/packages/ManifoldsBase/L10sL/src/retractions.jl:629 [inlined]
 [17] mean!(M::GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, y::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, x::Vector{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}}, w::StatsBase.UnitWeights{Float64}, ::GradientDescentEstimation; p0::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, stop_iter::Int64, retraction::ExponentialRetraction, inverse_retraction::LogarithmicInverseRetraction, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Manifolds ~/.julia/packages/Manifolds/wpEil/src/statistics.jl:387
 [18] mean!
    @ ~/.julia/packages/Manifolds/wpEil/src/statistics.jl:365 [inlined]
 [19] #mean!#146
    @ ~/.julia/packages/Manifolds/wpEil/src/statistics.jl:349 [inlined]
 [20] mean!
    @ ~/.julia/packages/Manifolds/wpEil/src/statistics.jl:348 [inlined]
 [21] #mean#144
    @ ~/.julia/packages/Manifolds/wpEil/src/statistics.jl:308 [inlined]
 [22] mean(M::GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, x::Vector{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}}, method::GradientDescentEstimation) (repeats 2 times)
    @ Manifolds ~/.julia/packages/Manifolds/wpEil/src/statistics.jl:307
 [23] top-level scope
    @ REPL[11]:1
kellertuer commented 2 years ago

To me it looks like we might have missed to make the translation group transparent w.r.t. exp, i.e. that it passes exp – which is here just + – down to Euclidean. Will take a look.

kellertuer commented 2 years ago

First addition, no my first assumption was wrong, since

M = TranslationGroup(2)
p = [2,0]
X = [1,0]
exp(M,p,X)
retract(M, p, X, ExponentialRetraction())

both last lines work fine. The very last one – on a MetricManifold might fall back to calling the ODE solver, which is what errors for you, since to approximate the Exponential map using a retraction, one can not use exp as a retraction.

edit: Uh! Narrowed it down, its not exp, it's exp! in the above code calling

 exp!(M,q,p,X)

fails. So now we at least have a minimal erroring example.

kellertuer commented 2 years ago

Found the culprit, as you can see in the PR. Up to one general point (which is just a short general discussion and maybe moving that one new function definition further up in the manifold Hierarchy), this should be available soon.

kellertuer commented 2 years ago

Maybe a little longer explanation. The old system of AbstractGroupManifold and AbstractMetricManifold and all these was changed to a more flexible (completely TTHT based) system of a list of traits one can attach to a manifold.

The TranslationGroup itself got a BiInvariant Metric trait and EuclideanMetric as its default metric (if no other is given using MetricManifold). But it also inherited all traits from Euclidean before finally IsExplicitDecorator is kind of a “catch-all” trait that passes all functions that were not handled further down to Euclidean itself.

This works really nicely in general with exp! as the really only exception, since for exp! with a IsMetricManifold decorator we have a fallback to solving the corresponding ODE (for the geodesic/exp) as long as you can specify a retraction that is not ExponentialRetration itself on a MetricManifold. This solver itself is called the ODEExponentialRetraction(r) retraction, where r is the nice/new default_retraction(M). This is - without surprise – ExponentialRetraction() for M=Euclidean.

And this is how we got to that error. The fix is, that exp! for TranslationGroup now just gets the IsExplicitDecorator trait and hence directly passes down to Euclidean. And the one thing to discuss is, whether we should do this for all group manifolds maybe.

Besides that: I grew quite fond of the new system we came up with, since it is more flexible, reasonable to read (In your StackTrance [3]. you can see that the exp for an IsMetricManifold is what is considered and that tries to start the ODE solver).

Affie commented 2 years ago

Thank you very much for the quick fix. The original issue is fixed, however, It looks like exp! is still not working on the SE group:

julia> using Manifolds

julia> p = ProductRepr([0.0,0.0], [1.0 0.0; 0.0 1.0])
ProductRepr with 2 submanifold components:
 Component 1 =
  2-element Vector{Float64}:
   0.0
   0.0
 Component 2 =
  2×2 Matrix{Float64}:
   1.0  0.0
   0.0  1.0

julia> X = ProductRepr([0.0,0.0], [0.0 0.1; -0.1 0.0])
ProductRepr with 2 submanifold components:
 Component 1 =
  2-element Vector{Float64}:
   0.0
   0.0
 Component 2 =
  2×2 Matrix{Float64}:
    0.0  0.1
   -0.1  0.0

julia> M = SpecialEuclidean(2)
SpecialEuclidean(2)

julia> exp(M, p, X)
ProductRepr with 2 submanifold components:
 Component 1 =
  2-element Vector{Float64}:
   0.0
   0.0
 Component 2 =
  2×2 Matrix{Float64}:
    0.995004   0.0998334
   -0.0998334  0.995004

julia> exp!(M, p, p, X)
ERROR: DomainError with ExponentialRetraction():
You can not use the exponential map as an inner method to solve the ode for the exponential map.
Stacktrace:
 [1] ODEExponentialRetraction(r::ExponentialRetraction, #unused#::DefaultOrthonormalBasis{ℝ, ManifoldsBase.TangentSpaceType})
   @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:93
 [2] ODEExponentialRetraction(r::ExponentialRetraction)
   @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:82
 [3] exp!(#unused#::ManifoldsBase.TraitList{IsMetricManifold, ManifoldsBase.TraitList{ManifoldsBase.IsExplicitDecorator, ManifoldsBase.EmptyTrait}}, M::GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, q::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, p::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, X::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}})
   @ Manifolds ~/.julia/packages/Manifolds/G5bzq/src/manifolds/MetricManifold.jl:257
 [4] exp! (repeats 2 times)
   @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:282 [inlined]
 [5] exp!(M::GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, q::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, p::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, X::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}})
   @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:275
 [6] top-level scope
   @ REPL[19]:1

I didn't know if I should open a new issue as it looks related.

kellertuer commented 2 years ago

So we might have missed another case, ah for the specific GroupManifold. I have to check (maybe tonight after my travels), but adapting the same traits as we just did for the previous error should to the trick here as well.

mateuszbaran commented 2 years ago

SE(n) is more complicated. I think we haven't decided yet whether we want the product metric or the left-invariant metric by default. Which one is more important for you?

Affie commented 2 years ago

We also use RealCircleGroup and it has the same issue.

Affie commented 2 years ago

SE(n) is more complicated. I think we haven't decided yet whether we want the product metric or the left-invariant metric by default. Which one is more important for you?

If I understand it correctly, I think the left-invariant metric. Perhaps @dehann can confirm.

mateuszbaran commented 2 years ago

We also use RealCircleGroup and it has the same issue.

That's simple, I'll fix it today.

Affie commented 2 years ago

I have a somewhat related question: With the updated trait system, should we use retract! with ExponentialRetraction() as opposed to exp! I guess it's more general in any case? We currently only (or mostly) use exp and log

Affie commented 2 years ago

Note that retract! works where exp! gives an error:

julia> using Manifolds

julia> p = [1.0]
1-element Vector{Float64}:
 1.0

julia> X = [0.1]
1-element Vector{Float64}:
 0.1

julia> M = RealCircleGroup()
RealCircleGroup()

julia> retract!(M, p, p, X, ExponentialRetraction())
1-element Vector{Float64}:
 1.1

julia> exp!(M, p, p, X)
ERROR: DomainError with ExponentialRetraction():
You can not use the exponential map as an inner method to solve the ode for the exponential map.
Stacktrace:
 [1] ODEExponentialRetraction(r::ExponentialRetraction, #unused#::DefaultOrthonormalBasis{ℝ, ManifoldsBase.TangentSpaceType})
   @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:93
 [2] ODEExponentialRetraction(r::ExponentialRetraction)
   @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:82
 [3] exp!(#unused#::ManifoldsBase.TraitList{IsMetricManifold, ManifoldsBase.TraitList{HasBiinvariantMetric, ManifoldsBase.TraitList{HasLeftInvariantMetric, ManifoldsBase.TraitList{HasRightInvariantMetric, ManifoldsBase.TraitList{ManifoldsBase.IsExplicitDecorator, ManifoldsBase.EmptyTrait}}}}}, M::RealCircleGroup, q::Vector{Float64}, p::Vector{Float64}, X::Vector{Float64})
   @ Manifolds ~/.julia/packages/Manifolds/G5bzq/src/manifolds/MetricManifold.jl:257
 [4] exp! (repeats 2 times)
   @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:282 [inlined]
 [5] exp!(M::RealCircleGroup, q::Vector{Float64}, p::Vector{Float64}, X::Vector{Float64})
   @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:275
 [6] top-level scope
   @ REPL[13]:1
mateuszbaran commented 2 years ago

exp!(M, p, p, X) not working is a bug (it will be fixed by #486). retract! is more general but you should use exp!(M, p, p, X) instead of retract!(M, p, p, X, ExponentialRetraction()).

dehann commented 2 years ago

SE(n) is more complicated. I think we haven't decided yet whether we want the product metric or the left-invariant metric by default. Which one is more important for you?

I think the left-invariant metric. Perhaps dehann can confirm.

As I understand, left-invariant is more important for us, however, I'm not yet able to complete foresee how the difference would effect us. My sense is to stay with the usual Lie Group / Algebra definitions (which is the way we are using it). Don't believe I have ever used Lie Groups under product invariant mechanization before. I probably need to learn more about the distinction in this context to give a better answer.

kellertuer commented 2 years ago

I'm not yet able to complete foresee how the difference would effect us

Don't worry, it would not affect you much, either metric can always be used with the MetricManifold(Manifold,Metric) scheme, just that Manifold itself will default to using the one we specify. My favourite would maybe be the left invariant since we are tiling about Lie groups here?

mateuszbaran commented 2 years ago

OK, left-invariant definitely makes sense.

It's possible to write a relatively generic code for left-invariant metrics on Lie groups but for SE(2) and SE(3) it would be nice to have optimized implementations. @dehann are you aware of some existing implementations we could copy here?

mateuszbaran commented 2 years ago

I've encounter a tricky issue. By giving SpecialEuclidean the left-invariant metric we need to adjust get_vector and get_coordinates so that they also respect orthogonality and orthonormality in the new metric. The easiest way to solve it is by transporting vectors to and from identity. Which is a significant departure from what we currently do so I'm not entirely sure if that's something we want.

dehann commented 2 years ago

My favourite would maybe be the left invariant since we are [talking] about Lie groups here?

OK, left-invariant definitely makes sense.

By giving SpecialEuclidean the left-invariant metric we need to adjust get_vector and get_coordinates so that they also respect orthogonality and orthonormality in the new metric. The easiest way to solve it is by transporting vectors to and from identity.

hmm, so I'm barely keeping up... This sounds like going for left-nvariant may have a performance implication, and we'd rather avoid bottlenecks for the sake of speed.

Don't worry, it would not affect you much, either metric can always be used with the MetricManifold(Manifold,Metric) scheme, just that Manifold itself will default to using the one we specify.

I'd say ignore my input on Product metric vs left-invariant metric decision (my knowledge likely too limited to help). Perhaps reduce scope of my input to "i'd vote for speed on SE(2) since we will be using that excessively in hot-loops".

It's possible to write a relatively generic code for left-invariant metrics on Lie groups but for SE(2) and SE(3) it would be nice to have optimized implementations.

If there is a performance implication on the decision between metrics, is this maybe one of those trade-off cases where either, general == slower, vs focused solution == better performance?

relatively generic code for left-invariant metrics @dehann are you aware of some existing implementations we could copy here?

Unfortunately no, not immediately.

[generic left invariant changes to get_vector, get_coordinates].. is a significant departure from what we currently do so I'm not entirely sure if that's something we want.

I'm a little nervous about pushing for one or the other option that results in bigger changes being made ... and then later as I learn more discover it was the wrong decision. The best hedge I can come up with (before learning more) is go for a simple focused implementation for speed that uses dispatch properly. And let the more "general flexibility" grow via Julia's multiple dispatch as the use-cases arrive.

My homework is to go get sharp on left-invariant vs. product metric to be useful on this topic in the future. So I'm starting by reading this:

also respect orthogonality and orthonormality in the new metric.

think I'm still following with that part, but I don't feel crisp about original question and fundamental choice between product vs left-invariant metric choice.

mateuszbaran commented 2 years ago

hmm, so I'm barely keeping up... This sounds like going for left-nvariant may have a performance implication, and we'd rather avoid bottlenecks for the sake of speed.

For SE(n) probably what we currently do is correct and there would be no performance implication but I'll have to check. It doesn't look correct for arbitrary semisimple products of Lie groups though.

Don't worry, it would not affect you much, either metric can always be used with the MetricManifold(Manifold,Metric) scheme, just that Manifold itself will default to using the one we specify.

I'd say ignore my input on Product metric vs left-invariant metric decision (my knowledge likely too limited to help). Perhaps reduce scope of my input to "i'd vote for speed on SE(2) since we will be using that excessively in hot-loops".

I definitely want to support both metrics and have both as fast as possible :slightly_smiling_face: .

If there is a performance implication on the decision between metrics, is this maybe one of those trade-off cases where either, general == slower, vs focused solution == better performance?

Yes, exactly. We should have focused implementations for SE(2) and SE(3) though so you shouldn't worry too much -- it's just a matter of writing some specialized methods.

Unfortunately no, not immediately.

That's OK, I will work on that then.

I'm a little nervous about pushing for one or the other option that results in bigger changes being made ... and then later as I learn more discover it was the wrong decision. The best hedge I can come up with (before learning more) is go for a simple focused implementation for speed that uses dispatch properly. And let the more "general flexibility" grow via Julia's multiple dispatch as the use-cases arrive.

Yes, sure, we can start with focused implementations.

My homework is to go get sharp on left-invariant vs. product metric to be useful on this topic in the future. So I'm starting by reading this:

That's way too general for our case here. We are talking about invariance as defined here: https://idv.sinica.edu.tw/ftliang/diff_geom/*diff_geometry(II)/4.08/lie_group_curvature.pdf .

Affie commented 2 years ago

EDIT: Ignore this one as the next two comments shows the issue better

I got another similar error, I'm still trying to figure out if it's a new error or related, I'll post an MWE as soon as I trace down the issue, but here is the stack trace in the meantime.

ERROR: DomainError with ManifoldsBase.ExponentialRetraction():
You can not use the exponential map as an inner method to solve the ode for the exponential map.
Stacktrace:
  [1] ManifoldsBase.ODEExponentialRetraction(r::ManifoldsBase.ExponentialRetraction, #unused#::ManifoldsBase.DefaultOrthonormalBasis{ℝ, ManifoldsBase.TangentSpaceType})
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:93
  [2] ManifoldsBase.ODEExponentialRetraction(r::ManifoldsBase.ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:82
  [3] exp!(#unused#::ManifoldsBase.TraitList{Manifolds.IsMetricManifold, ManifoldsBase.TraitList{ManifoldsBase.IsExplicitDecorator, ManifoldsBase.EmptyTrait}}, M::Manifolds.GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{Manifolds.RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, Manifolds.LeftAction}}}, q::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, p::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, X::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}})
    @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/manifolds/MetricManifold.jl:257
  [4] exp! (repeats 2 times)
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:282 [inlined]
  [5] exp!
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:275 [inlined]
  [6] map
    @ ./tuple.jl:266 [inlined]
  [7] exp!(M::ProductManifold{ℝ, Tuple{Manifolds.GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{Manifolds.RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, Manifolds.LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, q::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, p::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, X::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}})
    @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/manifolds/ProductManifold.jl:394
  [8] _retract!(M::ProductManifold{ℝ, Tuple{Manifolds.GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{Manifolds.RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, Manifolds.LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, q::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, p::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, X::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, #unused#::ManifoldsBase.ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:636
  [9] retract!(M::ProductManifold{ℝ, Tuple{Manifolds.GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{Manifolds.RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, Manifolds.LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, q::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, p::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, X::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, m::ManifoldsBase.ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:619
 [10] retract!
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:308 [inlined]
 [11] retract! (repeats 2 times)
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:282 [inlined]
 [12] retract!
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:275 [inlined]
 [13] retract!
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:291 [inlined]
 [14] retract! (repeats 3 times)
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:282 [inlined]
 [15] retract!
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:275 [inlined]
 [16] retract!(M::Manifolds.ProductGroup{ℝ, Tuple{Manifolds.GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{Manifolds.RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, Manifolds.LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, q::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, p::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, X::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, t::Float64, method::ManifoldsBase.ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:629
 [17] mean!(M::Manifolds.ProductGroup{ℝ, Tuple{Manifolds.GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{Manifolds.RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, Manifolds.LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, y::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, x::Vector{ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}}, w::StatsBase.UnitWeights{Float64}, ::Manifolds.GradientDescentEstimation; p0::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, stop_iter::Int64, retraction::ManifoldsBase.ExponentialRetraction, inverse_retraction::ManifoldsBase.LogarithmicInverseRetraction, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:389
 [18] mean!
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:367 [inlined]
 [19] mean(M::Manifolds.ProductGroup{ℝ, Tuple{Manifolds.GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{Manifolds.RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, Manifolds.LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, x::Vector{ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}}, w::StatsBase.UnitWeights{Float64}, method::Manifolds.GradientDescentEstimation; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:320
 [20] mean
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:319 [inlined]
 [21] #mean_and_var#173
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:987 [inlined]
 [22] #mean_and_var#174
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:1000 [inlined]
 [23] mean_and_var(M::Manifolds.ProductGroup{ℝ, Tuple{Manifolds.GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{Manifolds.RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, Manifolds.LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, x::Vector{ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}}, method::Manifolds.GradientDescentEstimation) (repeats 2 times)
    @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:998
 [24] #var#171
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:940 [inlined]
 [25] var
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:940 [inlined]
 [26] std(M::Manifolds.ProductGroup{ℝ, Tuple{Manifolds.GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{Manifolds.RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, Manifolds.LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, args::Vector{ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:958
 [27] std
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:958 [inlined]
 [28] #std#9
    @ ~/.julia/dev/IncrementalInference/src/VariableStatistics.jl:5 [inlined]
 [29] std
    @ ~/.julia/dev/IncrementalInference/src/VariableStatistics.jl:5 [inlined]
 [30] calcStdBasicSpread(vartype::DynPose2, ptsArr::Vector{ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}})
    @ IncrementalInference ~/.julia/dev/IncrementalInference/src/VariableStatistics.jl:14
 [31] evalPotentialSpecific(Xi::Vector{DFGVariable{DynPose2}}, ccwl::CommonConvWrapper{DynPose2VelocityPrior{FullNormal, FullNormal}, Nothing, Vector{Int64}, NamedTuple{(:x0,), Tuple{Vector{Any}}}, Nothing, ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, Nothing}, solvefor::Symbol, T_::Type{DynPose2VelocityPrior{FullNormal, FullNormal}}, measurement::Vector{Tuple}; needFreshMeasurements::Bool, solveKey::Symbol, N::Int64, dbg::Bool, spreadNH::Float64, inflateCycles::Int64, nullSurplus::Float64, skipSolve::Bool, _slack::Nothing)
    @ IncrementalInference ~/.julia/dev/IncrementalInference/src/services/EvalFactor.jl:433
 [32] #evalPotentialSpecific#342
    @ ~/.julia/dev/IncrementalInference/src/services/EvalFactor.jl:511 [inlined]
 [33] evalFactor(dfg::GraphsDFG{SolverParams, DFGVariable, DFGFactor}, fct::DFGFactor{CommonConvWrapper{DynPose2VelocityPrior{FullNormal, FullNormal}, Nothing, Vector{Int64}, NamedTuple{(:x0,), Tuple{Vector{Any}}}, Nothing, ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, Nothing}, 1}, solvefor::Symbol, measurement::Vector{Tuple}; needFreshMeasurements::Bool, solveKey::Symbol, N::Int64, inflateCycles::Int64, nullSurplus::Float64, dbg::Bool, skipSolve::Bool, _slack::Nothing)
    @ IncrementalInference ~/.julia/dev/IncrementalInference/src/services/EvalFactor.jl:550
 [34] approxConvBelief(dfg::GraphsDFG{SolverParams, DFGVariable, DFGFactor}, fc::DFGFactor{CommonConvWrapper{DynPose2VelocityPrior{FullNormal, FullNormal}, Nothing, Vector{Int64}, NamedTuple{(:x0,), Tuple{Vector{Any}}}, Nothing, ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, Nothing}, 1}, target::Symbol, measurement::Vector{Tuple}; solveKey::Symbol, N::Int64, nullSurplus::Float64, skipSolve::Bool)
    @ IncrementalInference ~/.julia/dev/IncrementalInference/src/services/ApproxConv.jl:18
 [35] #calcProposalBelief#352
    @ ~/.julia/dev/IncrementalInference/src/services/ApproxConv.jl:164 [inlined]
 [36] proposalbeliefs!(dfg::GraphsDFG{SolverParams, DFGVariable, DFGFactor}, destlbl::Symbol, factors::Vector{DFGFactor{CommonConvWrapper{DynPose2VelocityPrior{FullNormal, FullNormal}, Nothing, Vector{Int64}, NamedTuple{(:x0,), Tuple{Vector{Any}}}, Nothing, ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, Nothing}, 1}}, dens::Vector{ManifoldKernelDensity}, measurement::Vector{Tuple}; solveKey::Symbol, N::Int64, nullSurplusAdd::Float64, dbg::Bool)
    @ IncrementalInference ~/.julia/dev/IncrementalInference/src/services/ApproxConv.jl:247
 [37] propagateBelief(dfg::GraphsDFG{SolverParams, DFGVariable, DFGFactor}, destvar::DFGVariable{DynPose2}, factors::Vector{DFGFactor{CommonConvWrapper{DynPose2VelocityPrior{FullNormal, FullNormal}, Nothing, Vector{Int64}, NamedTuple{(:x0,), Tuple{Vector{Any}}}, Nothing, ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, Nothing}, 1}}; solveKey::Symbol, dens::Vector{ManifoldKernelDensity}, N::Int64, needFreshMeasurements::Bool, dbg::Bool, logger::Logging.ConsoleLogger)
    @ IncrementalInference ~/.julia/dev/IncrementalInference/src/GraphProductOperations.jl:30
 [38] doautoinit!(dfg::GraphsDFG{SolverParams, DFGVariable, DFGFactor}, xi::DFGVariable{DynPose2}; solveKey::Symbol, singles::Bool, N::Int64, logger::Logging.ConsoleLogger)
    @ IncrementalInference ~/.julia/dev/IncrementalInference/src/services/GraphInit.jl:126
 [39] #doautoinit!#25
    @ ~/.julia/dev/IncrementalInference/src/services/GraphInit.jl:160 [inlined]
 [40] doautoinit!(dfg::GraphsDFG{SolverParams, DFGVariable, DFGFactor}, Xi::Vector{DFGVariable{DynPose2}})
    @ IncrementalInference ~/.julia/dev/IncrementalInference/src/services/GraphInit.jl:156
 [41] top-level scope
    @ REPL[10]:1
Affie commented 2 years ago

It looks related here is a simpler test:


julia> M = ProductGroup(ProductManifold(SpecialEuclidean(2), TranslationGroup(2)))
ProductGroup with 2 subgroups:
 SpecialEuclidean(2)
 TranslationGroup(2; field = ℝ)

julia> p1 = ProductRepr(ProductRepr([0;0.0],[1 0; 0 1.0]),[0;0.0])
ProductRepr with 2 submanifold components:
 Component 1 =
  ProductRepr with 2 submanifold components:
   Component 1 =
    2-element Vector{Float64}:
     0.0
     0.0
   Component 2 =
    2×2 Matrix{Float64}:
     1.0  0.0
     0.0  1.0
 Component 2 =
  2-element Vector{Float64}:
   0.0
   0.0

julia> p2 = ProductRepr(ProductRepr([0;0.0],[0.0 -1.0; 1.0 0.0]),[0;0.0])
ProductRepr with 2 submanifold components:
 Component 1 =
  ProductRepr with 2 submanifold components:
   Component 1 =
    2-element Vector{Float64}:
     0.0
     0.0
   Component 2 =
    2×2 Matrix{Float64}:
     0.0  -1.0
     1.0   0.0
 Component 2 =
  2-element Vector{Float64}:
   0.0
   0.0

julia> mean(M, [p1,p2])
ERROR: DomainError with ExponentialRetraction():
You can not use the exponential map as an inner method to solve the ode for the exponential map.
Stacktrace:
  [1] ODEExponentialRetraction(r::ExponentialRetraction, #unused#::DefaultOrthonormalBasis{ℝ, ManifoldsBase.TangentSpaceType})
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:93
  [2] ODEExponentialRetraction(r::ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:82
  [3] exp!(#unused#::ManifoldsBase.TraitList{IsMetricManifold, ManifoldsBase.TraitList{ManifoldsBase.IsExplicitDecorator, ManifoldsBase.EmptyTrait}}, M::GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, q::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, p::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, X::ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}})
    @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/manifolds/MetricManifold.jl:257
  [4] exp! (repeats 2 times)
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:282 [inlined]
  [5] exp!
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:275 [inlined]
  [6] map
    @ ./tuple.jl:266 [inlined]
  [7] exp!(M::ProductManifold{ℝ, Tuple{GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, q::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, p::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, X::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}})
    @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/manifolds/ProductManifold.jl:394
  [8] _retract!(M::ProductManifold{ℝ, Tuple{GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, q::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, p::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, X::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, #unused#::ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:636
  [9] retract!(M::ProductManifold{ℝ, Tuple{GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, q::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, p::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, X::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, m::ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:619
 [10] retract!
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:308 [inlined]
 [11] retract! (repeats 2 times)
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:282 [inlined]
 [12] retract!
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:275 [inlined]
 [13] retract!(M::ProductManifold{ℝ, Tuple{GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, q::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, p::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, X::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, t::Float64, method::ExponentialRetraction)
    @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:629
 [14] mean!(M::ProductManifold{ℝ, Tuple{GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, y::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, x::Vector{ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}}, w::StatsBase.UnitWeights{Float64}, ::GradientDescentEstimation; p0::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, stop_iter::Int64, retraction::ExponentialRetraction, inverse_retraction::LogarithmicInverseRetraction, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:389
 [15] mean!
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:367 [inlined]
 [16] #mean!#146
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:351 [inlined]
 [17] mean!
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:350 [inlined]
 [18] mean(M::ProductManifold{ℝ, Tuple{GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, x::Vector{ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}}, method::GradientDescentEstimation; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:310
 [19] mean (repeats 2 times)
    @ ~/.julia/packages/Manifolds/oiCZl/src/statistics.jl:309 [inlined]
 [20] mean
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:308 [inlined]
 [21] mean (repeats 2 times)
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:282 [inlined]
 [22] mean
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:275 [inlined]
 [23] mean
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:291 [inlined]
 [24] mean (repeats 3 times)
    @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:282 [inlined]
 [25] mean(M::ProductGroup{ℝ, Tuple{GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, x::Vector{ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}})
    @ Manifolds ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:275
 [26] top-level scope
    @ REPL[23]:1
Affie commented 2 years ago

Or just the exp:


julia> p = ProductRepr(ProductRepr([0;0.0],[1 0; 0 1.0]),[0;0.0]);

julia> X = ProductRepr(ProductRepr([0;0.0],[0.0 -0.0; 0.0 0.0]),[0;0.0]);

julia> retract(M, p, X)
ProductRepr with 2 submanifold components:
 Component 1 =
  ProductRepr with 2 submanifold components:
   Component 1 =
    2-element Vector{Float64}:
     0.0
     0.0
   Component 2 =
    2×2 Matrix{Float64}:
     1.0  0.0
     0.0  1.0
 Component 2 =
  2-element Vector{Float64}:
   0.0
   0.0

julia> exp(M, p, X)
ProductRepr with 2 submanifold components:
 Component 1 =
  ProductRepr with 2 submanifold components:
   Component 1 =
    2-element Vector{Float64}:
     0.0
     0.0
   Component 2 =
    2×2 Matrix{Float64}:
     1.0  0.0
     0.0  1.0
 Component 2 =
  2-element Vector{Float64}:
   0.0
   0.0

julia> exp!(M, p, p, X)
ERROR: DomainError with ExponentialRetraction():
You can not use the exponential map as an inner method to solve the ode for the exponential map.
Stacktrace:
 [1] ODEExponentialRetraction(r::ExponentialRetraction, #unused#::DefaultOrthonormalBasis{ℝ, ManifoldsBase.TangentSpaceType})
   @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:93
 [2] ODEExponentialRetraction(r::ExponentialRetraction)
   @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/retractions.jl:82
 [3] exp!(#unused#::ManifoldsBase.TraitList{IsMetricManifold, ManifoldsBase.TraitList{ManifoldsBase.IsExplicitDecorator, ManifoldsBase.EmptyTrait}}, M::ProductGroup{ℝ, Tuple{GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, q::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, p::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, X::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}})
   @ Manifolds ~/.julia/packages/Manifolds/oiCZl/src/manifolds/MetricManifold.jl:257
 [4] exp! (repeats 2 times)
   @ ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:282 [inlined]
 [5] exp!(M::ProductGroup{ℝ, Tuple{GroupManifold{ℝ, ProductManifold{ℝ, Tuple{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}}}, Manifolds.SemidirectProductOperation{RotationAction{TranslationGroup{Tuple{2}, ℝ}, SpecialOrthogonal{2}, LeftAction}}}, TranslationGroup{Tuple{2}, ℝ}}}, q::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, p::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}}, X::ProductRepr{Tuple{ProductRepr{Tuple{Vector{Float64}, Matrix{Float64}}}, Vector{Float64}}})
   @ ManifoldsBase ~/.julia/packages/ManifoldsBase/wwhwL/src/nested_trait.jl:275
 [6] top-level scope
   @ REPL[28]:1
mateuszbaran commented 2 years ago

These issues will be fixed soon, somehow we didn't properly test manifold operations on special euclidean groups. I put fixes in #491 , it should fix everything except some issues with in-place mutation I haven't found yet.

mateuszbaran commented 2 years ago

Manifolds.jl 0.8.9 should fix all of these issues except some rare cases of in-place mutation.

Affie commented 2 years ago

Thanks @mateuszbaran, the exp! issues look fixed.

This one still gives an error though: https://github.com/JuliaManifolds/Manifolds.jl/issues/483#issuecomment-1147520585 EDIT: no it works, was my error testing it

Affie commented 2 years ago

Thanks!