Skip to content

Commit 3331833

Browse files
Transfer more elements from Manifolds.jl (#65)
* add jacobian of the exponential function. * Fix a merge mistake. * Improve notation and add a note on left/right Jacobians. * Fix a note. * Sketch ColumAction, transfer the LeftMult action of SE(n) onto Rn. * Finish SE(n) acting on Rn. * add rotation around axis action * limit imports from Manifolds * Introduce types for row and column wise actions as generic wrappers. * Fix docs. * runic. * add tests for row and columnwise actions. * transfer the last action. * test coverage I * propose a different way of transferring the jacobian of the exponential. * Fix docs. * Bump version, set today as release day. --------- Co-authored-by: Mateusz Baran <[email protected]>
1 parent 2c3033a commit 3331833

26 files changed

+624
-32
lines changed

NEWS.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@ All notable Changes to the Julia package `LieGroups.jl` will be documented in th
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [0.1.4] unreleased
8+
## [0.1.4] 2025-10-02
99

1010
### Added
1111

12+
* mention `adjoint_matrix` in the transition documentation (#52)
13+
* introduce `jacobian_exp` for the Jacobian of the exponential function.
1214
* Introduce a `AbstractActionActsOnType` to distinguish, what previously was called “side”,
1315
i.e. whether an action acts on the left (`ActionActsOnLeft`) or right (`ActionActsOnRight`)
1416
* Introduce `_inv` and `_inv!` functions for the inverse operation to work the same way as `_compose` and `_compose!`, respectively.
1517
* introduce a `LeftMultiplicationGroupAction` to represent left multiplication actions on Lie groups. While this is a bit more of a technical
1618
name, it replaces the old `ComplexPlanarRotation`, `QuaternionRotation`, and `RotationAction`, since in the `GroupAction` this type is coupled with a group and a manifold anyway.
19+
* further methods for the `LeftMultiplicationGroupAction` to cover the previous functionality of e.g.
20+
* `RotationTranslationActionOnVector`
1721
* Add the Special Galilean Group (#60)
1822

1923
### Fixed
@@ -23,6 +27,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2327
* Fixed an issue, where `exp!(G, h, g, X)` would return a wrong result if the input `g`and the output `h`are aliased (#63).
2428
* Fixed issues with the documentation of `diff_left_compose` and `diff_right_compose` that were inconsistent
2529
* fixed `push_forward_tangent` and `pull_back_tangent` which on general Lie groups provided a wrong default.
30+
* fixes an allocation bug for `apply` and `diff_apply` (#52)
31+
2632

2733
## [0.1.3] 2025-08-04
2834

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "LieGroups"
22
uuid = "6774de46-80ba-43f8-ba42-e41071ccfc5f"
33
authors = ["Seth Axen <[email protected]>", "Mateusz Baran <[email protected]>", "Ronny Bergmann <[email protected]>", "Yueh-Hua Tu", "Olivier Verdier <[email protected]>"]
4-
version = "0.1.3"
4+
version = "0.1.4"
55

66
[deps]
77
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

docs/src/interface/actions.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,42 @@ Order = [:function]
1616

1717
# Generic Lie group actions
1818

19+
```@autodocs
20+
Modules = [LieGroups]
21+
Pages = ["addition_action.jl"]
22+
Order = [:type, :function]
23+
```
24+
1925
```@autodocs
2026
Modules = [LieGroups]
2127
Pages = ["group_operation_action.jl"]
2228
Order = [:type, :function]
2329
```
2430

31+
```@autodocs
32+
Modules = [LieGroups]
33+
Pages = ["columnwise_action.jl"]
34+
Order = [:type, :function]
35+
```
36+
2537
```@autodocs
2638
Modules = [LieGroups]
2739
Pages = ["multiplication_action.jl"]
2840
Order = [:type, :function]
2941
```
3042

43+
```@autodocs
44+
Modules = [LieGroups]
45+
Pages = ["group_actions/rotation_around_axis_action.jl"]
46+
Order = [:type, :function]
47+
```
48+
49+
```@autodocs
50+
Modules = [LieGroups]
51+
Pages = ["rowwise_action.jl"]
52+
Order = [:type, :function]
53+
```
54+
3155
## Literature
3256

3357
```@bibliography

docs/src/notation.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,49 @@ In this package,the notation introduced in [Manifolds.jl Notation](https://julia
88
| ```` | a group operation | | |
99
| ``c_g:\mathcal G → \mathcal G`` | the conjugation map (with `g`) | | |
1010
| ``Df(p)[X]`` | the differential of a map `f` at point `p` in direction `X` | | |
11-
| ``\mathrm{d}f`` | the differential of a map `f` as a function on the Lie group and the differential on the Lie algebra. | | |
12-
| ``\mathrm{D}_af`` | the differential of a map `f`. An index is used to indicate a certain parameter. If ``f`` is defined on or maps into the Lie group, this differential indicates the one with respect to tangent spaces | | |
11+
| ``\mathrm{d}f`` | the differential of a map `f` as a function on the Lie group and the differential on the Lie algebra. | | see also note below |
12+
| ``\mathrm{D}_af`` | the differential of a map `f`. An index is used to indicate a certain parameter. If ``f`` is defined on or maps into the Lie group, this differential indicates the one with respect to tangent spaces | | see also note below|
1313
| ``\mathrm{e}`` | identity element of a group | | |
1414
| ``\exp_{\mathcal G}(X)`` | The Lie group exponential function | | |
1515
| ``\exp_g(X)`` | The Lie group exponential map (w.r.t. a Cartan Schouten connection) | | |
1616
| ``g, h, k`` | elements on a (Lie) group. Sometimes called points. | ``g_1, g_2, ...`` | |
1717
| ``\mathfrak g`` | a Lie algebra | | |
1818
| ``\mathcal{G}`` | a Lie group | | |
19+
| ``\operatorname{J}_f(p)`` | the Jacobian of a map `f` at point `p` | | sometimes left Jacobian, see note below. |
1920
| ``λ_g: \mathcal G → \mathcal G`` | the left group operation map ``λ_g(h) = g∘h`` | | |
2021
| ``\log_{\mathcal G}(g)`` | The Lie group logarithmic function | | |
2122
| ``\log_g(h)`` | The Lie group logarithmic map (w.r.t. a Cartan Schouten connection) | | |
2223
| ``α: \mathcal M → \mathcal G → \mathcal M`` | a (general) group action | | |
2324
| ``ρ_g: \mathcal G → \mathcal G`` | the right group operation map ``ρ_g(h) = h∘g`` | | |
2425
| ``σ: \mathcal G × \mathcal M → \mathcal M`` | a left group action | | ``σ_g(p)`` to emphasize a fixed group element |
2526
| ``τ: \mathcal G × \mathcal M → \mathcal M`` | a right group action | ``σ_\mathrm{R}`` | ``τ_g(p)`` to emphasize a fixed group element |
27+
28+
## About differentials and Jacobians
29+
30+
For a function defined on a [manifold](@extref `ManifoldsBase.AbstractManifold`) ``f:\mathcal M → \mathcal N``, the differential at a point ``p ∈ \mathcal M`` is a map between the tangent spaces
31+
32+
```math
33+
Df(p) : T_p\mathcal M → T_{f(p)}\mathcal N.
34+
```
35+
36+
This is the default in [`Manifolds.jl`](@extref Manifolds :std:doc:`index`).
37+
38+
For the case where ``\mathcal M = \mathcal N = \mathcal G`` is an [`AbstractLieGroup`](@ref), the differential can be expressed in terms of the Lie algebra ``\mathfrak g`` as
39+
40+
```math
41+
\mathrm{d}f(g) : \mathfrak g → \mathfrak g.
42+
```
43+
44+
An alternate way to define this differential on the Lie algebra is to consider the (usual) differential ``Dg(p)`` of ``g(q) = f(q⋅p)⋅f(p)^{-1}``.
45+
46+
where we use a different notation on purpose. This second notation is the default throughout `LieGroups.jl`.
47+
48+
The Jacobian ``\operatorname{J}_f(p)`` of ``f`` at ``p`` is the matrix representation of the differential with respect to a basis of each of the tangent spaces.
49+
For the default representation ``\mathrm{d}f(g)`` we have to choose a basis of the [Lie algebra](@ref LieAlgebra) ``\mathfrak g``.
50+
Throughout `LieGroups.jl` this is the [`DefaultLieAlgebraOrthogonalBasis`](@ref).
51+
52+
## About left and right Jacobians
53+
54+
This jacobian using ``\mathrm{d}f(g)`` and the [`DefaultLieAlgebraOrthogonalBasis`](@ref) is sometimes called the left Jacobian.
55+
The other choice using on two tangent space bases of ``T_p\mathcal G`` and ``T_{f(p)}\mathcal G``, respectively, is sometimes called the right Jacobian.
56+
The default throughout `LieGroups.jl` is the left Jacobian.

docs/src/references.bib

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,21 @@ @book{BinzPods:2008
3434
YEAR = {2008}
3535
}
3636

37+
#
38+
#
39+
# C
40+
# ------------------------------------------------------------------------------------------
41+
@book{Chirikjian:2012,
42+
edition = {1},
43+
series = {Applied and {Numerical} {Harmonic} {Analysis}},
44+
title = {Stochastic {Models}, {Information} {Theory}, and {Lie} {Groups}, {Volume} 2},
45+
volume = {2},
46+
url = {https://link.springer.com/book/10.1007/978-0-8176-4944-9},
47+
publisher = {Birkhäuser Boston, MA},
48+
author = {Chirikjian, Gregory S.},
49+
year = {2012},
50+
}
51+
3752
#
3853
#
3954
# G

docs/src/tutorials/transition.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ Lie algebra elements (vectors) always `X, Y`.
1717

1818
New functions and types in this package are only mentioned, if they are worth a comment and if something changed.
1919

20-
The list is alphabetical, but first lists types, then functions
20+
The list lists first types, then functions. Within both blocks, the order is alphabetical
2121

2222
| `Manifolds.jl` | `LieGroups.jl` | Comment |
2323
|:---------- |:---------- |:-------------- |
2424
| `AdditionOperation` | [`AdditionGroupOperation`](@ref) | |
25+
| `ColumnwiseMultiplicationAction` | [`ColumnwiseGroupAction`](@ref)`(`[`LeftMultiplicationGroupAction`](@ref)`)` | within a [`GroupAction`](@ref)`(action, group, manifold)` |
26+
| `ColumnwiseSpecialEuclideanAction` | [`ColumnwiseGroupAction`](@ref)`(`[`LeftMultiplicationGroupAction`](@ref)`)` | within a [`GroupAction`](@ref)`(action, group, manifold)`, where the `group`is a [`SpecialEuclideanGroup`](@ref) |
2527
| `ComplexPlanarRotation` | [`LeftMultiplicationGroupAction`](@ref) | a slightly more general type for all actions that are implemented by (matrix) multiplication |
2628
| `GroupActionSide` | [`AbstractActionActsOnType`](@ref) | Switching to a new, hopefully more descriptive naming. |
2729
| `LeftBackwardAction` | [`AbstractRightGroupActionType`](@ref) and [`ActionActsOnRight`](@ref) | This tuple form has been discontinued. |
@@ -36,9 +38,14 @@ The list is alphabetical, but first lists types, then functions
3638
| `RightForwardAction` | [`AbstractRightGroupActionType`](@ref) and [`ActionActsOnLeft`](@ref) | This tuple form has been discontinued. |
3739
| `RightSide` | [`ActionActsOnRight`](@ref) | |
3840
| `RotationAction` | [`LeftMultiplicationGroupAction`](@ref) | a slightly more general type for all actions that are implemented by (matrix) multiplication |
41+
| `RotationTranslationActionOnVector` | [`LeftMultiplicationGroupAction`](@ref) | e.g. in a [`GroupAction`](@ref) with [`SpecialEuclideanGroup`](@ref) and [`Euclidean`](@extref `Manifolds.Euclidean`)`(n)`. |
42+
| `RowwiseMultiplicationAction` | [`RowwiseGroupAction`](@ref)`(`[`LeftMultiplicationGroupAction`](@ref)`)` | |
3943
| `SemidirectProductGroup(G, H, a)` | [`LeftSemidirectProductLieGroup`](@ref)`(G, H, a)` | While this staid the same, there is now also the [`default_left_action`](@ref)`(G,H)`. When this agrees with `a` you can use the short hand `G⋉H` to generate this semidirect product. Analogously there now also exists the [`RightSemidirectProductLieGroup`](@ref)`(G,H)` with[`default_left_action`](@ref)`(G,H)` that allows for the short cut `G⋊H` |
4044
| `SpecialEuclidean(n)` | `SpecialEuclideanGroup(n; variant=:right)` | |
45+
| `TranslationAction` | [`AdditionGroupAction`](@ref) | this slightly more general name allows to reuse the action in other contexts easier |
46+
| `VeeOrthogonalBasis` | [`DefaultLieAlgebraOrthogonalBasis`](@ref) | |
4147
| `adjoint_action` | [`adjoint`](@ref) | now implemented with a default, when you provide [`diff_conjugate!`](@ref).
48+
| `adjoint_matrix(G, p, b)` | [`jacobian_conjugate`](@ref)`(G, p, e, b)` | `e` is either the [`Identity`](@ref)`(G)` or its [`identity_element`](@ref)`(G)` |
4249
| `apply_diff` | [`diff_apply`](@ref) | modifiers (diff) come first, consistent with [`ManifoldsDiff.jl`](https://juliamanifolds.github.io/ManifoldDiff.jl/stable/) |
4350
| `apply_diff_group` | [`diff_group_apply`](@ref) | modifiers (diff/group) come first, consistent with [`ManifoldsDiff.jl`](https://juliamanifolds.github.io/ManifoldDiff.jl/stable/) |
4451
| | [`conjugate`](@ref), [`diff_conjugate`](@ref) | a new function to model ``c_g: \mathcal G → \mathcal G`` given by ``c_g(h) = g∘h∘g^{-1}`` |
@@ -53,6 +60,7 @@ The list is alphabetical, but first lists types, then functions
5360
| `inverse_translate(G, g, h, c)` | [`inv_left_compose`](@ref)`(G, g, h)`, [`inv_right_compose`](@ref)`(G, g, h)` | compute ``g^{-1}∘h`` and ``g∘h^{-1}``, resp. |
5461
| `inverse_translate_diff(G, g, h, X, LeftForwardAction())` | - | discontinued, use `diff_left_compose(G, inv(G,g), h)` |
5562
| `inverse_translate_diff(G, g, h, X, RightBackwardAction())` | - | discontinued, use `diff_left_compose(G, h, inv(G,g))` |
63+
| `jacobian_exp_argument(G, g, X, b)` | [`jacobian_exp`](@ref)`(G, g, X, b)` | the Jacobian of the exponential map w.r.t. an [`AbstractBasis`](@extref `ManifoldsBase.AbstractBasis`) of the [`LieAlgebra`](@ref). The old name is resevered for the Riemannian exponential map. |
5664
| `log(G, g, h)` | `log(`[`base_manifold`](@ref base_manifold(G::LieGroup))`(G), g, h)` | you can now access the previous defaults on the internal manifold whenever they do not agree with the invariant one |
5765
| `log_inv(G, g, h)` | [`log`](@ref log(G::LieGroup, g, h))`(G, g, h)` | the logarithmic map invariant to the group operation is the default on Lie groups here |
5866
| `log_lie(G, g)` | [`log`](@ref log(G::LieGroup, g))`(G, g)` | the (matrix/Lie group) logarithm |
@@ -62,7 +70,6 @@ The list is alphabetical, but first lists types, then functions
6270
| `translate(G, g, h)` | [`compose`](@ref)`(G, g, h)` | unified to `compose` |
6371
| `translate_diff(G, g, X, c)` | [`diff_left_compose`](@ref)`(G, g, h, X)`, [`diff_right_compose`](@ref)`(G, g, h, X)` | for compose ``g∘h`` the functions now specify whether the derivative is taken w.r.t. to the left (`g`) or right (`h`) argument |
6472
| `vee(G, p, X)` | [`vee`](@ref vee(G::LieAlgebra, X))`(`[`LieAlgebra`](@ref)`(G), X)` | hat/vee moved to using the new [`LieAlgebra`](@ref). The old format should still work. |
65-
| `VeeOrthogonalBasis` | [`DefaultLieAlgebraOrthogonalBasis`](@ref) | |
6673

6774
## Further notable changes
6875

ext/LieGroupsRecursiveArrayToolsExt/LieGroupsRecursiveArrayToolsExt.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
module LieGroupsRecursiveArrayToolsExt
22

33
using LieGroups
4+
# As long as Manifolds.jl exports these, we have to specify them here specifically
45
using RecursiveArrayTools: ArrayPartition
56
using LinearAlgebra
67
using ManifoldsBase
78
using ManifoldsBase: base_manifold, submanifold_components, submanifold_component
9+
# Specify those that are imported twice to use the ones from LieGroups
10+
811

912
include("special_euclidean_group_RAT_ext.jl")
1013
include("special_galilean_group_RAT_ext.jl")

ext/LieGroupsRecursiveArrayToolsExt/special_euclidean_group_RAT_ext.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,41 @@
11
# disable affine check
22
LieGroups._check_matrix_affine(::ArrayPartition, ::Int; kwargs...) = nothing
33

4+
#
5+
# Action
6+
#
7+
8+
# (a) SE(n) on R^n
9+
# Euclidean was imported to LieGroups, so we can access it from there.
10+
function LieGroups.apply!(
11+
::GroupAction{LeftMultiplicationGroupAction, <:LieGroups.LeftSpecialEuclideanGroup, <:LieGroups.Euclidean}, q, g::ArrayPartition, p
12+
)
13+
mul!(q, g.x[1], p)
14+
q .+= g.x[2]
15+
return q
16+
end
17+
function LieGroups.apply!(
18+
::GroupAction{LieGroups.LeftMultiplicationGroupAction, <:LieGroups.RightSpecialEuclideanGroup, <:LieGroups.Euclidean}, q, g::ArrayPartition, p
19+
)
20+
mul!(q, g.x[2], p)
21+
q .+= g.x[1]
22+
return q
23+
end
24+
25+
function LieGroups.diff_apply!(
26+
::GroupAction{LieGroups.LeftMultiplicationGroupAction, <:LieGroups.LeftSpecialEuclideanGroup, <:LieGroups.Euclidean},
27+
Y, g::ArrayPartition, p, X
28+
)
29+
mul!(Y, g.x[1], X)
30+
return Y
31+
end
32+
function LieGroups.diff_apply!(
33+
::GroupAction{LieGroups.LeftMultiplicationGroupAction, <:LieGroups.RightSpecialEuclideanGroup, <:LieGroups.Euclidean},
34+
Y, g::ArrayPartition, p, X
35+
)
36+
mul!(Y, g.x[2], X)
37+
return Y
38+
end
439
#
540
# Conversions
641
#

src/LieGroups.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,13 @@ include("group_operations/multiplication_operation_abelian.jl")
6363

6464
# Actions
6565
include("group_actions/group_action_interface.jl")
66+
include("group_actions/addition_action.jl")
6667
include("group_actions/group_operation_action.jl")
6768
include("group_actions/multiplication_action.jl")
69+
include("group_actions/rotation_around_axis_action.jl")
70+
# These might use some of the above so we include them second
71+
include("group_actions/columnwise_action.jl")
72+
include("group_actions/rowwise_action.jl")
6873

6974
# Meta Lie groups
7075
include("groups/power_group.jl")
@@ -112,15 +117,18 @@ export PowerGroupOperation, ProductGroupOperation
112117
export LeftSemidirectProductGroupOperation, RightSemidirectProductGroupOperation
113118

114119
#
115-
#1,
120+
#
116121
# Group Actions
117122
export AbstractGroupActionType
118123
export AbstractLeftGroupActionType, AbstractRightGroupActionType
124+
export AdditionGroupAction
119125
export LeftGroupOperationAction, RightGroupOperationAction
120126
export GroupAction, GroupOperationAction
121127
export LeftMultiplicationGroupAction
122128
export InverseLeftGroupOperationAction, InverseRightGroupOperationAction
123129
export AbstractActionActsOnType, ActionActsOnLeft, ActionActsOnRight
130+
export RotationAroundAxisAction
131+
export ColumnwiseGroupAction, RowwiseGroupAction
124132

125133
#
126134
#
@@ -170,6 +178,7 @@ export identity_element, identity_element!, is_identity, inner
170178
export inv, inv!, diff_inv, diff_inv!
171179
export injectivity_radius
172180
export jacobian_conjugate, jacobian_conjugate!
181+
export jacobian_exp, jacobian_exp!
173182
export lie_bracket, lie_bracket!, log, log!
174183
export manifold_dimension
175184
export norm, number_of_coordinates
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
AdditionGroupAction <: AbstractLeftGroupActionType
3+
4+
Specify that in a [`GroupAction`](@ref) with Lie group ``$(_tex(:Cal, "G"))``
5+
and manifold ``$(_tex(:Cal, "M"))``, where the group action is given by addition
6+
7+
Given an element ``g ∈ $(_tex(:Cal, "G"))`` and a point ``p ∈ $(_tex(:Cal, "M"))``,
8+
the family of actions ``σ_g: $(_tex(:Cal, "M"))$(_tex(:Cal, "M"))`` is given by
9+
10+
```math
11+
σ_g(p) = g + p
12+
```
13+
14+
where ``+`` denotes the vector or matrix addition.
15+
"""
16+
struct AdditionGroupAction <: AbstractLeftGroupActionType end
17+
18+
function apply!(::GroupAction{AdditionGroupAction}, q, g, p)
19+
return q .= g .+ p
20+
end
21+
22+
function diff_apply!(::GroupAction{AdditionGroupAction}, Y, g, p, X)
23+
return Y .= X
24+
end
25+
26+
function diff_group_apply!(::GroupAction{AdditionGroupAction}, Y, g, p, X)
27+
return Y .= X
28+
end

0 commit comments

Comments
 (0)