Skip to content

Commit

Permalink
Introduce types to distinguish representations of SE(n), specify zero…
Browse files Browse the repository at this point in the history
…_vector accordingly
  • Loading branch information
kellertuer committed Jan 15, 2025
1 parent 60238ab commit 78a8955
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 17 deletions.
23 changes: 23 additions & 0 deletions ext/LieGroupsRecursiveArrayToolsExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ end
# disable affine check
LieGroups._check_matrix_affine(::ArrayPartition, ::Int; v=1) = nothing

function ManifoldsBase.submanifold_component(
G::LieGroups.SpecialEuclideanGroup, g::ArrayPartition, ::Val{I}
) where {I}
# pass down to manifold by default
return ManifoldsBase.submanifold_component(G.manifold, g, I)
end
function ManifoldsBase.submanifold_component(
G::LieGroups.LeftSpecialEuclideanGroup, g::ArrayPartition, ::Val{:Rotation}
)
Expand All @@ -36,6 +42,23 @@ Base.@propagate_inbounds function ManifoldsBase.submanifold_component(
return ManifoldsBase.submanifold_component(G.manifold, g, 1)
end

function ManifoldsBase.zero_vector(
G::LieGroups.LeftSpecialEuclideanGroup,
e::Identity{LieGroups.SpecialEuclideanOperation},
::Union{ComponentsLieAlgebraTVector,ArrayPartition},
)
n = Manifolds.get_parameter(G.manifold[1].size)[1]
return ArrayPartition(zeros(n, n), zeros(n))
end
function ManifoldsBase.zero_vector(
G::LieGroups.RightSpecialEuclideanGroup,
e::Identity{LieGroups.SpecialEuclideanOperation},
::Union{ComponentsLieAlgebraTVector,ArrayPartition},
)
n = Manifolds.get_parameter(G.manifold[1].size)[1]
return ArrayPartition(zeros(n), zeros(n, n))
end

# TODO: Implement?
# The following three should also work due to the
# AbstractProductGroup s implementations
Expand Down
4 changes: 4 additions & 0 deletions src/LieGroups.jl
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ export SpecialEuclideanGroup, SpecialOrthogonalGroup, SpecialUnitaryGroup
export TranslationGroup
export UnitaryGroup

# Points and Tangent representations
export AffineMatrixPoint, AffineMatrixTVector
export ComponentsLieGroupPoint, ComponentsLieAlgebraTVector
# Functions
export adjoint, adjoint!, apply, apply!
export base_lie_group, base_manifold
export compose, compose!
Expand Down
7 changes: 6 additions & 1 deletion src/Lie_algebra/Lie_algebra_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,15 @@ function Base.show(io::IO, 𝔤::LieAlgebra)
return print(io, "LieAlgebra( $(𝔤.manifold) )")
end

function ManifoldsBase.zero_vector(𝔤::LieAlgebra, T::Type)
# pass to Lie group
return ManifoldsBase.zero_vector(𝔤.manifold, Idenitity(𝔤.manifold), T)
end
function ManifoldsBase.zero_vector(𝔤::LieAlgebra)
# pass to manifold directly
return ManifoldsBase.zero_vector(𝔤.manifold.manifold, identity_element(𝔤.manifold))
end

function ManifoldsBase.zero_vector!(𝔤::LieAlgebra, X)
# pass to manifold directly
return ManifoldsBase.zero_vector!(𝔤.manifold.manifold, X, identity_element(𝔤.manifold))
end
26 changes: 20 additions & 6 deletions src/groups/special_euclidean_group.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ const SpecialEuclideanOperation = Union{
},
}


"""
AffineMatrixPoint <: AbstractLieGroupPoint
Expand Down Expand Up @@ -117,7 +116,7 @@ where ``$(_tex(:vec, "0"))_n ∈ ℝ^n`` denotes the vector containing zeros.
While this tangent vector itself is not an affine matrix itself, it can be used for the Lie algebra of the affine group
"""
struct AffineMatrixTVector{T} <: AbstractLieAlgebraTangentVector
struct AffineMatrixTVector{T} <: AbstractLieAlgebraTVector
value::T
end

Expand All @@ -135,17 +134,16 @@ struct ComponentsLieGroupPoint{T} <: AbstractLieGroupPoint
end

"""
ComponentsLieAlgebraTangentVector <: AbstractLieGroupPoint
ComponentsLieAlgebraTVector <: AbstractLieGroupPoint
represent a point on a Lie algebra (explicitly) as a point that consists of components
"""
struct ComponentsLieAlgebraTangentVector{T} <: AbstractLieAlgebraTangentVector
struct ComponentsLieAlgebraTVector{T} <: AbstractLieAlgebraTVector
value::T
end

ManifoldsBase.@manifold_element_forwards ComponentsLieGroupPoint value
ManifoldsBase.@manifold_vector_forwards ComponentsLieAlgebraTangentVector value

ManifoldsBase.@manifold_vector_forwards ComponentsLieAlgebraTVector value

# This union we can also use for the matrix case where we do not care

Expand Down Expand Up @@ -303,10 +301,19 @@ function identity_element(G::SpecialEuclideanGroup, ::Type{<:AbstractMatrix})
q = zeros(ManifoldsBase.representation_size(G)...)
return identity_element!(G, q)
end
function identity_element(G::SpecialEuclideanGroup, ::Type{AffineMatrixPoint})
q = zeros(ManifoldsBase.representation_size(G)...)
identity_element!(G, q)
return AffineMatrixPoint(q)
end
function identity_element!(::SpecialEuclideanGroup, q::AbstractMatrix)
copyto!(q, I)
return q
end
function identity_element!(G::SpecialEuclideanGroup, q::AffineMatrixPoint)
identity_element!(G, q.value)
return q
end

_doc_inv_SEn = """
inv(G::SpecialEuclideanGroup, g)
Expand Down Expand Up @@ -425,6 +432,13 @@ function _SOn_and_Tn(G::RightSpecialEuclideanGroup)
return A[2], A[1]
end

function ManifoldsBase.zero_vector(
G::SpecialEuclidean, e::Identity{SpecialEuclideanOperation}
)
n = Manifolds.get_parameter(G.manifold[1].size)[1]
return zeros(n + 1, n + 1)
end

function Base.show(io::IO, G::SpecialEuclideanGroup)
size = Manifolds.get_parameter(G.manifold[1].size)[1]
return print(io, "SpecialEuclideanGroup($(size))")
Expand Down
22 changes: 20 additions & 2 deletions src/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ By sub-typing the [`AbstractManifoldPoint`](@extref `ManifoldsBase.AbstractManif
abstract type AbstractLieGroupPoint <: ManifoldsBase.AbstractManifoldPoint end

"""
AbstractLieAlgebraTangentVector <: ManifoldsBase.TVector
AbstractLieAlgebraTVector <: ManifoldsBase.TVector
An abstract type for a tangent vector represented in a [`LieAlgebra`](@ref).
Expand All @@ -113,7 +113,7 @@ it might be necessary to distinguish different types of points, for example
By sub-typing the [`AbstractManifoldPoint`](@extref `ManifoldsBase.AbstractManifoldPoint`),
this follows the same idea as in $(_link(:ManifoldsBase)).
"""
abstract type AbstractLieAlgebraTangentVector <: ManifoldsBase.TVector end
abstract type AbstractLieAlgebraTVector <: ManifoldsBase.TVector end

#
#
Expand Down Expand Up @@ -941,6 +941,24 @@ function vee!(G::LieGroup{𝔽}, c, X) where {𝔽}
return c
end

"""
zero_vector(G::LieGroup, e::Identity, T::Type)
Generate a $(_link(:zero_vector)) of type `T` in the [`LieAlgebra`](@ref) ``𝔤`` of
the [`LieGroup`](@ref) `G` of type `T`.
By default this calls `zero_vector(G, e)`
Note that for the in-place variant `zero_vector!(G, X::T, e)` the type can be inferred by `X`.
"""
ManifoldsBase.zero_vector(
G::LieGroup{𝔽,<:O}, ::Identity{<:O}, T::Type
) where {𝔽,O<:AbstractGroupOperation}

function ManifoldsBase.zero_vector(
G::LieGroup{𝔽,<:O}, e::Identity{<:O}, T::Type
) where {𝔽,O<:AbstractGroupOperation}
return zero_vector(G, e)
end
function ManifoldsBase.zero_vector(
G::LieGroup{𝔽,<:O}, ::Identity{<:O}
) where {𝔽,O<:AbstractGroupOperation}
Expand Down
16 changes: 8 additions & 8 deletions test/LieGroupsTestSuite.jl/LieGroupsTestSuite.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ function test_compose(
end
if test_identity && test_mutating
for g_ in [g, h]
for e in [Identity(G), identity_element(G)]
for e in [Identity(G), identity_element(G, typeof(g))]
k1 = compose(G, g_, e)
compose!(G, k2, g_, e)
@test isapprox(G, k1, k2)
Expand Down Expand Up @@ -266,7 +266,7 @@ function test_diff_inv(G::LieGroup, g, X; expected=missing, test_mutating::Bool=
Y1 = diff_inv(G, g, X)
@test is_vector(G, identity_element(G), Y1)
if test_mutating
Y2 = zero_vector(𝔤)
Y2 = zero_vector(𝔤, typeof(X))
Y2 = diff_inv!(G, Y2, g, X)
@test isapprox(𝔤, Y1, Y2)
end
Expand Down Expand Up @@ -294,7 +294,7 @@ function test_diff_left_compose(
Y1 = diff_left_compose(G, g, h, X)
@test is_vector(G, identity_element(G), Y1)
if test_mutating
Y2 = zero_vector(𝔤)
Y2 = zero_vector(𝔤, typeof(X))
diff_left_compose!(G, Y2, g, h, X)
@test isapprox(LieAlgebra(G), Y1, Y2)
end
Expand Down Expand Up @@ -322,7 +322,7 @@ function test_diff_right_compose(
Y1 = diff_right_compose(G, g, h, X)
@test is_vector(G, identity_element(G), Y1)
if test_mutating
Y2 = zero_vector(𝔤)
Y2 = zero_vector(𝔤, typeof(X))
diff_right_compose!(G, Y2, g, h, X)
@test isapprox(𝔤, Y1, Y2)
end
Expand Down Expand Up @@ -378,7 +378,7 @@ function test_diff_conjugate(
Y1 = diff_conjugate(G, g, h, X)
@test is_point(𝔤, Y1; error=:error)
if test_mutating
Y2 = zero_vector(𝔤)
Y2 = zero_vector(𝔤, typeof(X))
diff_conjugate!(G, Y2, g, h, X)
@test isapprox(𝔤, Y1, Y2)
end
Expand Down Expand Up @@ -442,7 +442,7 @@ function test_exp_log(
# Lie group log
Y1 = log(G, e, g)
if test_mutating
Y2 = zero_vector(G, e)
Y2 = zero_vector(G, e, typeof(X))
log!(G, Y2, e, g)
@test isapprox(𝔤, Y1, Y2)
log!(G, Y2, e, e)
Expand All @@ -462,7 +462,7 @@ function test_exp_log(
# or equivalently
@test is_vector(G, Identity(G), Y1; error=:error)
@test is_vector(G, Y1; error=:error)
Y3 = zero_vector(G, e)
Y3 = zero_vector(G, e, typeof(X))
@test isapprox(G, e, Y3, log(G, e, e); atol=atol)
log!(G, Y3, e, e)
@test isapprox(G, e, Y3, log(G, e, e); atol=atol)
Expand Down Expand Up @@ -775,7 +775,7 @@ function test_rand(
X1 = rand(rng, G; vector_at=g1)
@test is_vector(G, g1, X1; error=:error)
if test_mutating
X2 = zero_vector(LieAlgebra(G), g1)
X2 = zero_vector(LieAlgebra(G), typeof(X1))
rand!(rng, G, X2; vector_at=g1)
@test is_vector(G, g1, X2; error=:error)
end
Expand Down

0 comments on commit 78a8955

Please sign in to comment.