Skip to content

Commit

Permalink
fixing special euclidean
Browse files Browse the repository at this point in the history
  • Loading branch information
mateuszbaran committed Aug 7, 2024
1 parent 09fe31c commit 3685b59
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ if isdefined(Base, :get_extension)
FiberBundleBasisData,
FiberBundleProductVectorTransport,
LeftColumnwiseSpecialEuclideanAction,
LeftInvariantRepresentation,
PowerManifoldNestedReplacing,
SpecialEuclideanIdentity,
SpecialEuclideanInGeneralLinear,
TangentVectorRepresentation,
TypeParameter

using Manifolds: bundle_transport_tangent_direction, _get_parameter
Expand Down Expand Up @@ -49,6 +51,7 @@ if isdefined(Base, :get_extension)
project,
translate,
translate_diff,
vector_representation,
_vector_transport_direction,
vee
else
Expand All @@ -69,9 +72,11 @@ else
FiberBundleBasisData,
FiberBundleProductVectorTransport,
LeftColumnwiseSpecialEuclideanAction,
LeftInvariantRepresentation,
PowerManifoldNestedReplacing,
SpecialEuclideanIdentity,
SpecialEuclideanInGeneralLinear,
TangentVectorRepresentation,
TypeParameter

import ..Manifolds:
Expand Down Expand Up @@ -102,6 +107,7 @@ else
project,
translate,
translate_diff,
vector_representation,
_vector_transport_direction,
vee
end
Expand Down
42 changes: 31 additions & 11 deletions ext/ManifoldsRecursiveArrayToolsExt/special_euclidean_rat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,43 +27,59 @@ function project(M::SpecialEuclideanInGeneralLinear, p, X)
G = M.manifold
np, hp = submanifold_components(G, p)
nX, hX = submanifold_components(G, X)
return ArrayPartition(hp * nX, hX)
if vector_representation(M.manifold) isa LeftInvariantRepresentation
return ArrayPartition(nX, hX)

Check warning on line 31 in ext/ManifoldsRecursiveArrayToolsExt/special_euclidean_rat.jl

View check run for this annotation

Codecov / codecov/patch

ext/ManifoldsRecursiveArrayToolsExt/special_euclidean_rat.jl#L31

Added line #L31 was not covered by tests
else
return ArrayPartition(hp * nX, hX)
end
end

### Special methods for better performance of selected operations

function Base.exp(M::SpecialEuclidean, p::ArrayPartition, X::ArrayPartition)
function Base.exp(
M::SpecialEuclidean{T,<:TangentVectorRepresentation},
p::ArrayPartition,
X::ArrayPartition,
) where {T}
M1, M2 = M.manifold.manifolds
return ArrayPartition(
exp(M1.manifold, p.x[1], X.x[1]),
exp(M2.manifold, p.x[2], X.x[2]),
)
end
function Base.log(M::SpecialEuclidean, p::ArrayPartition, q::ArrayPartition)
function Base.log(
M::SpecialEuclidean{T,<:TangentVectorRepresentation},
p::ArrayPartition,
q::ArrayPartition,
) where {T}
M1, M2 = M.manifold.manifolds
return ArrayPartition(
log(M1.manifold, p.x[1], q.x[1]),
log(M2.manifold, p.x[2], q.x[2]),
)
end
function vee(M::SpecialEuclidean, p::ArrayPartition, X::ArrayPartition)
function vee(
M::SpecialEuclidean{T,<:TangentVectorRepresentation},
p::ArrayPartition,
X::ArrayPartition,
) where {T}
M1, M2 = M.manifold.manifolds
return vcat(vee(M1.manifold, p.x[1], X.x[1]), vee(M2.manifold, p.x[2], X.x[2]))
end
function get_coordinates(
M::SpecialEuclidean,
M::SpecialEuclidean{T,<:TangentVectorRepresentation},
p::ArrayPartition,
X::ArrayPartition,
basis::DefaultOrthogonalBasis,
)
) where {T}
M1, M2 = M.manifold.manifolds
return vcat(
get_coordinates(M1.manifold, p.x[1], X.x[1], basis),
get_coordinates(M2.manifold, p.x[2], X.x[2], basis),
)
end
function hat(
M::SpecialEuclidean{TypeParameter{Tuple{2}}},
M::SpecialEuclidean{TypeParameter{Tuple{2}},<:TangentVectorRepresentation},
p::ArrayPartition,
c::AbstractVector,
)
Expand All @@ -74,7 +90,7 @@ function hat(
)
end
function get_vector(
M::SpecialEuclidean{TypeParameter{Tuple{2}}},
M::SpecialEuclidean{TypeParameter{Tuple{2}},<:TangentVectorRepresentation},
p::ArrayPartition,
c::AbstractVector,
basis::DefaultOrthogonalBasis,
Expand All @@ -86,7 +102,7 @@ function get_vector(
end

function hat(
M::SpecialEuclidean{TypeParameter{Tuple{3}}},
M::SpecialEuclidean{TypeParameter{Tuple{3}},<:TangentVectorRepresentation},
p::ArrayPartition,
c::AbstractVector,
)
Expand All @@ -97,7 +113,7 @@ function hat(
)
end
function get_vector(
M::SpecialEuclidean{TypeParameter{Tuple{3}}},
M::SpecialEuclidean{TypeParameter{Tuple{3}},<:TangentVectorRepresentation},
p::ArrayPartition,
c::AbstractVector,
basis::DefaultOrthogonalBasis,
Expand All @@ -107,6 +123,10 @@ function get_vector(
get_vector(M.manifold.manifolds[2].manifold, p.x[2], c[SA[4, 5, 6]], basis),
)
end
function compose(::SpecialEuclidean, p::ArrayPartition, q::ArrayPartition)
function compose(
::SpecialEuclidean{T,<:TangentVectorRepresentation},
p::ArrayPartition,
q::ArrayPartition,
) where {T}
return ArrayPartition(p.x[2] * q.x[1] + p.x[1], p.x[2] * q.x[2])
end
25 changes: 21 additions & 4 deletions src/groups/group.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1230,11 +1230,22 @@ end
direction_and_side(::GroupExponentialRetraction{D}) where {D} = D()
direction_and_side(::GroupLogarithmicInverseRetraction{D}) where {D} = D()

function log(::TraitList{<:IsGroupManifold}, G::AbstractDecoratorManifold, p, q)
function log(

Check warning on line 1233 in src/groups/group.jl

View check run for this annotation

Codecov / codecov/patch

src/groups/group.jl#L1233

Added line #L1233 was not covered by tests
::TraitList{<:IsGroupManifold,<:LeftInvariantRepresentation},
G::AbstractDecoratorManifold,
p,
q,
)
BG = base_group(G)
return log_lie(BG, compose(BG, inv(BG, p), q))

Check warning on line 1240 in src/groups/group.jl

View check run for this annotation

Codecov / codecov/patch

src/groups/group.jl#L1239-L1240

Added lines #L1239 - L1240 were not covered by tests
end
function log!(::TraitList{<:IsGroupManifold}, G::AbstractDecoratorManifold, X, p, q)
function log!(

Check warning on line 1242 in src/groups/group.jl

View check run for this annotation

Codecov / codecov/patch

src/groups/group.jl#L1242

Added line #L1242 was not covered by tests
::TraitList{<:IsGroupManifold,<:LeftInvariantRepresentation},
G::AbstractDecoratorManifold,
X,
p,
q,
)
x = allocate_result(G, inv)
BG = base_group(G)
inv!(BG, x, p)
Expand All @@ -1243,7 +1254,7 @@ function log!(::TraitList{<:IsGroupManifold}, G::AbstractDecoratorManifold, X, p
return X

Check warning on line 1254 in src/groups/group.jl

View check run for this annotation

Codecov / codecov/patch

src/groups/group.jl#L1249-L1254

Added lines #L1249 - L1254 were not covered by tests
end
function exp(

Check warning on line 1256 in src/groups/group.jl

View check run for this annotation

Codecov / codecov/patch

src/groups/group.jl#L1256

Added line #L1256 was not covered by tests
::TraitList{<:IsGroupManifold},
::TraitList{<:IsGroupManifold,<:LeftInvariantRepresentation},
G::AbstractDecoratorManifold,
p,
X,
Expand All @@ -1252,7 +1263,13 @@ function exp(
BG = base_group(G)
return compose(BG, p, exp_lie(BG, t * X))

Check warning on line 1264 in src/groups/group.jl

View check run for this annotation

Codecov / codecov/patch

src/groups/group.jl#L1263-L1264

Added lines #L1263 - L1264 were not covered by tests
end
function exp!(::TraitList{<:IsGroupManifold}, G::AbstractDecoratorManifold, q, p, X)
function exp!(

Check warning on line 1266 in src/groups/group.jl

View check run for this annotation

Codecov / codecov/patch

src/groups/group.jl#L1266

Added line #L1266 was not covered by tests
::TraitList{<:IsGroupManifold,<:LeftInvariantRepresentation},
G::AbstractDecoratorManifold,
q,
p,
X,
)
BG = base_group(G)
exp_lie!(BG, q, X)
compose!(BG, q, p, q)
Expand Down
12 changes: 8 additions & 4 deletions src/groups/semidirect_product_group.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const SemidirectProductGroup{
GVR<:AbstractGroupVectorRepresentation,
} = GroupManifold{𝔽,ProductManifold{𝔽,Tuple{N,H}},SemidirectProductOperation{A},GVR}

const SemidirectProductGroupTVR{𝔽,N,H,A<:AbstractGroupAction} =
SemidirectProductGroup{𝔽,N,H,A,TangentVectorRepresentation}

@doc raw"""
SemidirectProductGroup(N::GroupManifold, H::GroupManifold, A::AbstractGroupAction)
Expand Down Expand Up @@ -134,9 +137,10 @@ function _compose!(G::SemidirectProductGroup, x, p, q)
end

@doc raw"""
translate_diff(G::SemidirectProductGroup, p, q, X, conX::LeftForwardAction)
translate_diff(G::SemidirectProductGroupTVR, p, q, X, conX::LeftForwardAction)
Perform differential of the left translation on the semidirect product group `G`.
Perform differential of the left translation on the semidirect product group `G`
with `TangentVectorRepresentation`.
Since the left translation is defined as (cf. [`SemidirectProductGroup`](@ref)):
Expand All @@ -150,9 +154,9 @@ then its differential can be computed as
\mathrm{d}L_{(n', h')}(X_n, X_h) = ( \mathrm{d}L_{n'} (\mathrm{d}θ_{h'}(X_n)), \mathrm{d}L_{h'} X_h).
````
"""
translate_diff(G::SemidirectProductGroup, p, q, X, conX::LeftForwardAction)
translate_diff(G::SemidirectProductGroupTVR, p, q, X, conX::LeftForwardAction)

function translate_diff!(G::SemidirectProductGroup, Y, p, q, X, conX::LeftForwardAction)
function translate_diff!(G::SemidirectProductGroupTVR, Y, p, q, X, conX::LeftForwardAction)
M = base_manifold(G)
N, H = M.manifolds
A = G.op.action
Expand Down
34 changes: 28 additions & 6 deletions src/groups/special_euclidean.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,23 @@ const SpecialEuclideanOperation{N} = SemidirectProductOperation{
}
const SpecialEuclideanIdentity{N} = Identity{SpecialEuclideanOperation{N}}

function Base.show(io::IO, ::SpecialEuclidean{TypeParameter{Tuple{n}}}) where {n}
return print(io, "SpecialEuclidean($(n))")
function Base.show(io::IO, G::SpecialEuclidean{TypeParameter{Tuple{n}}}) where {n}
if vector_representation(G) isa TangentVectorRepresentation
return print(io, "SpecialEuclidean($(n))")
else
return print(io, "SpecialEuclidean($(n); gvr=LeftInvariantRepresentation())")

Check warning on line 68 in src/groups/special_euclidean.jl

View check run for this annotation

Codecov / codecov/patch

src/groups/special_euclidean.jl#L68

Added line #L68 was not covered by tests
end
end
function Base.show(io::IO, G::SpecialEuclidean{Tuple{Int}})
n = _get_parameter(G)
return print(io, "SpecialEuclidean($(n); parameter=:field)")
if vector_representation(G) isa TangentVectorRepresentation
return print(io, "SpecialEuclidean($(n); parameter=:field)")
else
return print(
io,
"SpecialEuclidean($(n); parameter=:field, gvr=LeftInvariantRepresentation())",
)
end
end

@inline function active_traits(f, M::SpecialEuclidean, args...)
Expand Down Expand Up @@ -167,7 +178,7 @@ matrix part of `p`, `r` is the translation part of `fX` and `ω` is the rotation
``×`` is the cross product and ``⋅`` is the matrix product.
"""
function adjoint_action(
::SpecialEuclidean{TypeParameter{Tuple{3}}},
::SpecialEuclidean{TypeParameter{Tuple{3}},<:TangentVectorRepresentation},
p,
fX::TFVector{<:Any,VeeOrthogonalBasis{ℝ}},
)
Expand Down Expand Up @@ -642,7 +653,14 @@ is the translation part of `p` and ``X_t`` is the translation part of `X`.
"""
translate_diff(G::SpecialEuclidean, p, q, X, ::RightBackwardAction)

function translate_diff!(G::SpecialEuclidean, Y, p, q, X, ::RightBackwardAction)
function translate_diff!(
G::SpecialEuclidean{T,<:TangentVectorRepresentation},
Y,
p,
q,
X,
::RightBackwardAction,
) where {T}
np, hp = submanifold_components(G, p)
nq, hq = submanifold_components(G, q)
nX, hX = submanifold_components(G, X)
Expand Down Expand Up @@ -707,7 +725,11 @@ function embed(M::SpecialEuclideanInGeneralLinear, p, X)
Y = allocate_result(G, screw_matrix, nX, hX)
nY, hY = submanifold_components(G, Y)
copyto!(hY, hX)
copyto!(nY, nX)
if vector_representation(M.manifold) isa LeftInvariantRepresentation
copyto!(nY, nX)

Check warning on line 729 in src/groups/special_euclidean.jl

View check run for this annotation

Codecov / codecov/patch

src/groups/special_euclidean.jl#L729

Added line #L729 was not covered by tests
else
copyto!(nY, hp' * nX)
end
@inbounds _padvector!(G, Y)
return Y
end
Expand Down
28 changes: 20 additions & 8 deletions test/groups/special_euclidean.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,29 @@ using Manifolds:
LeftForwardAction, LeftBackwardAction, RightForwardAction, RightBackwardAction

@testset "Special Euclidean group" begin
for se_parameter in [:field, :type]
@testset "SpecialEuclidean($n)" for n in (2, 3, 4)
G = SpecialEuclidean(n; parameter=se_parameter)
for (se_parameter, se_gvr) in [
(:field, Manifolds.TangentVectorRepresentation()),
(:type, Manifolds.TangentVectorRepresentation()),
(:field, Manifolds.LeftInvariantRepresentation()),
]
@testset "SpecialEuclidean($n; parameter=$se_parameter, gvr=$se_gvr)" for n in
(2, 3, 4)
G = SpecialEuclidean(n; parameter=se_parameter, gvr=se_gvr)
if se_parameter === :field
@test isa(G, SpecialEuclidean{Tuple{Int}})
else
@test isa(G, SpecialEuclidean{TypeParameter{Tuple{n}}})
end

if se_parameter === :field
if se_parameter === :field && se_gvr === Manifolds.TangentVectorRepresentation()
@test repr(G) == "SpecialEuclidean($n; parameter=:field)"
else
elseif se_parameter === :type &&
se_gvr === Manifolds.TangentVectorRepresentation()
@test repr(G) == "SpecialEuclidean($n)"
elseif se_parameter === :field &&
se_gvr === Manifolds.LeftInvariantRepresentation()
@test repr(G) ==
"SpecialEuclidean($n; parameter=:field, gvr=LeftInvariantRepresentation())"
end
M = base_manifold(G)
@test M ===
Expand Down Expand Up @@ -92,9 +102,11 @@ using Manifolds:
@test affine_matrix(G, Identity(G)) == SDiagonal{n,Float64}(I)

w = translate_diff(G, pts[1], Identity(G), X_pts[1])
w2mat = screw_matrix(G, w)
@test w2mat screw_matrix(G, X_pts[1])
@test screw_matrix(G, w2mat) === w2mat
if se_gvr isa Manifolds.LeftInvariantRepresentation
w2mat = screw_matrix(G, w)
@test w2mat screw_matrix(G, X_pts[1])
@test screw_matrix(G, w2mat) === w2mat
end

@test is_vector(G, Identity(G), rand(G; vector_at=Identity(G)))

Expand Down

0 comments on commit 3685b59

Please sign in to comment.