-
Notifications
You must be signed in to change notification settings - Fork 9
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
Nested power representation with replacement #73
Conversation
Codecov Report
@@ Coverage Diff @@
## master #73 +/- ##
==========================================
+ Coverage 99.70% 99.85% +0.15%
==========================================
Files 14 14
Lines 1351 1426 +75
==========================================
+ Hits 1347 1424 +77
+ Misses 4 2 -2
Continue to review full report at Codecov.
|
This looks interesting, though the name might be irritating due to its length; maybe it would help to have a concrete example how these two types of nested actions differ? |
The goal is to have a nested representation that supports immutable representation of points and tangent vectors on the wrapped manifold, for example Also, I'm definitely open to changing the name but so far I haven't come up with anything better. |
No I think the name sounds fine, if (but that would be breaking) I would call the other now Just for users to start with giving the details on similarities and differences would be neat. |
I'm not quite sure how to phrase it. Here is an example of a power manifold of SE(2) with in-line storage (all point on SE(2) are stored in a continuous block of memory): julia> using Manifolds, ManifoldsBase, StaticArrays
julia> R2 = Rotations(2)
Rotations(2)
julia> G = SpecialEuclidean(2)
SpecialEuclidean(2)
julia> N = 5
julia> GN = PowerManifold(G, ManifoldsBase.NestedReplacingPowerRepresentation(), N)
PowerManifold(SpecialEuclidean(2), ManifoldsBase.NestedReplacingPowerRepresentation(), N)
julia> q = [1.0 0.0; 0.0 1.0]
julia> p1 = [ProductRepr(SVector{2,Float64}([i - 0.1, -i]), SMatrix{2,2,Float64}(exp(R2, q, hat(R2, q, i)))) for i in 1:N]
5-element Vector{ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}}:
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.9, -1.0], [0.5403023058681398 -0.8414709848078965; 0.8414709848078965 0.5403023058681398]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([1.9, -2.0], [-0.4161468365471424 -0.9092974268256817; 0.9092974268256817 -0.4161468365471424]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([2.9, -3.0], [-0.9899924966004454 -0.1411200080598672; 0.1411200080598672 -0.9899924966004454]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([3.9, -4.0], [-0.6536436208636119 0.7568024953079282; -0.7568024953079282 -0.6536436208636119]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([4.9, -5.0], [0.28366218546322625 0.9589242746631385; -0.9589242746631385 0.28366218546322625]))
julia> p2 = [ProductRepr(SVector{2,Float64}([i - 0.1, -i]), SMatrix{2,2,Float64}(exp(R2, q, hat(R2, q, -i)))) for i in 1:N]
5-element Vector{ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}}:
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.9, -1.0], [0.5403023058681398 0.8414709848078965; -0.8414709848078965 0.5403023058681398]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([1.9, -2.0], [-0.4161468365471424 0.9092974268256817; -0.9092974268256817 -0.4161468365471424]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([2.9, -3.0], [-0.9899924966004454 0.1411200080598672; -0.1411200080598672 -0.9899924966004454]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([3.9, -4.0], [-0.6536436208636119 -0.7568024953079282; 0.7568024953079282 -0.6536436208636119]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([4.9, -5.0], [0.28366218546322625 -0.9589242746631385; 0.9589242746631385 0.28366218546322625]))
julia> X = similar(p1)
5-element Vector{ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}}:
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.0, 0.0], [0.0 0.0; 0.0 0.0]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.0, 0.0], [0.0 0.0; 0.0 0.0]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.0, 0.0], [0.0 0.0; 0.0 0.0]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.0, 0.0], [0.0 0.0; 0.0 0.0]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.0, 0.0], [0.0 0.0; 0.0 0.0]))
julia> log!(GN, X, p1, p2)
5-element Vector{ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}}:
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.0, 0.0], [0.0 2.0; -2.0 0.0]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.0, 0.0], [0.0 -2.2831853071795862; 2.2831853071795862 0.0]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.0, 0.0], [0.0 -0.28318530717958645; 0.28318530717958645 0.0]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.0, 0.0], [0.0 1.7168146928204135; -1.7168146928204135 0.0]))
ProductRepr{Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}}(([0.0, 0.0], [0.0 -2.566370614359173; 2.566370614359173 0.0])) I guess there should be perhaps a centralized place that explains strengths and weaknesses of each representation? Maybe in https://juliamanifolds.github.io/Manifolds.jl/stable/manifolds/power.html ? |
Thanks for the example, I think I have an idea of what the difference is. Yes that should be documented (all 3 types atcually) at https://juliamanifolds.github.io/Manifolds.jl/stable/manifolds/power.html Let me try to phrase it in my own words and we'll see whether this is correct.
In the beginning (this morning, and when starting to write this), I thought whether we would need a depth level for 3, but we don't, since for deeper nested structures one would have a
And maybe this nested of nested stuff is already too technical to be mentioned in the docs. Edit: For your last 2 lines I am not 100% sure, but allocating |
Yes, that's right.
That's also right, except IIRC we currently only support power-of-power by adding more indices, so no true nesting.
Yes, exactly.
Do we... actually want to support that?
Yes, outside of degenerate cases like a zero-index power manifold, it can't happen.
I'll have to think about it a bit more, it's not something I expected to support.
It's just an example. Sometimes you need to overwrite |
If you follow the
Cool. Then I understood this new case!
It is possible at least (see above), whether it is useful or we recommend using that is a different thing.
The first two are default ones, which should work (though see atop one has to trick a little to get them actually nested and not just stacked). For the third case – we should not support that, for the fourth – it should work but it'll be slow, and there is no real use in this I think.
Cool. My main point would be, that most generic things I write would use |
Right, I just didn't think of that.
I've thought a bit about it, and maybe I'm missing something, but I've summarized my thoughts in the table below.
In essence, I'd just recommend considering adding more indices to the inner power manifold. Other combinations should work, at least in some cases. I wouldn't add tests for them to our test suite unless some user specifically asks for it.
That's right, modifying variants still take priority over the non-modifying ones but I'm actually open to adding some non-mutating ones alongside mutating ones, if someone needs that. I expect |
Thanks for the table, yes, that's a good overview and I agree, that None of these are that good, and the default (adding dimenions to one PowerManifold) should stay the default. If one chooses one of these and goes the extra mile of construction these – the user will have a good reason. |
Could you maybe check whether you can provide a nice test for the allocation of the result of |
The |
That is, it doesn't seem to be needed for anything other than not having a harmless ambiguity. |
You're right, it's twice the CachedBasis, I misread the Codecov result. I am not sure whether this is harmless, but I feel if we have the code, we should have a test? |
OK, I've added a test. |
I'm not sure if I should export the new representation? And are you OK with the current naming? |
I think we should, since everybody should be able to use it. I think the name is a little long, but I do not have a better name in mind at the moment. |
That's the thing I've been recently talking about, i.e. a nested power manifold that doesn't require mutable representation of the wrapped manifold.