## Retractions and inverse Retractions

The exponential and logarithmic map might be too expensive to evaluate or not be available in a very stable numerical way on certain manifolds $\mathcal M$. Retractions provide a possibly cheap, fast and stable alternative.

A *retraction* $\operatorname{retr}_p: T_p\mathcal M → \mathcal M$ is a smooth map that fulfils (for all $p∈\mathcal M$) that

- $\operatorname{retr}_p(0) = p$
- $D\operatorname{retr}_p(0): T_p\mathcal M \to T_p\mathcal M$ is the identity map,

i.e. $D\operatorname{retr}_p(0)[X]=X$ holds for all $X∈ T_p\mathcal M$,

where $D\operatorname{retr}_p$ denotes the differential of the retraction.

A retraction $\operatorname{retr}_p$ can be interpreted as a first order approximation to the exponential map $\exp_p$.

The retraction is called of second order if for all $X$ the curves $c(t) = R_p(tX)$ have a zero acceleration at $t=0$, i.e. $c''(0) = 0$.

The following figure compares the exponential map `exp`

`(M, p, X)`

on the Circle `(ℂ)`

(or `Sphere`

`(1)`

embedded in $ℝ^2$ with one possible retraction, the one based on projections. Note especially that $\operatorname{dist}(p,q)=\lVert X\rVert_p$ while this is not the case for the result $\operatorname{retr}_p(X) = q'$.

Similar to the `exp`

onential map the `retract`

ion might not be globally invertible, but locally it is. So locally one can define the inverse retraction $\operatorname{retr}_p^{-1}\colon \mathcal M \to T_p\mathcal M$, which can be seen as a first order approximation to the `log`

arithmic map. Within the `ManifoldsBase.jl`

interface the inverse retraction is called `inverse_retract`

.

The general interface looks as follows.

`ManifoldsBase.default_inverse_retraction_method`

— Method```
default_inverse_retraction_method(M::AbstractManifold)
default_inverse_retraction_method(M::AbstractManifold, ::Type{T}) where {T}
```

The `AbstractInverseRetractionMethod`

that is used when calling `inverse_retract`

without specifying the inverse retraction method. By default, this is the `LogarithmicInverseRetraction`

.

This method can also be specified more precisely with a point type `T`

, for the case that on a `M`

there are two different representations of points, which provide different inverse retraction methods.

`ManifoldsBase.default_retraction_method`

— Method```
default_retraction_method(M::AbstractManifold)
default_retraction_method(M::AbstractManifold, ::Type{T}) where {T}
```

The `AbstractRetractionMethod`

that is used when calling `retract`

without specifying the retraction method. By default, this is the `ExponentialRetraction`

.

This method can also be specified more precisely with a point type `T`

, for the case that on a `M`

there are two different representations of points, which provide different retraction methods.

`ManifoldsBase.inverse_retract`

— Function```
inverse_retract(M::AbstractManifold, p, q)
inverse_retract(M::AbstractManifold, p, q, method::AbstractInverseRetractionMethod
```

Compute the inverse retraction, a cheaper, approximate version of the `log`

arithmic map), of points `p`

and `q`

on the `AbstractManifold`

`M`

.

Inverse retraction method can be specified by the last argument, defaulting to `default_inverse_retraction_method`

`(M)`

. For available inverse retractions on certain manifolds see the documentation on the corresponding manifold.

See also `retract`

.

`ManifoldsBase.inverse_retract!`

— Function`inverse_retract!(M::AbstractManifold, X, p, q[, method::AbstractInverseRetractionMethod])`

Compute the inverse retraction, a cheaper, approximate version of the `log`

arithmic map), of points `p`

and `q`

on the `AbstractManifold`

`M`

. Result is saved to `X`

.

Inverse retraction method can be specified by the last argument, defaulting to `default_inverse_retraction_method`

`(M)`

. See the documentation of respective manifolds for available methods.

See also `retract!`

.

`ManifoldsBase.retract`

— Function```
retract(M::AbstractManifold, p, X, method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)))
retract(M::AbstractManifold, p, X, t::Number=1, method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)))
```

Compute a retraction, a cheaper, approximate version of the `exp`

onential map, from `p`

into direction `X`

, scaled by `t`

, on the `AbstractManifold`

`M`

.

A retraction $\operatorname{retr}_p: T_p\mathcal M → \mathcal M$ is a smooth map that fulfils

- $\operatorname{retr}_p(0) = p$
- $D\operatorname{retr}_p(0): T_p\mathcal M \to T_p\mathcal M$ is the identity map,

i.e. $D\operatorname{retr}_p(0)[X]=X$ holds for all $X\in T_p\mathcal M$,

where $D\operatorname{retr}_p$ denotes the differential of the retraction

The retraction is called of second order if for all $X$ the curves $c(t) = R_p(tX)$ have a zero acceleration at $t=0$, i.e. $c''(0) = 0$.

Retraction method can be specified by the last argument, defaulting to `default_retraction_method`

`(M)`

. For further available retractions see the documentation of respective manifolds.

Locally, the retraction is invertible. For the inverse operation, see `inverse_retract`

.

`ManifoldsBase.retract!`

— Function```
retract!(M::AbstractManifold, q, p, X)
retract!(M::AbstractManifold, q, p, X, t::Real=1)
retract!(M::AbstractManifold, q, p, X, method::AbstractRetractionMethod)
retract!(M::AbstractManifold, q, p, X, t::Real=1, method::AbstractRetractionMethod)
```

Compute a retraction, a cheaper, approximate version of the `exp`

onential map, from `p`

into direction `X`

, scaled by `t`

, on the `AbstractManifold`

manifold `M`

. Result is saved to `q`

.

Retraction method can be specified by the last argument, defaulting to `default_retraction_method`

`(M)`

. See the documentation of respective manifolds for available methods.

See `retract`

for more details.

## Types of Retractions

To distinguish different types of retractions, the last argument of the retraction as well as its inverse specifies a type. The following ones are available.

`ManifoldsBase.AbstractInverseRetractionMethod`

— Type`AbstractInverseRetractionMethod <: AbstractApproximationMethod`

Abstract type for methods for inverting a retraction (see `inverse_retract`

).

`ManifoldsBase.AbstractRetractionMethod`

— Type`AbstractRetractionMethod <: AbstractApproximationMethod`

Abstract type for methods for `retract`

ing a tangent vector to a manifold.

`ManifoldsBase.ApproximateInverseRetraction`

— Type`ApproximateInverseRetraction <: AbstractInverseRetractionMethod`

An abstract type for representing approximate inverse retraction methods.

`ManifoldsBase.ApproximateRetraction`

— Type`ApproximateRetraction <: AbstractRetractionMethod`

An abstract type for representing approximate retraction methods.

`ManifoldsBase.CayleyInverseRetraction`

— Type`CayleyInverseRetraction <: AbstractInverseRetractionMethod`

A retraction based on the Cayley transform, which is realized by using the `PadeRetraction`

`{1}`

.

Though you would call e.g. `inverse_retract`

`(M, p, q, CayleyInverseRetraction())`

, to implement an inverse caley retraction, define `inverse_retract_cayley!`

`(M, X, p, q)`

for your manifold `M`

. By default both these functions fall back to calling a `PadeInverseRetraction`

`(1)`

.

`ManifoldsBase.CayleyRetraction`

— Type`CayleyRetraction <: AbstractRetractionMethod`

A retraction based on the Cayley transform, which is realized by using the `PadeRetraction`

`{1}`

.

Though you would call e.g. `retract`

`(M, p, X, CayleyRetraction())`

, to implement a caley retraction, define `retract_cayley!`

`(M, q, p, X, t)`

for your manifold `M`

. By default both these functions fall back to calling a `PadeRetraction`

`(1)`

.

`ManifoldsBase.EmbeddedInverseRetraction`

— TypeEmbeddedInverseRetraction{T<:AbstractInverseRetractionMethod} <: AbstractInverseRetractionMethod

Compute an inverse retraction by using the inverse retraction of type `T`

in the embedding and projecting the result

**Constructor**

`EmbeddedInverseRetraction(r::AbstractInverseRetractionMethod)`

Generate the inverse retraction with inverse retraction `r`

to use in the embedding.

`ManifoldsBase.EmbeddedRetraction`

— Type`EmbeddedRetraction{T<:AbstractRetractionMethod} <: AbstractRetractionMethod`

Compute a retraction by using the retraction of type `T`

in the embedding and projecting the result.

**Constructor**

`EmbeddedRetraction(r::AbstractRetractionMethod)`

Generate the retraction with retraction `r`

to use in the embedding.

`ManifoldsBase.ExponentialRetraction`

— Type`ExponentialRetraction <: AbstractRetractionMethod`

Retraction using the exponential map.

`ManifoldsBase.InverseRetractionWithKeywords`

— Type`InverseRetractionWithKeywords{R<:AbstractRetractionMethod,K} <: AbstractInverseRetractionMethod`

Since inverse retractions might have keywords, this type is a way to set them as an own type to be used as a specific inverse retraction. Another reason for this type is that we dispatch on the inverse retraction first and only the last layer would be implemented with keywords, so this way they can be passed down.

**Fields**

`inverse_retraction`

the inverse retraction that is decorated with keywords`kwargs`

the keyword arguments

Note that you can nest this type. Then the most outer specification of a keyword is used.

**Constructor**

`InverseRetractionWithKeywords(m::T; kwargs...) where {T <: AbstractInverseRetractionMethod}`

Specify the subtype `T <:`

`AbstractInverseRetractionMethod`

to have keywords `kwargs...`

.

`ManifoldsBase.LogarithmicInverseRetraction`

— Type`LogarithmicInverseRetraction <: AbstractInverseRetractionMethod`

Inverse retraction using the `log`

arithmic map.

`ManifoldsBase.NLSolveInverseRetraction`

— Type```
NLSolveInverseRetraction{T<:AbstractRetractionMethod,TV,TK} <:
ApproximateInverseRetraction
```

An inverse retraction method for approximating the inverse of a retraction using `NLsolve`

.

**Constructor**

```
NLSolveInverseRetraction(
method::AbstractRetractionMethod[, X0];
project_tangent=false,
project_point=false,
nlsolve_kwargs...,
)
```

Constructs an approximate inverse retraction for the retraction `method`

with initial guess `X0`

, defaulting to the zero vector. If `project_tangent`

is `true`

, then the tangent vector is projected before the retraction using `project`

. If `project_point`

is `true`

, then the resulting point is projected after the retraction. `nlsolve_kwargs`

are keyword arguments passed to `NLsolve.nlsolve`

.

`ManifoldsBase.ODEExponentialRetraction`

— Type`ODEExponentialRetraction{T<:AbstractRetractionMethod, B<:AbstractBasis} <: AbstractRetractionMethod`

Approximate the exponential map on the manifold by evaluating the ODE descripting the geodesic at 1, assuming the default connection of the given manifold by solving the ordinary differential equation

\[\frac{d^2}{dt^2} p^k + Γ^k_{ij} \frac{d}{dt} p_i \frac{d}{dt} p_j = 0,\]

where $Γ^k_{ij}$ are the Christoffel symbols of the second kind, and the Einstein summation convention is assumed.

**Constructor**

```
ODEExponentialRetraction(
r::AbstractRetractionMethod,
b::AbstractBasis=DefaultOrthogonalBasis(),
)
```

Generate the retraction with a retraction to use internally (for some approaches) and a basis for the tangent space(s).

`ManifoldsBase.PadeInverseRetraction`

— Type`PadeInverseRetraction{m} <: AbstractInverseRetractionMethod`

An inverse retraction based on the Padé approximation of order $m$ for the retraction.

Though you would call e.g. `inverse_retract`

`(M, p, q, PadeInverseRetraction(m))`

, to implement an inverse Padé retraction, define `inverse_retract_pade!`

`(M, X, p, q, m)`

for your manifold `M`

.

`ManifoldsBase.PadeRetraction`

— Type`PadeRetraction{m} <: AbstractRetractionMethod`

A retraction based on the Padé approximation of order $m$

**Constructor**

`PadeRetraction(m::Int)`

Though you would call e.g. `retract`

`(M, p, X, PadeRetraction(m))`

, to implement a Padé retraction, define `retract_pade!`

`(M, q, p, X, t, m)`

for your manifold `M`

.

`ManifoldsBase.PolarInverseRetraction`

— Type`PolarInverseRetraction <: AbstractInverseRetractionMethod`

Inverse retractions that are based on a singular value decomposition of the matrix / matrices for point and tangent vector on a `AbstractManifold`

Though you would call e.g. `inverse_retract`

`(M, p, q, PolarInverseRetraction())`

, to implement an inverse polar retraction, define `inverse_retract_polar!`

`(M, X, p, q)`

for your manifold `M`

.

`ManifoldsBase.PolarRetraction`

— Type`PolarRetraction <: AbstractRetractionMethod`

Retractions that are based on singular value decompositions of the matrix / matrices for point and tangent vectors.

Though you would call e.g. `retract`

`(M, p, X, PolarRetraction())`

, to implement a polar retraction, define `retract_polar!`

`(M, q, p, X, t)`

for your manifold `M`

.

`ManifoldsBase.ProjectionInverseRetraction`

— Type`ProjectionInverseRetraction <: AbstractInverseRetractionMethod`

Inverse retractions that are based on a projection (or its inversion).

Though you would call e.g. `inverse_retract`

`(M, p, q, ProjectionInverseRetraction())`

, to implement an inverse projection retraction, define `inverse_retract_project!`

`(M, X, p, q)`

for your manifold `M`

.

`ManifoldsBase.ProjectionRetraction`

— Type`ProjectionRetraction <: AbstractRetractionMethod`

Retractions that are based on projection and usually addition in the embedding.

Though you would call e.g. `retract`

`(M, p, X, ProjectionRetraction())`

, to implement a projection retraction, define `retract_project!`

`(M, q, p, X, t)`

for your manifold `M`

.

`ManifoldsBase.QRInverseRetraction`

— Type`QRInverseRetraction <: AbstractInverseRetractionMethod`

Inverse retractions that are based on a QR decomposition of the matrix / matrices for point and tangent vector on a `AbstractManifold`

Though you would call e.g. `inverse_retract`

`(M, p, q, QRInverseRetraction())`

, to implement an inverse QR retraction, define `inverse_retract_qr!`

`(M, X, p, q)`

for your manifold `M`

.

`ManifoldsBase.QRRetraction`

— Type`QRRetraction <: AbstractRetractionMethod`

Retractions that are based on a QR decomposition of the matrix / matrices for point and tangent vector on a `AbstractManifold`

Though you would call e.g. `retract`

`(M, p, X, QRRetraction())`

, to implement a QR retraction, define `retract_qr!`

`(M, q, p, X, t)`

for your manifold `M`

.

`ManifoldsBase.RetractionWithKeywords`

— Type`RetractionWithKeywords{R<:AbstractRetractionMethod,K} <: AbstractRetractionMethod`

Since retractions might have keywords, this type is a way to set them as an own type to be used as a specific retraction. Another reason for this type is that we dispatch on the retraction first and only the last layer would be implemented with keywords, so this way they can be passed down.

**Fields**

`retraction`

the retraction that is decorated with keywords`kwargs`

the keyword arguments

Note that you can nest this type. Then the most outer specification of a keyword is used.

**Constructor**

`RetractionWithKeywords(m::T; kwargs...) where {T <: AbstractRetractionMethod}`

Specify the subtype `T <:`

`AbstractRetractionMethod`

to have keywords `kwargs...`

.

`ManifoldsBase.SasakiRetraction`

— Type`struct SasakiRetraction <: AbstractRetractionMethod end`

Exponential map on `TangentBundle`

computed via Euler integration as described in [MF12]. The system of equations for $\gamma : ℝ \to T\mathcal M$ such that $\gamma(1) = \exp_{p,X}(X_M, X_F)$ and $\gamma(0)=(p, X)$ reads

\[\dot{\gamma}(t) = (\dot{p}(t), \dot{X}(t)) = (R(X(t), \dot{X}(t))\dot{p}(t), 0)\]

where $R$ is the Riemann curvature tensor (see `riemann_tensor`

).

**Constructor**

`SasakiRetraction(L::Int)`

In this constructor `L`

is the number of integration steps.

`ManifoldsBase.SoftmaxInverseRetraction`

— Type`SoftmaxInverseRetraction <: AbstractInverseRetractionMethod`

Describes an inverse retraction that is based on the softmax function.

Though you would call e.g. `inverse_retract`

`(M, p, q, SoftmaxInverseRetraction())`

, to implement an inverse softmax retraction, define `inverse_retract_softmax!`

`(M, X, p, q)`

for your manifold `M`

.

`ManifoldsBase.SoftmaxRetraction`

— Type`SoftmaxRetraction <: AbstractRetractionMethod`

Describes a retraction that is based on the softmax function.

Though you would call e.g. `retract`

`(M, p, X, SoftmaxRetraction())`

, to implement a softmax retraction, define `retract_softmax!`

`(M, q, p, X, t)`

for your manifold `M`

.

`ManifoldsBase.ShootingInverseRetraction`

— Type`ShootingInverseRetraction <: ApproximateInverseRetraction`

Approximating the inverse of a retraction using the shooting method.

This implementation of the shooting method works by using another inverse retraction to form the first guess of the vector. This guess is updated by shooting the vector, guessing the vector pointing from the shooting result to the target point, and transporting this vector update back to the initial point on a discretized grid. This process is repeated until the norm of the vector update falls below a specified tolerance or the maximum number of iterations is reached.

**Fields**

`retraction::AbstractRetractionMethod`

: The retraction whose inverse is approximated.`initial_inverse_retraction::AbstractInverseRetractionMethod`

: The inverse retraction used to form the initial guess of the vector.`vector_transport::AbstractVectorTransportMethod`

: The vector transport used to transport the initial guess of the vector.`num_transport_points::Int`

: The number of discretization points used for vector transport in the shooting method. 2 is the minimum number of points, including just the endpoints.`tolerance::Real`

: The tolerance for the shooting method.`max_iterations::Int`

: The maximum number of iterations for the shooting method.

## The functions on layer 3

While you should always add your documentation to `retract`

or `retract!`

when implementing new manifolds, the actual implementation happens on the following functions on layer III.

`ManifoldsBase.inverse_retract_cayley!`

— Method`inverse_retract_cayley!(M::AbstractManifold, X, p, q)`

Compute the in-place variant of the `CayleyInverseRetraction`

, which by default calls the first order [`PadeInverseRetraction`

§(@ref).

`ManifoldsBase.inverse_retract_embedded!`

— Method`inverse_retract_embedded!(M::AbstractManifold, X, p, q, m::AbstractInverseRetractionMethod)`

Compute the in-place variant of the `EmbeddedInverseRetraction`

using the `AbstractInverseRetractionMethod`

`m`

in the embedding (see `get_embedding`

) and projecting the result back.

`ManifoldsBase.inverse_retract_nlsolve!`

— Method`inverse_retract_nlsolve!(M::AbstractManifold, X, p, q, m::NLSolveInverseRetraction)`

Compute the in-place variant of the `NLSolveInverseRetraction`

`m`

.

`ManifoldsBase.inverse_retract_pade!`

— Method`inverse_retract_pade!(M::AbstractManifold, p, q, n)`

Compute the in-place variant of the `PadeInverseRetraction`

`(n)`

,

`ManifoldsBase.inverse_retract_polar!`

— Method`inverse_retract_polar!(M::AbstractManifold, X, p, q)`

Compute the in-place variant of the `PolarInverseRetraction`

.

`ManifoldsBase.inverse_retract_project!`

— Method`inverse_retract_project!(M::AbstractManifold, X, p, q)`

Compute the in-place variant of the `ProjectionInverseRetraction`

.

`ManifoldsBase.inverse_retract_qr!`

— Method`inverse_retract_qr!(M::AbstractManifold, X, p, q)`

Compute the in-place variant of the `QRInverseRetraction`

.

`ManifoldsBase.inverse_retract_softmax!`

— Method`inverse_retract_softmax!(M::AbstractManifold, X, p, q)`

Compute the in-place variant of the `SoftmaxInverseRetraction`

.

`ManifoldsBase.retract_cayley!`

— Method`retract_cayley!(M::AbstractManifold, q, p, X, t)`

Compute the in-place variant of the `CayleyRetraction`

, which by default falls back to calling the first order `PadeRetraction`

.

`ManifoldsBase.retract_embedded!`

— Method`retract_embedded!(M::AbstractManifold, q, p, X, t, m::AbstractRetractionMethod)`

Compute the in-place variant of the `EmbeddedRetraction`

using the `AbstractRetractionMethod`

`m`

in the embedding (see `get_embedding`

) and projecting the result back.

`ManifoldsBase.retract_exp_ode!`

— Method`retract_exp_ode!(M::AbstractManifold, q, p, X, t, m::AbstractRetractionMethod, B::AbstractBasis)`

Compute the in-place variant of the `ODEExponentialRetraction`

`(m, B)`

.

`ManifoldsBase.retract_pade!`

— Method`retract_pade!(M::AbstractManifold, q, p, X, t, m::PadeRetraction)`

Compute the in-place variant of the `PadeRetraction`

`m`

.

`ManifoldsBase.retract_polar!`

— Method`retract_polar!(M::AbstractManifold, q, p, X, t)`

Compute the in-place variant of the `PolarRetraction`

.

`ManifoldsBase.retract_project!`

— Method`retract_project!(M::AbstractManifold, q, p, X, t)`

Compute the in-place variant of the `ProjectionRetraction`

.

`ManifoldsBase.retract_qr!`

— Method`retract_qr!(M::AbstractManifold, q, p, X, t)`

Compute the in-place variant of the `QRRetraction`

.

`ManifoldsBase.retract_sasaki!`

— Method`retract_sasaki!(M::AbstractManifold, q, p, X, t::Number, m::SasakiRetraction)`

Compute the in-place variant of the `SasakiRetraction`

`m`

.

`ManifoldsBase.retract_softmax!`

— Method`retract_softmax!(M::AbstractManifold, q, p, X, t)`

Compute the in-place variant of the `SoftmaxRetraction`

.

`ManifoldsBase.inverse_retract_shooting!`

— Method`inverse_retract_shooting!(M::AbstractManifold, X, p, q, m::ShootingInverseRetraction)`

Approximate the inverse of a retraction using the shooting method.