An interface for Lie groups
LieGroups.LieGroup
— TypeLieGroup{𝔽, O<:AbstractGroupOperation, M<:AbstractManifold{𝔽}} <: AbstractManifold{𝔽}
Represent a Lie Group $\mathcal G$.
A Lie Group $\mathcal G$ is a group endowed with the structure of a manifold such that the group operations $∘: \mathcal G×\mathcal G → \mathcal G$, see compose
and the inverse operation $⋅^{-1}: \mathcal G → \mathcal G$, see inv
are smooth, see for example [HN12, Definition 9.1.1].
Lie groups are named after the Norwegian mathematician Marius Sophus Lie (1842–1899).
Fields
manifold
: anAbstractManifold
$\mathcal M$op
: anAbstractGroupOperation
$∘$ on that manifold
Constructor
LieGroup(M::AbstractManifold, op::AbstractGroupOperation)
Generate a Lie group based on a manifold M
and a group operation op
, where vectors by default are stored in the Lie Algebra.
LieGroups.AbstractLieAlgebraTangentVector
— TypeAbstractLieAlgebraTangentVector <: ManifoldsBase.AbstractTangentVector
An abstract type for a tangent vector represented in a LieAlgebra
.
While an tangent vectors are usually kept untyped for flexibility, it might be necessary to distinguish different types of points, for example
- for complicated representations that require a struct
@ semantic verification
- when there exist different representations
By sub-typing the AbstractManifoldPoint
, this follows the same idea as in ManifoldsBase.jl
.
LieGroups.AbstractLieGroupPoint
— TypeAbstractLieGroupPoint <: ManifoldsBase.AbstractManifoldPoint end
An abstract type for a point on a LieGroup
. While an points and tangent vectors are usually kept untyped for flexibility, it might be necessary to distinguish different types of points, for example
- for complicated representations that require a struct
- semantic verification
- when there exist different representations
By sub-typing the AbstractManifoldPoint
, this follows the same idea as in ManifoldsBase.jl
.
Functions on Lie groups
Base.adjoint
— Methodadjoint(G::LieGroup, g, X)
adjoint!(G::LieGroup, Y, g, X)
Compute the adjoint $\mathrm{Ad}(g): \mathfrak g → \mathfrak g$, which is defined as the differential diff_conjugate
of the conjugate
$c_g(h) = g∘h∘g^{-1}$ evaluated at the Identity
$h=\mathrm{e}$. The operation can be performed in-place of Y
.
\[ \mathrm{Ad}(g)[X] = D c_g(\mathrm{e}) [X], \qquad X ∈ \mathfrak g.\]
see [HN12, Section 9.2.3].
On matrix Lie groups the adjoint reads $\mathrm{Ad}(g)[X] = g∘X∘g^{-1}$.
Base.exp
— Methodexp(G::LieGroup, g, X)
exp!(G::LieGroup, h, g, X)
Compute the Lie group exponential map for $g∈\mathcal G$ and $X∈\mathfrak g$, where $\mathfrak g$ denotes the LieAlgebra
of $\mathcal G$. It is given by
\[\exp_g X = g∘\exp_{\mathcal G}(X)\]
where X
can be scaled by t
, the computation can be performed in-place of h
, and $\exp_{\mathcal G}$ denotes the Lie group exponential function.
If g
is the Identity
the Lie group exponential function $\exp_{\mathcal G}$ is computed directly. Implementing the Lie group exponential function introduces a default implementation with the formula above.
The Lie group exponential map is usually different from the exponential map with respect to the metric of the underlying Riemannian manifold $\mathcal M$. To access the (Riemannian) exponential map, use exp(
base_manifold
(G), g, X)
.
Base.exp
— Methodexp(G::LieGroup, X::T)
exp!(G::LieGroup, g, X)
Compute the (Lie group) exponential function
\[\exp_{\mathcal G}: \mathfrak g → \mathcal G,\qquad \exp_{\mathcal G}(X) = γ_X(1),\]
where $γ_X$ is the unique solution of the initial value problem
\[γ(0) = \mathrm{e}, \quad γ'(s) = γ(s)⋅X.\]
See also [HN12, Definition 9.2.2]. On matrix Lie groups this is the same as the matrix exponential.
The computation can be performed in-place of g
.
There are at least two different objects usually called “exponential” that need to be distinguished
- the (Riemannian) exponential map
exp(M, p, X)
fromManifoldsBase.jl
. This can be accessed here usingexp(base_manifold(G), p, X)
- the exponential map for a (left/right/bi-invariant) Cartan-Schouten (pseudo-)metric
exp(G, g, X)
, which we use as a default within this package - the (matrix/Lie group) exponential function
exp(G, g)
which agrees with the previous one forg
being the identity there.
Base.inv
— Methodinv(G::LieGroup, g)
inv!(G::LieGroup, h, g)
Compute the inverse group element $g^{-1}$ with respect to the AbstractGroupOperation
$∘$ on the LieGroup
$\mathcal G$, that is, return the unique element $h=g^{-1}$ such that $h∘g=\mathrm{e}$, where $\mathrm{e}$ denotes the Identity
.
This can be done in-place of h
, without side effects, that is you can do inv!(G, g, g)
.
Base.isapprox
— Methodisapprox(M::LieGroup, g, h; kwargs...)
Check if points g
and h
from LieGroup
are approximately equal. this function calls the corresponding isapprox
on the AbstractManifold
after handling the cases where one or more of the points are the Identity
. All keyword argments are passed to this function as well.
Base.log
— Methodlog(G::LieGroup, g, h)
log!(G::LieGroup, X, g, h)
Compute the Lie group logarithmic map $\log_g: \mathcal G → \mathfrak g$, where $\mathfrak g$ denotes the LieAlgebra
of $\mathcal G$. It is given by
\[\log_g h = \log_{\mathcal G}(g^{-1}∘h)\]
where $\log_{\mathcal G}$ denotes the Lie group logarithmic function The computation can be performed in-place of X
.
There are at least two different objects usually called “logarithm” that need to be distinguished
- the (Riemannian) logarithmic map
log(M, p, X)
fromManifoldsBase.jl
- the exponential map for a (left/right/bi-invariant) Cartan-Schouten (pseudo-)metric
exp(G, g, X)
, which we use as a default within this package - the (matrix/Lie group) exponential function
exp(G, g)
which agrees with the previous one forg
being the identity there.
Base.log
— Methodlog(G::LieGroup, g, h)
log(G::LieGroup, g)
log(G::LieGroup, g::Identity, T)
log!(G::LieGroup, X::T, g)
Compute the (Lie group) logarithmic function $\log_{\mathcal G}: \mathcal G → \mathfrak g$, which is the inverse of the Lie group exponential function. For the allocating variant, you can specify the type T
, when the point argument is the identity and hence does not provide the representation used. The computation can be performed in-place of X::T
, which then determines the type.
There are at least two different objects usually called “logarithm” that need to be distinguished
- the (Riemannian) logarithm map
log(M, p, q)
fromManifoldsBase.jl
. This can be accessed here usinglog(base_manifold(G), p, q)
. - the logarithmic map for a (left/right/bi-invariant) Cartan-Schouten (pseudo-)metric
log(G, g, h)
, which we use as a default within this package - the (matrix/Lie group) logarithm function
log(G, h)
which agrees with the previous one forg
being the identity there.
Base.rand
— Methodrand(::LieGroup; vector_at=nothing, σ::Real=1.0, kwargs...)
rand(::LieGroup, PT::Type; vector_at=nothing, σ::Real=1.0, kwargs...)
rand!(::LieAlgebra, T::Type; σ::Real=1.0, kwargs...)
rand!(::LieGroup, gX::PT; vector_at=nothing, σ::Real=1.0, kwargs...)
rand!(::LieAlgebra, X::T; σ::Real=1.0, kwargs...)
Compute a random point or tangent vector on a Lie group.
For points this just means to generate a random point on the underlying manifold itself.
For tangent vectors, an element in the Lie Algebra is generated, see also rand(::LieAlgebra; kwargs...)
For both cases, you can provide the type $T$ for the tangent vector and/or point $PT$, if you want to generate a random point in a certain representation. For the in-place variants the type is inferred from pX´ and
X`, respectively.
Base.rand
— Methodrand(::LieGroup; vector_at=nothing, σ::Real=1.0, kwargs...)
rand(::LieGroup, PT::Type; vector_at=nothing, σ::Real=1.0, kwargs...)
rand!(::LieAlgebra, T::Type; σ::Real=1.0, kwargs...)
rand!(::LieGroup, gX::PT; vector_at=nothing, σ::Real=1.0, kwargs...)
rand!(::LieAlgebra, X::T; σ::Real=1.0, kwargs...)
Compute a random point or tangent vector on a Lie group.
For points this just means to generate a random point on the underlying manifold itself.
For tangent vectors, an element in the Lie Algebra is generated, see also rand(::LieAlgebra; kwargs...)
For both cases, you can provide the type $T$ for the tangent vector and/or point $PT$, if you want to generate a random point in a certain representation. For the in-place variants the type is inferred from pX´ and
X`, respectively.
LieGroups.compose!
— Methodcompose(G::LieGroup, g, h)
compose!(G::LieGroup, k, g, h)
Perform the group operation $g ∘ h$ for two $g, h ∈ \mathcal G$ on the LieGroup
G
. This can also be done in-place of h
.
This function also handles the case where g
or/and h
are the Identity
(G)
. Since this would lead to ambiguities when implementing a new group operations, this function calls _compose
and _compose!
, respectively, which is meant for the actual computation of group operations on (non-Identity
` but maybe its numerical representation) elements.
LieGroups.conjugate!
— Methodconjugate(G::LieGroup, g, h)
conjugate!(G::LieGroup, k, g, h)
Compute the conjugation map $c_g: \mathcal G → \mathcal G$ given by $c_g(h) = g∘h∘g^{-1}$. This can be done in-place of k
.
LieGroups.conjugate
— Methodconjugate(G::LieGroup, g, h)
conjugate!(G::LieGroup, k, g, h)
Compute the conjugation map $c_g: \mathcal G → \mathcal G$ given by $c_g(h) = g∘h∘g^{-1}$. This can be done in-place of k
.
LieGroups.diff_conjugate!
— Methoddiff_conjugate(G::LieGroup, g, h, X)
diff_conjugate!(G::LieGroup, Y, g, h, X)
Compute the differential of the conjugate
$c_g(h) = g∘h∘g^{-1}$, which can be performed in-place of Y
.
\[ D(c_g(h))[X], \qquad X ∈ \mathfrak g.\]
LieGroups.diff_conjugate
— Methoddiff_conjugate(G::LieGroup, g, h, X)
diff_conjugate!(G::LieGroup, Y, g, h, X)
Compute the differential of the conjugate
$c_g(h) = g∘h∘g^{-1}$, which can be performed in-place of Y
.
\[ D(c_g(h))[X], \qquad X ∈ \mathfrak g.\]
LieGroups.diff_inv!
— Methoddiff_inv(G::LieGroup, g, X)
diff_inv!(G::LieGroup, Y, g, X)
Compute the differential of the function $ι_{\mathcal G}(g) = g^{-1}$, where $Dι_{\mathcal G}(g): \mathfrak g → \mathfrak g$. This can be done in-place of Y
.
LieGroups.diff_inv
— Methoddiff_inv(G::LieGroup, g, X)
diff_inv!(G::LieGroup, Y, g, X)
Compute the differential of the function $ι_{\mathcal G}(g) = g^{-1}$, where $Dι_{\mathcal G}(g): \mathfrak g → \mathfrak g$. This can be done in-place of Y
.
LieGroups.diff_left_compose!
— Methoddiff_left_compose(G::LieGroup, g, h, X)
diff_left_compose!(G::LieGroup, Y, g, h, X)
Compute the differential of the left group multiplication $λ_g(h) = g∘h$, on the LieGroup
G
, that is Compute $Dλ_g(h)[X]$, $X ∈ 𝔤$. This can be done in-place of Y
.
LieGroups.diff_left_compose
— Methoddiff_left_compose(G::LieGroup, g, h, X)
diff_left_compose!(G::LieGroup, Y, g, h, X)
Compute the differential of the left group multiplication $λ_g(h) = g∘h$, on the LieGroup
G
, that is Compute $Dλ_g(h)[X]$, $X ∈ 𝔤$. This can be done in-place of Y
.
LieGroups.diff_right_compose!
— Methoddiff_right_compose(G::LieGroup, h, g, X)
diff_right_compose!(G::LieGroup, Y, h, g, X)
Compute the differential of the right group multiplication $ρ_g(h) = h∘g$, on the LieGroup
G
, that is Compute $Dρ_g(h)[X]$, $X ∈ 𝔤$ This can be done in-place of Y
.
LieGroups.diff_right_compose
— Methoddiff_right_compose(G::LieGroup, h, g, X)
diff_right_compose!(G::LieGroup, Y, h, g, X)
Compute the differential of the right group multiplication $ρ_g(h) = h∘g$, on the LieGroup
G
, that is Compute $Dρ_g(h)[X]$, $X ∈ 𝔤$ This can be done in-place of Y
.
LieGroups.identity_element!
— Methodidentity_element(G::LieGroup)
identity_element(G::LieGroup, T)
identity_element!(G::LieGroup, e::T)
Return a point representation of the Identity
on the LieGroup
G
. By default this representation is the default array or number representation. If there exist several representations, the type T
can be used to distinguish between them, and it should be provided for both the AbstractLieGroupPoint
as well as the AbstractLieAlgebraTangentVector
if they differ, since maybe only one of these types might be available for the second signature.
It returns the corresponding default representation of $e$ as a point on G
. This can be performed in-place of e
.
LieGroups.inv!
— Methodinv(G::LieGroup, g)
inv!(G::LieGroup, h, g)
Compute the inverse group element $g^{-1}$ with respect to the AbstractGroupOperation
$∘$ on the LieGroup
$\mathcal G$, that is, return the unique element $h=g^{-1}$ such that $h∘g=\mathrm{e}$, where $\mathrm{e}$ denotes the Identity
.
This can be done in-place of h
, without side effects, that is you can do inv!(G, g, g)
.
LieGroups.inv_left_compose!
— Methodcompose(G::LieGroup, g, h)
compose!(G::LieGroup, k, g, h)
Perform the group operation $g ∘ h$ for two $g, h ∈ \mathcal G$ on the LieGroup
G
. This can also be done in-place of h
.
This function also handles the case where g
or/and h
are the Identity
(G)
. Since this would lead to ambiguities when implementing a new group operations, this function calls _compose
and _compose!
, respectively, which is meant for the actual computation of group operations on (non-Identity
` but maybe its numerical representation) elements.
LieGroups.inv_left_compose
— Methodinv_left_compose(G::LieGroup, g, h)
inv_left_compose!(G::LieGroup, k, g, h)
Compute the inverse of the left group operation $λ_g(h) = g∘h$, on the LieGroup
G
, that is, compute $λ_g^{-1}(h) = g^{-1}∘h$. This can be done in-place of k
.
LieGroups.inv_right_compose!
— Methodinv_right_compose(G::LieGroup, h, g)
inv_right_compose!(G::LieGroup, k, h, g)
Compute the inverse of the right group operation $ρ_g(h) = h∘g$, on the LieGroup
G
, that is compute $ρ_g^{-1}(h) = h∘g^{-1}$. This can be done in-place of k
.
LieGroups.inv_right_compose
— Methodinv_right_compose(G::LieGroup, h, g)
inv_right_compose!(G::LieGroup, k, h, g)
Compute the inverse of the right group operation $ρ_g(h) = h∘g$, on the LieGroup
G
, that is compute $ρ_g^{-1}(h) = h∘g^{-1}$. This can be done in-place of k
.
LieGroups.jacobian_conjugate
— Functionjacobian_conjugate(G::LieGroup, g, h, B::AbstractBasis=DefaultLieAlgebraOrthogonalBasis())
jacobian_conjugate!(G::LieGroup, J, g, h, B::AbstractBasis=DefaultLieAlgebraOrthogonalBasis())
Compute the Jacobian of the conjugate
$c_g(h) = g∘h∘g^{-1}$, with respect to an AbstractBasis
.
This can be seen as a matrix representation of the diff_conjugate
$D(c_g(h))[X]$ with respect to the given basis.
LieGroups.jacobian_conjugate!
— Methodjacobian_conjugate(G::LieGroup, g, h, B::AbstractBasis=DefaultLieAlgebraOrthogonalBasis())
jacobian_conjugate!(G::LieGroup, J, g, h, B::AbstractBasis=DefaultLieAlgebraOrthogonalBasis())
Compute the Jacobian of the conjugate
$c_g(h) = g∘h∘g^{-1}$, with respect to an AbstractBasis
.
This can be seen as a matrix representation of the diff_conjugate
$D(c_g(h))[X]$ with respect to the given basis.
LinearAlgebra.adjoint!
— Methodadjoint(G::LieGroup, g, X)
adjoint!(G::LieGroup, Y, g, X)
Compute the adjoint $\mathrm{Ad}(g): \mathfrak g → \mathfrak g$, which is defined as the differential diff_conjugate
of the conjugate
$c_g(h) = g∘h∘g^{-1}$ evaluated at the Identity
$h=\mathrm{e}$. The operation can be performed in-place of Y
.
\[ \mathrm{Ad}(g)[X] = D c_g(\mathrm{e}) [X], \qquad X ∈ \mathfrak g.\]
see [HN12, Section 9.2.3].
On matrix Lie groups the adjoint reads $\mathrm{Ad}(g)[X] = g∘X∘g^{-1}$.
Manifolds.compose
— Methodcompose(G::LieGroup, g, h)
compose!(G::LieGroup, k, g, h)
Perform the group operation $g ∘ h$ for two $g, h ∈ \mathcal G$ on the LieGroup
G
. This can also be done in-place of h
.
This function also handles the case where g
or/and h
are the Identity
(G)
. Since this would lead to ambiguities when implementing a new group operations, this function calls _compose
and _compose!
, respectively, which is meant for the actual computation of group operations on (non-Identity
` but maybe its numerical representation) elements.
Manifolds.identity_element
— Methodidentity_element(G::LieGroup)
identity_element(G::LieGroup, T)
identity_element!(G::LieGroup, e::T)
Return a point representation of the Identity
on the LieGroup
G
. By default this representation is the default array or number representation. If there exist several representations, the type T
can be used to distinguish between them, and it should be provided for both the AbstractLieGroupPoint
as well as the AbstractLieAlgebraTangentVector
if they differ, since maybe only one of these types might be available for the second signature.
It returns the corresponding default representation of $e$ as a point on G
. This can be performed in-place of e
.
Manifolds.is_identity
— Methodis_identity(G::LieGroup, q; kwargs...)
Check whether q
is the identity on the LieGroup
$\mathcal G$. This means it is either the Identity
{O}
with the respect to the corresponding AbstractGroupOperation
O
, or (approximately) the correct point representation.
See also
ManifoldsBase.base_manifold
— Methodbase_manifold(G::LieGroup)
Return the manifold stored within the LieGroup
G
.
ManifoldsBase.exp!
— Methodexp(G::LieGroup, g, X)
exp!(G::LieGroup, h, g, X)
Compute the Lie group exponential map for $g∈\mathcal G$ and $X∈\mathfrak g$, where $\mathfrak g$ denotes the LieAlgebra
of $\mathcal G$. It is given by
\[\exp_g X = g∘\exp_{\mathcal G}(X)\]
where X
can be scaled by t
, the computation can be performed in-place of h
, and $\exp_{\mathcal G}$ denotes the Lie group exponential function.
If g
is the Identity
the Lie group exponential function $\exp_{\mathcal G}$ is computed directly. Implementing the Lie group exponential function introduces a default implementation with the formula above.
The Lie group exponential map is usually different from the exponential map with respect to the metric of the underlying Riemannian manifold $\mathcal M$. To access the (Riemannian) exponential map, use exp(
base_manifold
(G), g, X)
.
ManifoldsBase.exp!
— Methodexp(G::LieGroup, X::T)
exp!(G::LieGroup, g, X)
Compute the (Lie group) exponential function
\[\exp_{\mathcal G}: \mathfrak g → \mathcal G,\qquad \exp_{\mathcal G}(X) = γ_X(1),\]
where $γ_X$ is the unique solution of the initial value problem
\[γ(0) = \mathrm{e}, \quad γ'(s) = γ(s)⋅X.\]
See also [HN12, Definition 9.2.2]. On matrix Lie groups this is the same as the matrix exponential.
The computation can be performed in-place of g
.
There are at least two different objects usually called “exponential” that need to be distinguished
- the (Riemannian) exponential map
exp(M, p, X)
fromManifoldsBase.jl
. This can be accessed here usingexp(base_manifold(G), p, X)
- the exponential map for a (left/right/bi-invariant) Cartan-Schouten (pseudo-)metric
exp(G, g, X)
, which we use as a default within this package - the (matrix/Lie group) exponential function
exp(G, g)
which agrees with the previous one forg
being the identity there.
ManifoldsBase.is_point
— Methodis_point(G::LieGroup, g; kwargs...)
Check whether g
is a valid point on the Lie Group G
. This falls back to checking whether g
is a valid point on the base_manifold
G
. unless g
is an Identity
. Then, it is checked whether it is the identity element corresponding to G
.
ManifoldsBase.log!
— Methodlog(G::LieGroup, g, h)
log!(G::LieGroup, X, g, h)
Compute the Lie group logarithmic map $\log_g: \mathcal G → \mathfrak g$, where $\mathfrak g$ denotes the LieAlgebra
of $\mathcal G$. It is given by
\[\log_g h = \log_{\mathcal G}(g^{-1}∘h)\]
where $\log_{\mathcal G}$ denotes the Lie group logarithmic function The computation can be performed in-place of X
.
There are at least two different objects usually called “logarithm” that need to be distinguished
- the (Riemannian) logarithmic map
log(M, p, X)
fromManifoldsBase.jl
- the exponential map for a (left/right/bi-invariant) Cartan-Schouten (pseudo-)metric
exp(G, g, X)
, which we use as a default within this package - the (matrix/Lie group) exponential function
exp(G, g)
which agrees with the previous one forg
being the identity there.
ManifoldsBase.log!
— Methodlog(G::LieGroup, g, h)
log(G::LieGroup, g)
log(G::LieGroup, g::Identity, T)
log!(G::LieGroup, X::T, g)
Compute the (Lie group) logarithmic function $\log_{\mathcal G}: \mathcal G → \mathfrak g$, which is the inverse of the Lie group exponential function. For the allocating variant, you can specify the type T
, when the point argument is the identity and hence does not provide the representation used. The computation can be performed in-place of X::T
, which then determines the type.
There are at least two different objects usually called “logarithm” that need to be distinguished
- the (Riemannian) logarithm map
log(M, p, q)
fromManifoldsBase.jl
. This can be accessed here usinglog(base_manifold(G), p, q)
. - the logarithmic map for a (left/right/bi-invariant) Cartan-Schouten (pseudo-)metric
log(G, g, h)
, which we use as a default within this package - the (matrix/Lie group) logarithm function
log(G, h)
which agrees with the previous one forg
being the identity there.
Random.rand!
— Methodrand(::LieGroup; vector_at=nothing, σ::Real=1.0, kwargs...)
rand(::LieGroup, PT::Type; vector_at=nothing, σ::Real=1.0, kwargs...)
rand!(::LieAlgebra, T::Type; σ::Real=1.0, kwargs...)
rand!(::LieGroup, gX::PT; vector_at=nothing, σ::Real=1.0, kwargs...)
rand!(::LieAlgebra, X::T; σ::Real=1.0, kwargs...)
Compute a random point or tangent vector on a Lie group.
For points this just means to generate a random point on the underlying manifold itself.
For tangent vectors, an element in the Lie Algebra is generated, see also rand(::LieAlgebra; kwargs...)
For both cases, you can provide the type $T$ for the tangent vector and/or point $PT$, if you want to generate a random point in a certain representation. For the in-place variants the type is inferred from pX´ and
X`, respectively.
Internal functions and macros
LieGroups.CommonUnitarySubAlgebra
— TypeCommonUnitarySubAlgebra{𝔽,T}
A constant that allows to refer to several sub Algebras of $\mathfrak u(n)$ for implementations where
- certain sub algebras real/complex share a common implementation, e.g. for the same sizes
T
usually viaTypeParameter
- certain functions are the same for all sizes
T
as long as the field𝔽
is the same
LieGroups.@default_lie_group_fallbacks
— Macrodefault_lie_group_fallbacks(TG, TF, TP, TV, pfield::Symbol, Xfield::Symbol, groupOp)
Introduce default fallbacks for all basic functions on Lie groups, for Lie group of type TG
with group operation Op
, points of type TP
, tangent vectors of type TV
, with forwarding to fields pfield
and Xfield
for point and tangent vector functions, respectively.
Literature
- [HN12]
- J. Hilgert and K.-H. Neeb. Structure and Geometry of Lie Groups (Springer Monographs in Mathematics, 2012).
- [SDA21]
- J. Solà, J. Deray and D. Atchuthan. A micro Lie theory for state estimation in robotics (Dec 2021), arXiv:1812.01537 [cs.RO], arXiv: 1812.01537.