Skip to content

Commit

Permalink
Fix exp/log defaults and fallbacks.
Browse files Browse the repository at this point in the history
  • Loading branch information
kellertuer committed Oct 14, 2024
1 parent 4ae7f74 commit 23cd4f0
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 48 deletions.
3 changes: 3 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ authors = ["Seth Axen <[email protected]>", "Mateusz Baran <mateuszbaran89@gma
version = "0.1.0"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Manifolds = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e"
ManifoldsBase = "3362f125-f0bb-47a3-aa74-596ffd7ef2fb"

[compat]
LinearAlgebra = "1.6"
Manifolds = "0.10"
ManifoldsBase = "0.15.16"
julia = "1.6"

[extras]
Manifolds = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e"
Expand Down
33 changes: 18 additions & 15 deletions src/LieGroups.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
module LieGroups

using ManifoldsBase, Manifolds

# before removing them from Manifolds.jl, let's for consistency include them here but
# overwrite them for now. This makes moving away from that (in Manifolds.jl 0.11) here non-breaking.
import Manifolds: apply, apply!, identity_element
using ManifoldsBase, Manifolds, LinearAlgebra

#
#
# = Compatibility (and a bit of type piracy for now)
# The following imports shall be removed once Manifolds.jl does no longer define them (in 0.11)
import Manifolds: apply, apply!, identity_element, is_identity, compose
# Both define the following structs, so these for now lead to asking for explicit prefixes
# Manifolds: Identity, TranslationGroup
include("documentation_glossary.jl")
include("interface.jl")

Expand All @@ -31,12 +35,11 @@ export GroupOperationAction

export TranslationGroup

export apply, apply!, diff_apply, diff_apply!
export base_manifold
export adjoint,
adjoint!,
compose,
compose!,
export adjoint, adjoint!, apply, apply!
export base_Lie_group, base_manifold
export compose, compose!
export diff_apply,
diff_apply!,
diff_left_compose,
diff_left_compose!,
diff_right_compose,
Expand All @@ -47,9 +50,9 @@ export adjoint,
inv_right_compose!
export isapprox, is_point, is_vector
export conjugate, conjugate!, diff_conjugate, diff_conjugate!
export exp, exp!, log, log!
export exp, exp!
export identity_element, identity_element!, is_identity, inv, inv!, diff_inv, diff_inv!
export base_Lie_group, base_manifold
export lie_bracket, lie_bracket!
export inv
export lie_bracket, lie_bracket!, log, log!
export norm
export zero_vector
end # module LieGroups
42 changes: 19 additions & 23 deletions src/group_operations/addition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,31 @@ Base.:*(e::Identity{AdditionGroupOperation}, p) = e
Base.:*(::Any, e::Identity{AdditionGroupOperation}) = e
Base.:*(e::Identity{AdditionGroupOperation}, ::Identity{AdditionGroupOperation}) = e

Check warning on line 26 in src/group_operations/addition.jl

View check run for this annotation

Codecov / codecov/patch

src/group_operations/addition.jl#L24-L26

Added lines #L24 - L26 were not covered by tests

function _compose(::LieGroup{𝔽,AdditionGroupOperation}, g, h) where {𝔽}
return g + h
end

function _compose!(G::LieGroup{𝔽,AdditionGroupOperation}, k, g, h) where {𝔽}
ManifoldsBase.copyto!(G, k, g + h)
return k
end

function Base.exp(::LieGroup{𝔽,AdditionGroupOperation}, X) where {𝔽}
return X
end
"""
"""
Base.exp(
::LieGroup{𝔽,AdditionGroupOperation}, ::Identity{AdditionGroupOperation}, X
) where {𝔽}

function ManifoldsBase.exp!(G::LieGroup{𝔽,AdditionGroupOperation}, g, X) where {𝔽}
function ManifoldsBase.exp!(
G::LieGroup{𝔽,AdditionGroupOperation},
g,
::Identity{AdditionGroupOperation},
X,
t::Number=1,
) where {𝔽}
return copyto!(G, g, X)
end

function identity_element!(::LieGroup{𝔽,AdditionGroupOperation}, e) where {𝔽}
return fill!(e, 0)
end

function Base.inv(::LieGroup{𝔽,AdditionGroupOperation}, g) where {𝔽}
return -g
end
function inv!(G::LieGroup{𝔽,AdditionGroupOperation}, h, g) where {𝔽}
return copyto!(G, h, -g)
end
Expand All @@ -67,19 +68,14 @@ function is_identity(
return true

Check warning on line 68 in src/group_operations/addition.jl

View check run for this annotation

Codecov / codecov/patch

src/group_operations/addition.jl#L68

Added line #L68 was not covered by tests
end

function Base.log(::LieGroup{𝔽,AdditionGroupOperation}, q) where {𝔽}
return q
end
function Base.log(
::LieGroup{𝔽,AdditionGroupOperation}, ::Identity{AdditionGroupOperation}
"""
"""
ManifoldsBase.log(
G::LieGroup{𝔽,AdditionGroupOperation}, ::Identity{AdditionGroupOperation}, q
) where {𝔽}
return zero_vector(G, identity_element(G))
end
function ManifoldsBase.log!(G::LieGroup{𝔽,AdditionGroupOperation}, X, q) where {𝔽}
return copyto!(G, X, q)
end

function ManifoldsBase.log!(
G::LieGroup{𝔽,AdditionGroupOperation}, X, ::Identity{AdditionGroupOperation}
G::LieGroup{𝔽,AdditionGroupOperation}, X, ::Identity{AdditionGroupOperation}, q
) where {𝔽}
return zero_vector!(G, X, identity_element(G))
return copyto!(G, X, q)
end
33 changes: 28 additions & 5 deletions src/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ and ``$(_tex(:exp))_{$(_math(:G))}`` denotes the [Lie group exponential functio
!!! note
The Lie group exponential map is usually different from the exponential map with respect
to the metric of the underlying Riemannian manifold ``$(_math(:M))``.
To access the (Riemannian) exponential map, use `exp(`[`base_manifold`](@ref)`G, g, X)`.
To access the (Riemannian) exponential map, use `exp(`[`base_manifold`](@ref)`(G), g, X)`.
"""

@doc "$_doc_exp"
Expand Down Expand Up @@ -383,9 +383,15 @@ function ManifoldsBase.exp(G::LieGroup, e::Identity, X, t::Number=1)
return h
end

# Fallback to a MethodError to avoid stack overflow
@doc "$(_doc_exp_id)"
ManifoldsBase.exp!(::LieGroup, h, ::Identity, X, ::Number=1)

function ManifoldsBase.exp!(G::LieGroup, h, e::Identity, X, t::Number=1)
throw(

Check warning on line 389 in src/interface.jl

View check run for this annotation

Codecov / codecov/patch

src/interface.jl#L388-L389

Added lines #L388 - L389 were not covered by tests
MethodError(
ManifoldsBase.exp!, (typeof(G), typeof(h), typeof(e), typeof(X), typeof(t))
),
)
end
_doc_inv_left_compose = """
inv_left_compose(G::LieGroup, g, h)
inv_left_compose!(G::LieGroup, k, g, h)
Expand Down Expand Up @@ -494,7 +500,7 @@ This falls back to checking whether `X` is a valid point on the tangent space
at the [`identity_element``](@ref)`]`(G)` on `G.manifold` on the [`LieGroup`](@ref)
of `G`
"""
function ManifoldsBase.is_point(𝔤::LieAlgebra, g; kwargs...)
function ManifoldsBase.is_point(𝔤::LieAlgebra, X; kwargs...)
# the manifold stored in the Fiber / Lie Algebra is the Lie Group G
G = 𝔤.manifold
e = identity_element(G)
Expand Down Expand Up @@ -638,11 +644,28 @@ function ManifoldsBase.log(G::LieGroup, e::Identity, g)
return X
end

# explicit method error to avoid stack overflow
@doc "$(_doc_log_id)"
ManifoldsBase.log!(::LieGroup, X, ::Identity, g)
function ManifoldsBase.log!(G::LieGroup, X, e::Identity, g)
throw(MethodError(ManifoldsBase.log!, (typeof(G), typeof(X), typeof(e), typeof(g))))

Check warning on line 650 in src/interface.jl

View check run for this annotation

Codecov / codecov/patch

src/interface.jl#L649-L650

Added lines #L649 - L650 were not covered by tests
end

# Move this line already to ManifoldsBase?
LinearAlgebra.norm(𝔤::LieAlgebra, X) = LinearAlgebra.norm(𝔤.manifold, 𝔤.point, X)
function LinearAlgebra.norm(
G::LieGroup{𝔽,O}, ::Identity{O}, X
) where {𝔽,O<:AbstractGroupOperation}
return LinearAlgebra.norm(G, identity_element(G), X)
end
LinearAlgebra.norm(G::LieGroup, g, X) = LinearAlgebra.norm(G.manifold, g, X)

function ManifoldsBase.representation_size(G::LieGroup)
return ManifoldsBase.representation_size(G.manifold)
end

Base.show(io::IO, 𝔤::LieAlgebra) = print(io, "Lie Algebra( $(𝔤.manifold) )")
Base.show(io::IO, G::LieGroup) = print(io, "LieGroup($(G.manifold), $(G.op))")

function ManifoldsBase.zero_vector(G, e::Identity)
return ManifoldsBase.zero_vector(G, identity_element(G))
end
29 changes: 28 additions & 1 deletion test/LieGroupsTestSuite.jl/LieGroupsTestSuite.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,33 @@ a vector `X` from the Lie Algebra.
* `test_log=true`: test the logarithmic map.
"""
function test_exp_log(G::LieGroup, g, h, X; test_exp=true, test_log=true)
@testset "exp(G, g, X) & log(G, g, h)" begin
@testset "(Lie group) exp & log" begin
𝔤 = LieAlgebra(G)
e = Identity(G)
if test_exp
# Lie group exp
k1 = exp(G, e, X)
k2 = copy(G, g)
exp!(G, k2, e, X)
@test isapprox(G, k1, k2)
@test is_point(G, k1)
# exp
k1 = exp(G, g, X)
k2 = copy(G, g)
exp!(G, k2, g, X)
@test isapprox(G, k1, k2)
@test is_point(G, k1)
end
if test_log
# Lie group log
Y1 = log(G, e, g)
Y2 = copy(G, g)
log!(G, Y2, e, g)
@test isapprox(𝔤, Y1, Y2)
@test is_point(𝔤, Y1)
@test norm(𝔤, log(G, g, g)) 0
@test norm(𝔤, log(G, h, h)) 0
# log
Y1 = log(G, g, h)
Y2 = copy(G, g)
log!(G, Y2, g, h)
Expand All @@ -91,6 +108,16 @@ function test_exp_log(G::LieGroup, g, h, X; test_exp=true, test_log=true)
@test norm(𝔤, log(G, h, h)) 0
end
if test_exp && test_log
# Lie group exp / log
k1 = exp(G, e, X)
k2 = copy(G, g)
exp!(G, k2, e, X)
Y1 = log(G, e, k1)
Y2 = copy(G, g)
log!(G, Y2, e, k2)
@test isapprox(𝔤, Y1, Y2)
@test isapprox(𝔤, X, Y1)
# exp & log
k1 = exp(G, g, X)
k2 = copy(G, g)
exp!(G, k2, g, X)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ using LieGroupsTestSuite
begin
G = TranslationGroup(3)
# Later maybe via auto-discover?
p1, p2, p3 = [1.0, 0.0, 0.0], [0.0, 3.0, 0.0], [1.1, 1.2, 3.3]
g1, g2, g3 = [1.0, 0.0, 0.0], [0.0, 3.0, 0.0], [1.1, 1.2, 3.3]
X1, X2, X3 = [0.0, 1.0, 0.0], [2.0, 0.0, 0.0], [0.1, 0.2, 0.3]
properties = Dict(
:Name => "The Translation group",
:Points => [p1, p2, p3],
:Points => [g1, g2, g3],
:Vectors => [X1, X2, X3],
:Functions => [compose, exp, inv, log, show, is_identity],
)
Expand Down
4 changes: 2 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ using LieGroupsTestSuite

function include_test(path)
@info "Testing $path"
@time include(path) # show basic timing, (this will print a newline at end)
@time include(path) # show basic timing, (this prints a newline at end)
end

@testset "Lie Groups" begin
include_test("groups/translation.jl")
include_test("groups/test_translation_group.jl")
end

0 comments on commit 23cd4f0

Please sign in to comment.