Skip to content
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

Make switch_direction consistent #639

Merged
merged 8 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/src/manifolds/group.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,14 @@ The following operations are available:

* [`apply`](@ref): performs given action of an element of the group on an object of compatible type.
* [`apply_diff`](@ref): differential of [`apply`](@ref) with respect to the object it acts upon.
* [`direction`](@ref): tells whether a given action is [`LeftAction`](@ref) or [`RightAction`](@ref).
* [`direction`](@ref): tells whether a given action is [`LeftForwardAction`](@ref), [`RightForwardAction`](@ref), [`LeftBackwardAction`](@ref) or [`RightBackwardAction`](@ref).
* [`inverse_apply`](@ref): performs given action of the inverse of an element of the group on an object of compatible type. By default inverts the element and calls [`apply`](@ref) but it may be have a faster implementation for some actions.
* [`inverse_apply_diff`](@ref): counterpart of [`apply_diff`](@ref) for [`inverse_apply`](@ref).
* [`optimal_alignment`](@ref): determine the element of a group that, when it acts upon a point, produces the element closest to another given point in the metric of the G-manifold.

Furthermore, group operation action features the following:

* [`translate`](@ref Main.Manifolds.translate): an operation that performs either left ([`LeftAction`](@ref)) or right ([`RightAction`](@ref)) translation. This is by default performed by calling [`compose`](@ref) with appropriate order of arguments. This function is separated from `compose` mostly to easily represent its differential, [`translate_diff`](@ref).
* [`translate`](@ref Main.Manifolds.translate): an operation that performs either left ([`LeftForwardAction`](@ref)) or right ([`RightBackwardAction`](@ref)) translation, or actions by inverses of elements ([`RightForwardAction`](@ref) and [`LeftBackwardAction`](@ref)). This is by default performed by calling [`compose`](@ref) with appropriate order of arguments. This function is separated from `compose` mostly to easily represent its differential, [`translate_diff`](@ref).
* [`translate_diff`](@ref): differential of [`translate`](@ref Main.Manifolds.translate) with respect to the point being translated.
* [`adjoint_action`](@ref): adjoint action of a given element of a Lie group on an element of its Lie algebra.
* [`lie_bracket`](@ref): Lie bracket of two vectors from a Lie algebra corresponding to a given group.
Expand Down
87 changes: 42 additions & 45 deletions ext/ManifoldsTestExt/tests_group.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ using Base: IdentityUnitRange
test_invariance = false,
test_lie_bracket=false,
test_adjoint_action=false,
diff_convs = [(), (LeftAction(),), (RightAction(),)],
diff_convs = [(), (LeftForwardAction(),), (RightBackwardAction(),)],
)

Tests general properties of the group `G`, given at least three different points
Expand All @@ -37,22 +37,22 @@ function test_group(
test_invariance=false,
test_lie_bracket=false,
test_adjoint_action=false,
diff_convs=[(), (LeftAction(),), (RightAction(),)],
diff_convs=[(), (LeftForwardAction(),), (RightBackwardAction(),)],
test_log_from_identity=false,
test_exp_from_identity=false,
test_vee_hat_from_identity=false,
)
e = Identity(G)

Test.@testset "Basic group properties" begin
Test.@testset "Basic group properties" begin # COV_EXCL_LINE
Test.@testset "Closed" begin
for g1 in g_pts, g2 in g_pts
g3 = compose(G, g1, g2)
Test.@test is_point(G, g3, true; atol=atol)
end
end

Test.@testset "Associative" begin
Test.@testset "Associative" begin # COV_EXCL_LINE
g12_3 = compose(G, compose(G, g_pts[1], g_pts[2]), g_pts[3])
g1_23 = compose(G, g_pts[1], compose(G, g_pts[2], g_pts[3]))
Test.@test isapprox(G, g12_3, g1_23; atol=atol)
Expand All @@ -67,7 +67,7 @@ function test_group(
end
end

Test.@testset "Identity" begin
Test.@testset "Identity" begin # COV_EXCL_LINE
Test.@test is_point(G, e)
wrong_e = if e === Identity(MultiplicationOperation())
Identity(AdditionOperation())
Expand Down Expand Up @@ -109,7 +109,7 @@ function test_group(
end
end

Test.@testset "Inverse" begin
Test.@testset "Inverse" begin # COV_EXCL_LINE
Test.@test inv(G, e) === e
for g in g_pts
ginv = inv(G, g)
Expand All @@ -132,8 +132,8 @@ function test_group(
end
end

Test.@testset "translation" begin
convs = ((), (LeftAction(),), (RightAction(),))
Test.@testset "translation" begin # COV_EXCL_LINE
convs = ((), (LeftForwardAction(),), (RightBackwardAction(),))

Test.@test isapprox(
G,
Expand All @@ -143,13 +143,13 @@ function test_group(
)
Test.@test isapprox(
G,
translate(G, g_pts[1], g_pts[2], LeftAction()),
translate(G, g_pts[1], g_pts[2], LeftForwardAction()),
compose(G, g_pts[1], g_pts[2]);
atol=atol,
)
Test.@test isapprox(
G,
translate(G, g_pts[1], g_pts[2], RightAction()),
translate(G, g_pts[1], g_pts[2], RightBackwardAction()),
compose(G, g_pts[2], g_pts[1]);
atol=atol,
)
Expand Down Expand Up @@ -211,20 +211,20 @@ function test_group(
G,
g12,
translate_diff(G, g_pts[2], g_pts[1], X),
translate_diff(G, g_pts[2], g_pts[1], X, LeftAction());
translate_diff(G, g_pts[2], g_pts[1], X, LeftForwardAction());
atol=atol,
)
Test.@test is_vector(
G,
g12,
translate_diff(G, g_pts[2], g_pts[1], X, LeftAction()),
translate_diff(G, g_pts[2], g_pts[1], X, LeftForwardAction()),
true;
atol=atol,
)
RightAction() in diff_convs && Test.@test is_vector(
RightBackwardAction() in diff_convs && Test.@test is_vector(
G,
g21,
translate_diff(G, g_pts[2], g_pts[1], X, RightAction()),
translate_diff(G, g_pts[2], g_pts[1], X, RightBackwardAction()),
true;
atol=atol,
)
Expand Down Expand Up @@ -334,14 +334,14 @@ function test_group(
end
end

Test.@testset "inv(g) = exp(-log(g))" begin
Test.@testset "inv(g) = exp(-log(g))" begin # COV_EXCL_LINE
g = g_pts[1]
X = log_lie(G, g)
ginv = exp_lie(G, -X)
Test.@test isapprox(G, ginv, inv(G, g); atol=atol)
end

Test.@testset "exp(sX)∘exp(tX) = exp((s+t)X)" begin
Test.@testset "exp(sX)∘exp(tX) = exp((s+t)X)" begin # COV_EXCL_LINE
g1 = exp_lie(G, 0.2 * Xe_pts[1])
g2 = exp_lie(G, 0.3 * Xe_pts[1])
g12 = exp_lie(G, 0.5 * Xe_pts[1])
Expand All @@ -354,7 +354,7 @@ function test_group(

test_exp_lie_log &&
test_diff &&
Test.@testset "exp/log retract/inverse_retract" begin
Test.@testset "exp/log retract/inverse_retract" begin # COV_EXCL_LINE
for conv in diff_convs
y = retract(
G,
Expand Down Expand Up @@ -397,27 +397,27 @@ function test_group(
end

test_invariance && Test.@testset "metric invariance" begin
if has_invariant_metric(G, LeftAction())
Test.@testset "left-invariant" begin
if has_invariant_metric(G, LeftForwardAction())
Test.@testset "left-invariant" begin # COV_EXCL_LINE
Test.@test has_approx_invariant_metric(
G,
g_pts[1],
X_pts[1],
X_pts[end],
g_pts,
LeftAction(),
LeftForwardAction(),
)
end
end
if has_invariant_metric(G, RightAction())
Test.@testset "right-invariant" begin
if has_invariant_metric(G, RightBackwardAction())
Test.@testset "right-invariant" begin # COV_EXCL_LINE
Test.@test has_approx_invariant_metric(
G,
g_pts[1],
X_pts[1],
X_pts[end],
g_pts,
RightAction(),
RightBackwardAction(),
)
end
end
Expand Down Expand Up @@ -476,7 +476,7 @@ function test_group(
end
end

Test.@testset "Metric operations with Identity" begin
Test.@testset "Metric operations with Identity" begin # COV_EXCL_LINE
if test_log_from_identity
pe = identity_element(G)
Test.@test isapprox(G, pe, log(G, e, g_pts[1]), log(G, pe, g_pts[1]))
Expand Down Expand Up @@ -516,6 +516,8 @@ function test_group(
return nothing
end

_direction_from_type(::AbstractGroupAction{TD}) where {TD<:ActionDirection} = TD()

"""
test_action(
A::AbstractGroupAction,
Expand Down Expand Up @@ -550,52 +552,47 @@ function test_action(
test_mutating_group=true,
test_mutating_action=true,
test_diff=false,
test_switch_direction=true,
test_switch_direction=Manifolds.LeftRightSwitch(),
)
G = base_group(A)
M = group_manifold(A)
e = Identity(G)

Test.@testset "Basic action properties" begin
test_switch_direction && Test.@testset "Direction" begin
Test.@testset "Basic action properties" begin # COV_EXCL_LINE
test_switch_direction !== false && Test.@testset "Direction" begin
Aswitch = switch_direction(A)
if isa(A, AbstractGroupAction{LeftAction})
Test.@test direction(A) === LeftAction()
Test.@test isa(Aswitch, AbstractGroupAction{RightAction})
Test.@test direction(Aswitch) === RightAction()
else
Test.@test direction(A) === RightAction()
Test.@test isa(Aswitch, AbstractGroupAction{LeftAction})
Test.@test direction(Aswitch) === LeftAction()
end
end

Test.@testset "Closed" begin
Test.@testset "over actions" begin
Test.@test direction(A) === _direction_from_type(A)
sd = switch_direction(_direction_from_type(A), test_switch_direction)
Test.@test isa(Aswitch, AbstractGroupAction{typeof(sd)})
Test.@test direction(Aswitch) === sd
end
Test.@testset "Closed" begin # COV_EXCL_LINE
Test.@testset "over actions" begin # COV_EXCL_LINE
for a1 in a_pts, a2 in a_pts
a3 = compose(A, a1, a2)
Test.@test is_point(G, a3, true; atol=atol)
end
end
Test.@testset "over g-manifold" begin
Test.@testset "over g-manifold" begin # COV_EXCL_LINE
for a in a_pts, m in m_pts
Test.@test is_point(M, apply(A, a, m), true; atol=atol)
Test.@test is_point(M, inverse_apply(A, a, m), true; atol=atol)
end
end
end

Test.@testset "Associative" begin
Test.@testset "Associative" begin # COV_EXCL_LINE
a12 = compose(A, a_pts[1], a_pts[2])
a23 = compose(A, a_pts[2], a_pts[3])

Test.@testset "over compose" begin
Test.@testset "over compose" begin # COV_EXCL_LINE
a12_a3 = compose(A, a12, a_pts[3])
a1_a23 = compose(A, a_pts[1], a23)
Test.@test isapprox(G, a12_a3, a1_a23; atol=atol)
end

Test.@testset "over apply" begin
Test.@testset "over apply" begin # COV_EXCL_LINE
for m in m_pts
a12_a3_m = apply(A, a12, apply(A, a_pts[3], m))
a1_a23_m = apply(A, a_pts[1], apply(A, a23, m))
Expand All @@ -621,7 +618,7 @@ function test_action(
end
end

Test.@testset "Identity" begin
Test.@testset "Identity" begin # COV_EXCL_LINE
Test.@test compose(A, e, e) === e

for a in a_pts
Expand Down Expand Up @@ -675,7 +672,7 @@ function test_action(
end
end

Test.@testset "Inverse" begin
Test.@testset "Inverse" begin # COV_EXCL_LINE
for a in a_pts
ainv = inv(G, a)
Test.@test isapprox(G, compose(A, a, ainv), e; atol=atol)
Expand Down
4 changes: 4 additions & 0 deletions src/Manifolds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,8 @@ export AbstractGroupAction,
Identity,
InvariantMetric,
LeftAction,
LeftBackwardAction,
LeftForwardAction,
LeftInvariantMetric,
MultiplicationOperation,
Orthogonal,
Expand All @@ -874,6 +876,8 @@ export AbstractGroupAction,
ProductOperation,
RealCircleGroup,
RightAction,
RightBackwardAction,
RightForwardAction,
RightInvariantMetric,
RotationAction,
SemidirectProductGroup,
Expand Down
8 changes: 4 additions & 4 deletions src/groups/circle_group.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ function inverse_translate(
::CircleGroup,
p::AbstractArray{<:Any,0},
q::AbstractArray{<:Any,0},
::LeftAction,
::LeftForwardAction,
)
return map(/, q, p)
end
function inverse_translate(
::CircleGroup,
p::AbstractArray{<:Any,0},
q::AbstractArray{<:Any,0},
::RightAction,
::RightBackwardAction,
)
return map(/, q, p)
end
Expand Down Expand Up @@ -175,15 +175,15 @@ function inverse_translate(
::RealCircleGroup,
p::AbstractArray{<:Any,0},
q::AbstractArray{<:Any,0},
::LeftAction,
::LeftForwardAction,
)
return map((x, y) -> sym_rem(x - y), q, p)
end
function inverse_translate(
::RealCircleGroup,
p::AbstractArray{<:Any,0},
q::AbstractArray{<:Any,0},
::RightAction,
::RightBackwardAction,
)
return map((x, y) -> sym_rem(x - y), q, p)
end
Expand Down
Loading
Loading