ManifoldsBase.jl
– an interface for manifolds
The interface for a manifold is provided in the lightweight package ManifoldsBase.jl. You can easily implement your algorithms and even your own manifolds just using the interface. All manifolds from the package here are also based on this interface, so any project based on the interface can benefit from all manifolds, as soon as a certain manifold provides implementations of the functions a project requires.
Additionally the AbstractDecoratorManifold
is provided as well as the ValidationManifold
as a specific example of such a decorator.
Types and functions
The following functions are currently available from the interface. If a manifold that you implement for your own package fits this interface, we happily look forward to a Pull Request to add it here.
ManifoldsBase.AbstractEstimationMethod
— TypeAbstractEstimationMethod
Abstract type for defining statistical estimation methods.
ManifoldsBase.AbstractInverseRetractionMethod
— TypeAbstractInverseRetractionMethod
Abstract type for methods for inverting a retraction (see inverse_retract
).
ManifoldsBase.AbstractRetractionMethod
— TypeAbstractRetractionMethod
Abstract type for methods for retract
ing a tangent vector to a manifold.
ManifoldsBase.CoTVector
— TypeCoTVector
Type for a cotangent vector of a manifold. While a Manifold
does not necessarily require this type, for example when it is implemented for Vector
s or Matrix
type elements, this type can be used for more complicated representations, semantic verification, or even dispatch for different representations of cotangent vectors and their types on a manifold.
ManifoldsBase.ExponentialRetraction
— TypeExponentialRetraction
Retraction using the exponential map.
ManifoldsBase.LogarithmicInverseRetraction
— TypeLogarithmicInverseRetraction
Inverse retraction using the log
arithmic map.
ManifoldsBase.MPoint
— TypeMPoint
Type for a point on a manifold. While a Manifold
does not necessarily require this type, for example when it is implemented for Vector
s or Matrix
type elements, this type can be used for more complicated representations, semantic verification, or even dispatch for different representations of points on a manifold.
ManifoldsBase.Manifold
— TypeManifold{F}
A manifold type. The Manifold
is used to dispatch to different functions on a manifold, usually as the first argument of the function. Examples are the exp
onential and log
arithmic maps as well as more general functions that are built on them like the geodesic
.
The manifold is parametrized by an AbstractNumbers
to distinguish for example real (ℝ) and complex (ℂ) manifolds.
For subtypes the preferred order of parameters is: size and simple value parameters, followed by the AbstractNumbers
field
, followed by data type parameters, which might depend on the abstract number field type.
ManifoldsBase.OutOfInjectivityRadiusError
— TypeOutOfInjectivityRadiusError
An error thrown when a function (for example log
arithmic map or inverse_retract
) is given arguments outside of its injectivity_radius
.
ManifoldsBase.PolarInverseRetraction
— TypePolarInverseRetraction <: AbstractInverseRetractionMethod
Inverse retractions that are based on a singular value decomposition of the matrix / matrices for point and tangent vector on a Manifold
ManifoldsBase.PolarRetraction
— TypePolarRetraction <: AbstractRetractionMethod
Retractions that are based on singular value decompositions of the matrix / matrices for point and tangent vector on a Manifold
ManifoldsBase.ProjectionInverseRetraction
— TypeProjectionInverseRetraction <: AbstractInverseRetractionMethod
Inverse retractions that are based on a projection (or its inversion).
ManifoldsBase.ProjectionRetraction
— TypeProjectionRetraction <: AbstractRetractionMethod
Retractions that are based on projection and usually addition in the embedding.
ManifoldsBase.QRInverseRetraction
— TypeQRInverseRetraction <: AbstractInverseRetractionMethod
Inverse retractions that are based on a QR decomposition of the matrix / matrices for point and tangent vector on a Manifold
ManifoldsBase.QRRetraction
— TypeQRRetraction <: AbstractRetractionMethod
Retractions that are based on a QR decomposition of the matrix / matrices for point and tangent vector on a Manifold
ManifoldsBase.TVector
— TypeTVector
Type for a tangent vector of a manifold. While a Manifold
does not necessarily require this type, for example when it is implemented for Vector
s or Matrix
type elements, this type can be used for more complicated representations, semantic verification, or even dispatch for different representations of tangent vectors and their types on a manifold.
Base.angle
— MethodBase.exp
— Methodexp(M::Manifold, p, X)
exp(M::Manifold, p, X, t::Real = 1)
Compute the exponential map of tangent vector X
, optionally scaled by t
, at point p
from manifold the Manifold
M
.
Base.isapprox
— Methodisapprox(M::Manifold, p, X, Y; kwargs...)
Check if vectors X
and Y
tangent at p
from Manifold
M
are approximately equal.
Keyword arguments can be used to specify tolerances.
Base.isapprox
— Methodisapprox(M::Manifold, p, q; kwargs...)
Check if points p
and q
from Manifold
M
are approximately equal.
Keyword arguments can be used to specify tolerances.
Base.log
— Methodlog(M::Manifold, p, q)
Compute the logarithmic map of point q
at base point p
on the Manifold
M
.
LinearAlgebra.norm
— MethodManifoldsBase.allocate
— Methodallocate(a)
allocate(a, dims::Integer...)
allocate(a, dims::Tuple)
allocate(a, T::Type)
allocate(a, T::Type, dims::Integer...)
allocate(a, T::Type, dims::Tuple)
Allocate an object similar to a
. It is similar to function similar
, although instead of working only on the outermost layer of a nested structure, it maps recursively through outer layers and calls similar
on the innermost array-like object only. Type T
is the new number element type number_eltype
, if it is not given the element type of a
is retained. The dims
argument can be given for non-nested allocation and is forwarded to the function similar
.
ManifoldsBase.allocate_result
— Methodallocate_result(M::Manifold, f, x...)
Allocate an array for the result of function f
on Manifold
M
and arguments x...
for implementing the non-modifying operation using the modifying operation.
Usefulness of passing a function is demonstrated by methods that allocate results of musical isomorphisms.
ManifoldsBase.allocate_result_type
— Methodallocate_result_type(M::Manifold, f, args::NTuple{N,Any}) where N
Return type of element of the array that will represent the result of function f
and the Manifold
M
on given arguments args
(passed as a tuple).
ManifoldsBase.base_manifold
— Functionbase_manifold(M::Manifold, depth = Val(-1))
Return the internally stored Manifold
for decorated manifold M
and the base manifold for vector bundles or power manifolds. The optional parameter depth
can be used to remove only the first depth
many decorators and return the Manifold
from that level, whether its decorated or not. Any negative value deactivates this depth limit.
ManifoldsBase.check_manifold_point
— Methodcheck_manifold_point(M::Manifold, p; kwargs...) -> Union{Nothing,String}
Return nothing
when p
is a point on the Manifold
M
. Otherwise, return an error with description why the point does not belong to manifold M
.
By default, check_manifold_point
returns nothing
, i.e. if no checks are implemented, the assumption is to be optimistic for a point not deriving from the MPoint
type.
ManifoldsBase.check_size
— Methodcheck_size(M::Manifold, p)
check_size(M::Manifold, p, X)
Check whether p
has the right representation_size
for a Manifold
M
. Additionally if a tangent vector is given, both p
and X
are checked to be of corresponding correct representation sizes for points and tangent vectors on M
.
By default, check_size
returns nothing
, i.e. if no checks are implemented, the assumption is to be optimistic.
ManifoldsBase.check_tangent_vector
— Methodcheck_tangent_vector(M::Manifold, p, X; kwargs...) -> Union{Nothing,String}
Check whether X
is a valid tangent vector in the tangent space of p
on the Manifold
M
. An implementation should first call check_manifold_point(M, p; kwargs...)
and then validate X
. If it is not a tangent vector, an error string should be returned.
By default, check_tangent_vector
returns nothing
, i.e. if no checks are implemented, the assumption is to be optimistic for tangent vectors not deriving from the TVector
type.
ManifoldsBase.distance
— Methoddistance(M::Manifold, p, q)
Shortest distance between the points p
and q
on the Manifold
M
.
ManifoldsBase.embed!
— Methodembed!(M::Manifold, Y, p, X)
Embed a tangent vector X
at a point p
on the Manifold
M
into the ambient space and return the result in Y
. This method is only available for manifolds where implicitly an embedding or ambient space is given. Additionally, embed!
includes changing data representation, if applicable, i.e. if the tangents on M
are not represented in the same way as tangents on the embedding, the representation is changed accordingly. This is the case for example for Lie groups, when tangent vectors are represented in the Lie algebra. The embedded tangents are then in the tangent spaces of the embedded base points.
See also: EmbeddedManifold
, project!
ManifoldsBase.embed!
— Methodembed!(M::Manifold, q, p)
Embed point p
from the Manifold
M
into an ambient space. This method is only available for manifolds where implicitly an embedding or ambient space is given. Not implementing this function means, there is no proper embedding for your manifold. Additionally, embed
might include changing data representation, if applicable, i.e. if points on M
are not represented in the same way as their counterparts in the embedding, the representation is changed accordingly.
If you have more than one embedding, see EmbeddedManifold
for defining a second embedding. If your point p
is already represented in some embedding, see AbstractEmbeddedManifold
how you can avoid reimplementing code from the embedded manifold
See also: EmbeddedManifold
, project!
ManifoldsBase.embed
— Methodembed(M::Manifold, p, X)
Embed a tangent vector X
at a point p
on the Manifold
M
into an ambient space. This method is only available for manifolds where implicitly an embedding or ambient space is given. Not implementing this function means, there is no proper embedding for your tangent space(s).
Additionally, embed
might include changing data representation, if applicable, i.e. if tangent vectors on M
are not represented in the same way as their counterparts in the embedding, the representation is changed accordingly.
If you have more than one embedding, see EmbeddedManifold
for defining a second embedding. If your tangent vector X
is already represented in some embedding, see AbstractEmbeddedManifold
how you can avoid reimplementing code from the embedded manifold
See also: EmbeddedManifold
, project
ManifoldsBase.embed
— Methodembed(M::Manifold, p)
Embed point p
from the Manifold
M
into the ambient space. This method is only available for manifolds where implicitly an embedding or ambient space is given. Additionally, embed
includes changing data representation, if applicable, i.e. if the points on M
are not represented in the same way as points on the embedding, the representation is changed accordingly.
See also: EmbeddedManifold
, project
ManifoldsBase.exp!
— Methodexp!(M::Manifold, q, p, X)
exp!(M::Manifold, q, p, X, t::Real = 1)
Compute the exponential map of tangent vector X
, optionally scaled by t
, at point p
from manifold the Manifold
M
. The result is saved to q
.
ManifoldsBase.geodesic
— Methodgeodesic(M::Manifold, p, X) -> Function
Get the geodesic with initial point p
and velocity X
on the Manifold
M
. The geodesic is the curve of constant velocity that is locally distance-minimizing. This function returns a function of (time) t
.
geodesic(M::Manifold, x, v, t::Real)
geodesic(M::Manifold, x, v, T::AbstractVector) -> AbstractVector
Return the point at time t
or points at times t
in T
along the geodesic.
ManifoldsBase.injectivity_radius
— Methodinjectivity_radius(M::Manifold, p)
Return the distance $d$ such that exp(M, p, X)
is injective for all tangent vectors shorter than $d$ (i.e. has an inverse).
injectivity_radius(M::Manifold)
Infimum of the injectivity radius of all manifold points.
injectivity_radius(M::Manifold[, x], method::AbstractRetractionMethod)
injectivity_radius(M::Manifold, x, method::AbstractRetractionMethod)
Distance $d$ such that retract(M, p, X, method)
is injective for all tangent vectors shorter than $d$ (i.e. has an inverse) for point p
if provided or all manifold points otherwise.
ManifoldsBase.inner
— Methodinner(M::Manifold, p, X, Y)
Compute the inner product of tangent vectors X
and Y
at point p
from the Manifold
M
.
See also: MetricManifold
ManifoldsBase.inverse_retract!
— Methodinverse_retract!(M::Manifold, 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 Manifold
M
. Result is saved to X
.
Inverse retraction method can be specified by the last argument, defaulting to LogarithmicInverseRetraction
. See the documentation of respective manifolds for available methods.
ManifoldsBase.inverse_retract
— Methodinverse_retract(M::Manifold, x, y)
inverse_retract(M::Manifold, x, y, method::AbstractInverseRetractionMethod
Compute the inverse retraction, a cheaper, approximate version of the log
arithmic map), of points p
and q
on the Manifold
M
.
Inverse retraction method can be specified by the last argument, defaulting to LogarithmicInverseRetraction
. See the documentation of respective manifolds for available methods.
ManifoldsBase.is_manifold_point
— Functionis_manifold_point(M::Manifold, p, throw_error = false; kwargs...)
Return whether p
is a valid point on the Manifold
M
.
If throw_error
is false
, the function returns either true
or false
. If throw_error
is true
, the function either returns true
or throws an error. By default the function calls check_manifold_point(M, p; kwargs...)
and checks whether the returned value is nothing
or an error.
ManifoldsBase.is_tangent_vector
— Functionis_tangent_vector(M::Manifold, p, X, throw_error = false; kwargs...)
Return whether X
is a valid tangent vector at point p
on the Manifold
M
. Returns either true
or false
.
If throw_error
is false
, the function returns either true
or false
. If throw_error
is true
, the function either returns true
or throws an error. By default the function calls check_tangent_vector(M, p, X; kwargs...)
and checks whether the returned value is nothing
or an error.
ManifoldsBase.log!
— Methodlog!(M::Manifold, X, p, q)
Compute the logarithmic map of point q
at base point p
on the Manifold
M
. The result is saved to X
.
ManifoldsBase.manifold_dimension
— Methodmanifold_dimension(M::Manifold)
The dimension $n=\dim_{\mathcal M}$ of real space $\mathbb R^n$ to which the neighborhood of each point of the Manifold
M
is homeomorphic.
ManifoldsBase.mid_point!
— MethodManifoldsBase.mid_point
— MethodManifoldsBase.number_eltype
— Methodnumber_eltype(x)
Numeric element type of the a nested representation of a point or a vector. To be used in conjuntion with allocate
or allocate_result
.
ManifoldsBase.project!
— Methodproject!(M::Manifold, Y, p, X)
Project ambient space representation of a vector X
to a tangent vector at point p
on the Manifold
M
. The result is saved in vector Y
. This method is only available for manifolds where implicitly an embedding or ambient space is given. Additionally, project!
includes changing data representation, if applicable, i.e. if the tangents on M
are not represented in the same way as points on the embedding, the representation is changed accordingly. This is the case for example for Lie groups, when tangent vectors are represented in the Lie algebra. after projection the change to the Lie algebra is perfomed, too.
See also: EmbeddedManifold
, embed!
ManifoldsBase.project!
— Methodproject!(M::Manifold, q, p)
Project point p
from the ambient space onto the Manifold
M
. The result is storedin q
. This method is only available for manifolds where implicitly an embedding or ambient space is given. Additionally, the projection includes changing data representation, if applicable, i.e. if the points on M
are not represented in the same array data, the data is changed accordingly.
See also: EmbeddedManifold
, embed!
ManifoldsBase.project
— Methodproject(M::Manifold, p, X)
Project ambient space representation of a vector X
to a tangent vector at point p
on the Manifold
M
. This method is only available for manifolds where implicitly an embedding or ambient space is given. Additionally, project
includes changing data representation, if applicable, i.e. if the tangents on M
are not represented in the same way as points on the embedding, the representation is changed accordingly. This is the case for example for Lie groups, when tangent vectors are represented in the Lie algebra. after projection the change to the Lie algebra is perfomed, too.
See also: EmbeddedManifold
, embed
ManifoldsBase.project
— Methodproject(M::Manifold, p)
Project point p
from the ambient space of the Manifold
M
to M
. This method is only available for manifolds where implicitly an embedding or ambient space is given. Additionally, the projection includes changing data representation, if applicable, i.e. if the points on M
are not represented in the same array data, the data is changed accordingly.
See also: EmbeddedManifold
, embed
ManifoldsBase.representation_size
— Methodrepresentation_size(M::Manifold)
The size of an array representing a point on Manifold
M
. Returns nothing
by default indicating that points are not represented using an AbstractArray
.
ManifoldsBase.retract!
— Methodretract!(M::Manifold, q, p, X)
retract!(M::Manifold, q, p, X, t::Real=1)
retract!(M::Manifold, q, p, X, method::AbstractRetractionMethod)
retract!(M::Manifold, 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 Manifold
manifold M
. Result is saved to q
.
Retraction method can be specified by the last argument, defaulting to ExponentialRetraction
. See the documentation of respective manifolds for available methods.
ManifoldsBase.retract
— Methodretract(M::Manifold, p, X)
retract(M::Manifold, p, X, t::Real=1)
retract(M::Manifold, p, X, method::AbstractRetractionMethod)
retract(M::Manifold, 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 Manifold
M
.
Retraction method can be specified by the last argument, defaulting to ExponentialRetraction
. See the documentation of respective manifolds for available methods.
ManifoldsBase.shortest_geodesic
— Methodshortest_geodesic(M::Manifold, p, q) -> Function
Get a geodesic
$\gamma_{p,q}(t)$ whose length is the shortest path between the points p
and q
, where $\gamma_{p,q}(0)=p$ and $\gamma_{p,q}(1)=q$. When there are multiple shortest geodesics, there is no guarantee which will be returned.
This function returns a function of time, which may be a Real
or an AbstractVector
.
shortest_geodesic(M::Manifold, p, q, t::Real)
shortest_geodesic(M::Manifold, p, q, T::AbstractVector) -> AbstractVector
Return the point at time t
or points at times t
in T
along the shortest geodesic.
ManifoldsBase.zero_tangent_vector!
— Methodzero_tangent_vector!(M::Manifold, X, p)
Save to X
a vector such that retracting X
to the Manifold
M
at p
produces p
.
ManifoldsBase.zero_tangent_vector
— Methodzero_tangent_vector(M::Manifold, p)
Return the tangent vector from the tangent space at p
on the Manifold
M
, that represents the zero vector, i.e. such that a retraction at p
produces p
.
Number systems
ManifoldsBase.AbstractNumbers
— TypeAbstractNumbers
An abstract type to represent the number system on which a manifold is built.
This provides concrete number types for dispatch. The two most common number types are the fields RealNumbers
(ℝ
for short) and ComplexNumbers
(ℂ
).
ManifoldsBase.ComplexNumbers
— TypeComplexNumbers <: AbstractNumbers
ℂ = ComplexNumbers()
The field of complex numbers.
ManifoldsBase.QuaternionNumbers
— TypeQuaternionNumbers <: AbstractNumbers
ℍ = QuaternionNumbers()
The division algebra of quaternions.
ManifoldsBase.RealNumbers
— TypeRealNumbers <: AbstractNumbers
ℝ = RealNumbers()
The field of real numbers.
ManifoldsBase._unify_number_systems
— Method_unify_number_systems(𝔽s::AbstractNumbers...)
Compute a number system that includes all given number systems (as sub-systems) and is closed under addition and multiplication.
ManifoldsBase.number_system
— Methodnumber_system(M::Manifold{𝔽})
Return the number system the manifold M
is based on, i.e. the parameter 𝔽
.
ManifoldsBase.real_dimension
— Methodreal_dimension(𝔽::AbstractNumbers)
Return the real dimension $\dim_ℝ 𝔽$ of the AbstractNumbers
system 𝔽
. The real dimension is the dimension of a real vector space with which a number in 𝔽
can be identified. For example, ComplexNumbers
have a real dimension of 2, and QuaternionNumbers
have a real dimension of 4.
Allocation
Non-mutating functions in ManifoldsBase.jl
are typically implemented using mutating variants. Allocation of new points is performed using a custom mechanism that relies on the following functions:
allocate
that allocates a new point or vector similar to the given one. This function behaves likesimilar
for simple representations of points and vectors (for exampleArray{Float64}
). For more complex types, such as nested representations ofPowerManifold
(seeNestedPowerRepresentation
),FVector
types, checked types likeValidationMPoint
and more it operates differently. Whilesimilar
only concerns itself with the higher level of nested structures,allocate
maps itself through all levels of nesting until a simple array of numbers is reached and then callssimilar
. The difference can be most easily seen in the following example:
julia> x = similar([[1.0], [2.0]])
2-element Array{Array{Float64,1},1}:
#undef
#undef
julia> y = Manifolds.allocate([[1.0], [2.0]])
2-element Array{Array{Float64,1},1}:
[6.90031725726027e-310]
[6.9003678131654e-310]
julia> x[1]
ERROR: UndefRefError: access to undefined reference
Stacktrace:
[1] getindex(::Array{Array{Float64,1},1}, ::Int64) at ./array.jl:744
[2] top-level scope at REPL[12]:1
julia> y[1]
1-element Array{Float64,1}:
6.90031725726027e-310
allocate_result
allocates a result of a particular function (for example [exp
], [flat
], etc.) on a particular manifold with particular arguments. It takes into account the possibility that different arguments may have different numericnumber_eltype
types thorough theManifoldsBase.allocate_result_type
function.
Bases
The following functions and types provide support for bases of the tangent space of different manifolds. An orthonormal basis of the tangent space $T_p \mathcal M$ of (real) dimension $n$ has a real-coefficient basis $e_1, e_2, …, e_n$ if $\mathrm{Re}(g_p(e_i, e_j)) = δ_{ij}$ for each $i,j ∈ \{1, 2, …, n\}$ where $g_p$ is the Riemannian metric at point $p$. A vector $X$ from the tangent space $T_p \mathcal M$ can be expressed in Einstein notation as a sum $X = X^i e_i$, where (real) coefficients $X^i$ are calculated as $X^i = \mathrm{Re}(g_p(X, e_i))$.
The main types are:
DefaultOrthonormalBasis
, which is designed to work when no special properties of the tangent space basis are required. It is designed to makeget_coordinates
andget_vector
fast.DiagonalizingOrthonormalBasis
, which diagonalizes the curvature tensor and makes the curvature in the selected direction equal to 0.ProjectedOrthonormalBasis
, which projects a basis of the ambient space and orthonormalizes projections to obtain a basis in a generic way.CachedBasis
, which stores (explicitly or implicitly) a precomputed basis at a certain point.
The main functions are:
get_basis
precomputes a basis at a certain point.get_coordinates
returns coordinates of a tangent vector.get_vector
returns a vector for the specified coordinates.get_vectors
returns a vector of basis vectors. Calling it should be avoided for high-dimensional manifolds.
ManifoldsBase.AbstractBasis
— TypeAbstractBasis{𝔽}
Abstract type that represents a basis on a manifold or a subset of it.
The type parameter 𝔽
denotes the AbstractNumbers
that will be used for the vectors elements.
ManifoldsBase.AbstractOrthogonalBasis
— TypeAbstractOrthogonalBasis{𝔽}
Abstract type that represents an orthonormal basis on a manifold or a subset of it.
The type parameter 𝔽
denotes the AbstractNumbers
that will be used for the vectors elements.
ManifoldsBase.AbstractOrthonormalBasis
— TypeAbstractOrthonormalBasis{𝔽}
Abstract type that represents an orthonormal basis on a manifold or a subset of it.
The type parameter 𝔽
denotes the AbstractNumbers
that will be used for the vectors elements.
ManifoldsBase.CachedBasis
— TypeCachedBasis{𝔽,V,<:AbstractBasis{𝔽}} <: AbstractBasis{𝔽}
A cached version of the given basis
with precomputed basis vectors. The basis vectors are stored in data
, either explicitly (like in cached variants of ProjectedOrthonormalBasis
) or implicitly.
Constructor
CachedBasis(basis::AbstractBasis, data)
ManifoldsBase.DefaultBasis
— TypeDefaultBasis{𝔽}
An arbitrary basis on a manifold. This will usually be the fastest basis available for a manifold.
The type parameter 𝔽
denotes the AbstractNumbers
that will be used for the vectors elements
ManifoldsBase.DefaultOrthogonalBasis
— TypeDefaultOrthogonalBasis{𝔽}
An arbitrary orthogonal basis on a manifold. This will usually be the fastest orthogonal basis available for a manifold.
The type parameter 𝔽
denotes the AbstractNumbers
that will be used for the vectors elements.
ManifoldsBase.DefaultOrthonormalBasis
— TypeDefaultOrthonormalBasis(𝔽::AbstractNumbers = ℝ)
An arbitrary orthonormal basis on a manifold. This will usually be the fastest orthonormal basis available for a manifold.
The type parameter 𝔽
denotes the AbstractNumbers
that will be used for the vectors elements.
ManifoldsBase.DiagonalizingOrthonormalBasis
— TypeDiagonalizingOrthonormalBasis{𝔽,TV} <: AbstractOrthonormalBasis{𝔽}
An orthonormal basis Ξ
as a vector of tangent vectors (of length determined by manifold_dimension
) in the tangent space that diagonalizes the curvature tensor $R(u,v)w$ and where the direction frame_direction
$v$ has curvature 0
.
The type parameter 𝔽
denotes the AbstractNumbers
that will be used for the vectors elements.
Constructor
DiagonalizingOrthonormalBasis(frame_direction, 𝔽::AbstractNumbers = ℝ)
ManifoldsBase.ProjectedOrthonormalBasis
— TypeProjectedOrthonormalBasis(method::Symbol, 𝔽::AbstractNumbers = ℝ)
An orthonormal basis that comes from orthonormalization of basis vectors of the ambient space projected onto the subspace representing the tangent space at a given point.
The type parameter 𝔽
denotes the AbstractNumbers
that will be used for the vectors elements.
Available methods:
:gram_schmidt
uses a modified Gram-Schmidt orthonormalization.:svd
uses SVD decomposition to orthogonalize projected vectors. The SVD-based method should be more numerically stable at the cost of an additional assumption (local metric tensor at a point where the basis is calculated has to be diagonal).
ManifoldsBase.allocation_promotion_function
— Methodallocation_promotion_function(M::Manifold, f, args::Tuple)
Determine the function that must be used to ensure that the allocated representation is of the right type. This is needed for get_vector
when a point on a complex manifold is represented by a real-valued vectors with a real-coefficient basis, so that a complex-valued vector representation is allocated.
ManifoldsBase.get_basis
— Methodget_basis(M::Manifold, p, B::AbstractBasis) -> CachedBasis
Compute the basis vectors of the tangent space at a point on manifold M
represented by p
.
Returned object derives from AbstractBasis
and may have a field .vectors
that stores tangent vectors or it may store them implicitly, in which case the function get_vectors
needs to be used to retrieve the basis vectors.
See also: get_coordinates
, get_vector
ManifoldsBase.get_coordinates
— Methodget_coordinates(M::Manifold, p, X, B::AbstractBasis)
get_coordinates(M::Manifold, p, X, B::CachedBasis)
Compute a one-dimensional vector of coefficients of the tangent vector X
at point denoted by p
on manifold M
in basis B
.
Depending on the basis, p
may not directly represent a point on the manifold. For example if a basis transported along a curve is used, p
may be the coordinate along the curve. If a CachedBasis
is provided, their stored vectors are used, otherwise the user has to provide a method to compute the coordinates.
For the CachedBasis
keep in mind that the reconstruction with get_vector
requires either a dual basis or the cached basis to be selfdual, for example orthonormal
See also: get_vector
, get_basis
ManifoldsBase.get_vector
— Methodget_vector(M::Manifold, p, X, B::AbstractBasis)
Convert a one-dimensional vector of coefficients in a basis B
of the tangent space at p
on manifold M
to a tangent vector X
at p
.
Depending on the basis, p
may not directly represent a point on the manifold. For example if a basis transported along a curve is used, p
may be the coordinate along the curve.
For the CachedBasis
keep in mind that the reconstruction from get_coordinates
requires either a dual basis or the cached basis to be selfdual, for example orthonormal
See also: get_coordinates
, get_basis
ManifoldsBase.get_vectors
— Methodget_vectors(M::Manifold, p, B::AbstractBasis)
Get the basis vectors of basis B
of the tangent space at point p
.
ManifoldsBase.hat
— Methodhat(M::Manifold, p, Xⁱ)
Given a basis $e_i$ on the tangent space at a point p
and tangent component vector $X^i$, compute the equivalent vector representation $X=X^i e_i$, where Einstein summation notation is used:
For array manifolds, this converts a vector representation of the tangent vector to an array representation. The vee
map is the hat
map's inverse.
ManifoldsBase.number_of_coordinates
— Methodnumber_of_coordinates(M::Manifold, B::AbstractBasis)
Compute the number of coordinates in basis B
of manifold M
. This also corresponds to the number of vectors represented by B
, or stored within B
in case of a CachedBasis
.
ManifoldsBase.number_system
— Methodnumber_system(::AbstractBasis)
The number system for the vectors of the given basis.
ManifoldsBase.vee
— Methodvee(M::Manifold, p, X)
Given a basis $e_i$ on the tangent space at a point p
and tangent vector X
, compute the vector components $X^i$, such that $X = X^i e_i$, where Einstein summation notation is used:
For array manifolds, this converts an array representation of the tangent vector to a vector representation. The hat
map is the vee
map's inverse.
Vector transport
There are three main functions for vector transport:
Different types of vector transport are implemented using subtypes of AbstractVectorTransportMethod
:
ManifoldsBase.AbstractVectorTransportMethod
— TypeAbstractVectorTransportMethod
Abstract type for methods for transporting vectors.
ManifoldsBase.ParallelTransport
— TypeParallelTransport <: AbstractVectorTransportMethod
Specify to use parallel transport as vector transport method within vector_transport_to
, vector_transport_direction
, or vector_transport_along
.
ManifoldsBase.PoleLadderTransport
— TypePoleLadderTransport <: AbstractVectorTransportMethod
Specify to use pole_ladder
as vector transport method within vector_transport_to
, vector_transport_direction
, or vector_transport_along
, i.e.
Let $X\in T_p\mathcal M$ be a tangent vector at $p\in\mathcal M$ and $q\in\mathcal M$ the point to transport to. Then $x = \exp_pX$ is used to call y =
pole_ladder
(M, p, x, q)
and the resulting vector is obtained by computing $Y = -\log_qy$.
The PoleLadderTransport
posesses two advantages compared to SchildsLadderTransport
:
- it is cheaper to evaluate, if you want to transport several vectors, since the mid point $c$ then stays unchanged.
- while both methods are exact if the curvature is zero, pole ladder is even exact in symmetric Riemannian manifolds[Pennec2018]
The pole ladder was was proposed in [LorenziPennec2014]. Its name stems from the fact that it resembles a pole ladder when applied to a sequence of points usccessively.
Constructor
PoleLadderTransport(
retraction = ExponentialRetraction(),
inverse_retraction = LogarithmicInverseRetraction(),
)
Construct the classical pole ladder that employs exp and log, i.e. as proposed in[LorenziPennec2014]. For an even cheaper transport the inner operations can be changed to an AbstractRetractionMethod
retraction
and an AbstractInverseRetractionMethod
inverse_retraction
, respectively.
ManifoldsBase.ProjectionTransport
— TypeProjectionTransport <: AbstractVectorTransportMethod
Specify to use projection onto tangent space as vector transport method within vector_transport_to
, vector_transport_direction
, or vector_transport_along
. See project
for details.
ManifoldsBase.SchildsLadderTransport
— TypeSchildsLadderTransport <: AbstractVectorTransportMethod
Specify to use schilds_ladder
as vector transport method within vector_transport_to
, vector_transport_direction
, or vector_transport_along
, i.e.
Let $X\in T_p\mathcal M$ be a tangent vector at $p\in\mathcal M$ and $q\in\mathcal M$ the point to transport to. Then
where $c$ is the mid point between $q$ and $d=\exp_pX$.
This method employs the internal function schilds_ladder
(M, p, d, q)
that avoids leaving the manifold.
The name stems from the image of this paralleltogram in a repeated application yielding the image of a ladder. The approximation was proposed in [EhlersPiraniSchild1972].
Constructor
SchildsLadderTransport(
retraction = ExponentialRetraction(),
inverse_retraction = LogarithmicInverseRetraction(),
)
Construct the classical Schilds ladder that employs exp and log, i.e. as proposed in[EhlersPiraniSchild1972]. For an even cheaper transport these inner operations can be changed to an AbstractRetractionMethod
retraction
and an AbstractInverseRetractionMethod
inverse_retraction
, respectively.
ManifoldsBase.pole_ladder
— Functionpole_ladder(
M,
p,
d,
q,
c = mid_point(M, p, q);
retraction=ExponentialRetraction(),
inverse_retraction=LogarithmicInverseRetraction()
)
Compute an inner step of the pole ladder, that can be used as a vector_transport_to
. Let $c = \gamma_{p,q}(\frac{1}{2})$ mid point between p
and q
, then the pole ladder is given by
Where the classical pole ladder employs $\operatorname{retr}_d=\exp_d$ and $\operatorname{retr}_d^{-1}=\log_d$ but for an even cheaper transport these can be set to different AbstractRetractionMethod
and AbstractInverseRetractionMethod
.
When you have $X=log_pd$ and $Y = -\log_q \operatorname{Pl}(p,d,q)$, you will obtain the PoleLadderTransport
. When performing multiple steps, this method avoidsd the switching to the tangent space. Keep in mind that after $n$ successive steps the tangent vector reads $Y_n = (-1)^n\log_q \operatorname{Pl}(p_{n-1},d_{n-1},p_n)$.
It is cheaper to evaluate than schilds_ladder
, sinc if you want to form multiple ladder steps between p
and q
, but with different d
, there is just one evaluation of a geodesic each., since the center c
can be reused.
ManifoldsBase.pole_ladder!
— Functionpole_ladder(
M,
pl,
p,
d,
q,
c = mid_point(M, p, q),
X = allocate_result_type(M, log, d, c);
retraction = ExponentialRetraction(),
inverse_retraction = LogarithmicInverseRetraction()
)
Compute the pole_ladder
, i.e. the result is saved in pl
. X
is used for storing intermediate inverse retraction.
ManifoldsBase.schilds_ladder
— Functionschilds_ladder(
M,
p,
d,
q,
c = mid_point(M, q, d);
retraction = ExponentialRetraction(),
inverse_retraction = LogarithmicInverseRetraction(),
)
Perform an inner step of schilds ladder, which can be used as a vector_transport_to
, see SchildsLadderTransport
. Let $c = \gamma_{q,d}(\frac{1}{2})$ denote the mid point on the shortest geodesic connecting $q$ and the point $d$. Then Schild's ladder reads as
Where the classical Schilds ladder employs $\operatorname{retr}_d=\exp_d$ and $\operatorname{retr}_d^{-1}=\log_d$ but for an even cheaper transport these can be set to different AbstractRetractionMethod
and AbstractInverseRetractionMethod
.
In consistency with pole_ladder
you can change the way the mid point is computed using the optional parameter c
, but note that here it's the mid point between q
and d
.
When you have $X=log_pd$ and $Y = \log_q \operatorname{Sl}(p,d,q)$, you will obtain the PoleLadderTransport
. Then the approximation to the transported vector is given by $\log_q\operatorname{Sl}(p,d,q)$.
When performing multiple steps, this method avoidsd the switching to the tangent space. Hence after $n$ successive steps the tangent vector reads $Y_n = \log_q \operatorname{Pl}(p_{n-1},d_{n-1},p_n)$.
ManifoldsBase.schilds_ladder!
— Functionschilds_ladder!(
M,
sl
p,
d,
q,
c = mid_point(M, q, d),
X = allocate_result_type(M, log, d, c);
retraction = ExponentialRetraction(),
inverse_retraction = LogarithmicInverseRetraction()
)
Compute schilds_ladder
and return the value in the parameter sl
. If the required mid point c
was computed before, it can be passed using c
, and the allocation of new memory can be avoided providing a tangent vector X
for the interims result.
ManifoldsBase.vector_transport_along!
— Methodvector_transport_along!(
M::Manifold,
Y,
p,
X,
c::AbstractVector,
method::AbstractVectorTransportMethod
) where {T}
Compute the vector transport along a discretized curve c
using an AbstractVectorTransportMethod
method
succesively along the sampled curve.
ManifoldsBase.vector_transport_along!
— Methodfunction vector_transport_along!(
M::Manifold,
Y,
p,
X,
c::AbstractVector,
method::PoleLadderTransport
)
Compute the vector transport along a discretized curve using PoleLadderTransport
succesively along the sampled curve. This method is avoiding additional allocations as well as inner exp/log by performing all ladder steps on the manifold and only computing one tangent vector in the end.
ManifoldsBase.vector_transport_along!
— Methodvector_transport_along!(
M::Manifold,
Y,
p,
X,
c::AbstractVector,
method::SchildsLadderTransport
)
Compute the vector transport along a discretized curve using SchildsLadderTransport
succesively along the sampled curve. This method is avoiding additional allocations as well as inner exp/log by performing all ladder steps on the manifold and only computing one tangent vector in the end.
ManifoldsBase.vector_transport_along!
— Methodvector_transport_along!(M::Manifold, Y, p, X, c)
vector_transport_along!(M::Manifold, Y, p, X, c, method::AbstractVectorTransportMethod)
Transport a vector X
from the tangent space at a point p
on the Manifold
M
along the curve represented by c
using the method
, which defaults to ParallelTransport
. The result is saved to Y
.
ManifoldsBase.vector_transport_along
— Methodvector_transport_along(M::Manifold, p, X, c)
vector_transport_along(M::Manifold, p, X, c, method::AbstractVectorTransportMethod)
Transport a vector X
from the tangent space at a point p
on the Manifold
M
along the curve represented by c
using the method
, which defaults to ParallelTransport
.
ManifoldsBase.vector_transport_direction!
— Methodvector_transport_direction!(M::Manifold, Y, p, X, d)
vector_transport_direction!(M::Manifold, Y, p, X, d, method::AbstractVectorTransportMethod)
Transport a vector X
from the tangent space at a point p
on the Manifold
M
in the direction indicated by the tangent vector d
at p
. By default, exp
and vector_transport_to!
are used with the method
, which defaults to ParallelTransport
. The result is saved to Y
.
ManifoldsBase.vector_transport_direction
— Methodvector_transport_direction(M::Manifold, p, X, d)
vector_transport_direction(M::Manifold, p, X, d, method::AbstractVectorTransportMethod)
Transport a vector X
from the tangent space at a point p
on the Manifold
M
in the direction indicated by the tangent vector d
at p
. By default, exp
and vector_transport_to!
are used with the method
, which defaults to ParallelTransport
.
ManifoldsBase.vector_transport_to!
— Methodvector_transport_to!(M::Manifold, Y, p, X, q, method::PoleLadderTransport)
Perform a vector transport by using PoleLadderTransport
.
ManifoldsBase.vector_transport_to!
— Methodvector_transport_to!(M::Manifold, Y, p, X, q, method::ProjectionTransport)
Transport a vector X
from the tangent space at p
on the Manifold
M
by interpreting it as an element of the embedding and then projecting it onto the tangent space at q
. This function needs to be separately implemented for each manifold because projection project
may also change vector representation (if it's different than in the embedding) and it is assumed that the vector X
already has the correct representation for M
.
ManifoldsBase.vector_transport_to!
— Methodvector_transport_to!(M::Manifold, Y, p, X, q, method::SchildsLadderTransport)
Perform a vector transport by using SchildsLadderTransport
.
ManifoldsBase.vector_transport_to!
— Methodvector_transport_to!(M::Manifold, Y, p, X, q)
vector_transport_to!(M::Manifold, Y, p, X, q, method::AbstractVectorTransportMethod)
Transport a vector X
from the tangent space at a point p
on the Manifold
M
along the shortest_geodesic
to the tangent space at another point q
. By default, the AbstractVectorTransportMethod
method
is ParallelTransport
. The result is saved to Y
.
ManifoldsBase.vector_transport_to
— Methodvector_transport_to(M::Manifold, p, X, q)
vector_transport_to(M::Manifold, p, X, q, method::AbstractVectorTransportMethod)
Transport a vector X
from the tangent space at a point p
on the Manifold
M
along the shortest_geodesic
to the tangent space at another point q
. By default, the AbstractVectorTransportMethod
method
is ParallelTransport
.
A Decorator for manifolds
A decorator manifold extends the functionality of a Manifold
in a semi-transparent way. It internally stores the Manifold
it extends and by default for functions defined in the ManifoldsBase
it acts transparently in the sense that it passes all functions through to the base except those that it actually affects. For example, because the ValidationManifold
affects nearly all functions, it overwrites nearly all functions, except a few like manifold_dimension
. On the other hand, the MetricManifold
only affects functions that involve metrics, especially exp
and log
but not the manifold_dimension
. Contrary to the previous decorator, the MetricManifold
does not overwrite functions. The decorator sets functions like exp
and log
to be implemented anew but required to be implemented when specifying a new metric. An exception is not issued if a metric is additionally set to be the default metric (see is_default_metric
, since this makes all functions act transparently. this last case assumes that the newly specified metric type is actually the one already implemented on a manifold initially.
By default, i.e. for a plain new decorator, all functions are passed down. To implement a method for a decorator that behaves differently from the method of the same function for the internal manifold, two steps are required. Let's assume the function is called f(M, arg1, arg2)
, and our decorator manifold DM
of type OurDecoratorManifold
decorates M
. Then
- set
decorator_transparent_dispatch(f, M::OurDecoratorManifold, args...) = Val(:intransparent)
- implement
f(DM::OurDecoratorManifold, arg1, arg2)
This makes it possible to extend a manifold or all manifolds with a feature or replace a feature of the original manifold. The MetricManifold
is the best example of the second case, since the default metric indicates for which metric the manifold was originally implemented, such that those functions are just passed through. This can best be seen in the SymmetricPositiveDefinite
manifold with its LinearAffineMetric
.
ManifoldsBase.@decorator_transparent_fallback
— Macro@decorator_transparent_fallback(ex)
@decorator_transparent_fallback(fallback_case = :intransparent, ex)
This macro introduces an additional implementation for a certain additional case. This can especially be used if for an already transparent function and an abstract intermediate type a change in the default is required. For implementing a concrete type, neither this nor any other trick is necessary. One just implements the function as before. Note that a decorator that is_default_decorator
still dispatches to the transparent case.
:transparent
states, that the function is transparently passed on to the manifold that is decorated by theAbstractDecoratorManifold
M
, which is determined using the functiondecorated_manifold
.:intransparent
states that an implementation for this decorator is required, and if none of the types provides one, an error is issued. Since this macro provides such an implementation, this is the default.:parent
states, that this function passes on to the supertype instead of to the decorated manifold.
Inline definitions are not supported. The function signature however may contain keyword arguments and a where clause. It does not allow for parameters with default values.
Examples
@decorator_transparent_fallback function log!(M::AbstractGroupManifold, X, p, q)
log!(decorated_manifold(M), X, p, Q)
end
@decorator_transparent_fallback :transparent function log!(M::AbstractGroupManifold, X, p, q)
log!(decorated_manifold(M), X, p, Q)
end
ManifoldsBase.@decorator_transparent_function
— Macro@decorator_transparent_function(ex)
@decorator_transparent_function(fallback_case = :intransparent, ex)
Introduce the function specified by ex
to act transparently with respect to AbstractDecoratorManifold
s. This introduces the possibility to modify the kind of transparency the implementation is done for. This optional first argument, the Symbol
within fallback_case
. This macro can be used to define a function and introduce it as transparent to other decorators. Note that a decorator that is_default_decorator
still dispatches to the transparent case.
The cases of transparency are
:transparent
states, that the function is transparently passed on to the manifold that is decorated by theAbstractDecoratorManifold
M
, which is determined using the functiondecorated_manifold
.:intransparent
states that an implementation for this decorator is required, and if none of the types provides one, an error is issued. Since this macro provides such an implementation, this is the default.:parent
states, that this function passes on to the supertype instead of to the decorated manifold. Passing is performed using theinvoke
function where the type of manifold is replaced by its supertype.
Innkoline-definitions are not yet covered – the function signature however may contain keyword arguments and a where clause.
Examples
@decorator_transparent_function log!(M::AbstractDecoratorManifold, X, p, q)
log!(decorated_manifold(M), X, p, Q)
end
@decorator_transparent_function :parent log!(M::AbstractDecoratorManifold, X, p, q)
log!(decorated_manifold(M), X, p, Q)
end
ManifoldsBase.@decorator_transparent_signature
— Macro@decorator_transparent_signature(ex)
Introduces a given function to be transparent with respect to all decorators. The function is adressed by its signature in ex
.
Supports standard, keyword arguments and where
clauses. Doesn't support parameters with default values. It introduces a dispatch on several transparency modes
The cases of transparency are
:transparent
states, that the function is transparently passed on to the manifold that is decorated by theAbstractDecoratorManifold
M
, which is determined using the functiondecorated_manifold
. This is the default.:intransparent
states that an implementation for this decorator is required, and if none of the types provides one, an error is issued.:parent
states, that this function passes on to the supertype instead of to the decorated manifold.
Inline definitions are not supported. The function signature however may contain keyword arguments and a where clause.
The dispatch kind can later still be set to something different, see decorator_transparent_dispatch
Examples:
@decorator_transparent_signature log!(M::AbstractDecoratorManifold, X, p, q)
@decorator_transparent_signature log!(M::TD, X, p, q) where {TD<:AbstractDecoratorManifold}
@decorator_transparent_signature isapprox(M::AbstractDecoratorManifold, p, q; kwargs...)
ManifoldsBase.AbstractDecoratorManifold
— TypeAbstractDecoratorManifold{𝔽} <: Manifold{𝔽}
An AbstractDecoratorManifold
indicates that to some extent a manifold subtype decorates another Manifold
in the sense that it either
- it extends the functionality of a manifold with further features
- it defines a new manifold that internally uses functions from the decorated manifold
with the main intent that several or most functions of Manifold
are transparently passed through to the manifold that is decorated. This way a function implemented for a decorator acts transparent on all other decorators, i.e. they just pass them through. If the decorator the function is implemented for is not among the decorators, an error is issued. By default all base manifold functions, for example exp
and log
are transparent for all decorators.
Transparency of functions with respect to decorators can be specified using the macros @decorator_transparent_fallback
, @decorator_transparent_function
and @decorator_transparent_signature
.
ManifoldsBase.decorated_manifold
— Methoddecorated_manifold(M::AbstractDecoratorManifold)
Return the manifold decorated by the decorator M
. Defaults to M.manifold
.
ManifoldsBase.decorator_transparent_dispatch
— Methoddecorator_transparent_dispatch(f, M::Manifold, args...) -> Val
Given a Manifold
M
and a function f(M,args...)
, indicate, whether a function is Val(:transparent)
or Val(:intransparent)
for the (decorated) Manifold
M
. Another possibility is, that for M
and given args...
the function f
should invoke M
s Val(:parent)
implementation, see @decorator_transparent_function
for details.
ManifoldsBase.default_decorator_dispatch
— Methoddefault_decorator_dispatch(M) -> Val
Return whether by default to dispatch the the inner manifold of a decorator (Val(true)
) or not (Val(false
). For more details see is_decorator_transparent
.
ManifoldsBase.is_decorator_transparent
— Methodis_decorator_transparent(f, M::Manifold, args...) -> Bool
Given a Manifold
M
and a function f(M, args...)
, indicate, whether an AbstractDecoratorManifold
acts transparently for f
. This means, it just passes through down to the internally stored manifold. Transparency is only defined for decorator manifolds and by default all decorators are transparent. A function that is affected by the decorator indicates this by returning false
. To change this behaviour, see decorator_transparent_dispatch
.
If a decorator manifold is not in general transparent, it might still pass down for the case that a decorator is the default decorator, see is_default_decorator
.
ManifoldsBase.is_default_decorator
— Methodis_default_decorator(M) -> Bool
For any manifold that is a subtype of AbstractDecoratorManifold
, this function indicates whether a certain manifold M
acts as a default decorator.
This yields that all functions are passed through to the decorated Manifold
if M
is indicated as default. This overwrites all is_decorator_transparent
values.
This yields the following advantange: For a manifold one usually implicitly assumes for example a metric. To avoid reimplementation of this metric when introducing a second metric, the first metric can be set to be the default, i.e. its implementaion is already given by the undecorated case.
Value returned by this function is determined by default_decorator_dispatch
, which returns a Val
-wrapped boolean for type stability of certain functions.
ValidationManifold
ValidationManifold
is a simple decorator that “decorates” a manifold with tests that all involved arrays are correct. For example involved input and output paratemers are checked before and after running a function, repectively. This is done by calling is_manifold_point
or is_tangent_vector
whenever applicable.
ManifoldsBase.ValidationCoTVector
— TypeValidationCoTVector <: CoTVector
Represent a cotangent vector to a point on an ValidationManifold
, i.e. on a manifold where data can be represented by arrays. The array is stored internally and semantically. This distinguished the value from ValidationMPoint
s and ValidationTVector
s.
ManifoldsBase.ValidationMPoint
— TypeValidationMPoint <: MPoint
Represent a point on an ValidationManifold
, i.e. on a manifold where data can be represented by arrays. The array is stored internally and semantically. This distinguished the value from ValidationTVector
s and ValidationCoTVector
s.
ManifoldsBase.ValidationManifold
— TypeValidationManifold{𝔽,M<:Manifold{𝔽}} <: AbstractDecoratorManifold{𝔽}
A manifold to encapsulate manifolds working on array representations of MPoint
s and TVector
s in a transparent way, such that for these manifolds it's not necessary to introduce explicit types for the points and tangent vectors, but they are encapsulated/stripped automatically when needed.
This manifold is a decorator for a manifold, i.e. it decorates a Manifold
M
with types points, vectors, and covectors.
ManifoldsBase.ValidationTVector
— TypeValidationTVector <: TVector
Represent a tangent vector to a point on an ValidationManifold
, i.e. on a manifold where data can be represented by arrays. The array is stored internally and semantically. This distinguished the value from ValidationMPoint
s and ValidationCoTVector
s.
ManifoldsBase.array_value
— Methodarray_value(p)
Return the internal array value of an ValidationMPoint
, ValidationTVector
, or ValidationCoTVector
if the value p
is encapsulated as such. Return p
if it is already an array.
EmbeddedManifold
Some manifolds can easily be defined by using a certain embedding. For example the Sphere
(n)
is embedded in Euclidean
(n+1)
. Similar to the metric and MetricManifold
, an embedding is often implicitly assumed. We introduce the embedded manifolds hence as an AbstractDecoratorManifold
.
This decorator enables to use such an embedding in an transparent way. Different types of embeddings can be distinguished using the AbstractEmbeddingType
.
Isometric Embeddings
For isometric embeddings the type AbstractIsometricEmbeddingType
can be used to avoid reimplementing the metric. See Sphere
or Hyperbolic
for example. Here, the exponential map, the logarithmic map, the retraction and its inverse are set to :intransparent
, i.e. they have to be implemented.
Furthermore, the TransparentIsometricEmbedding
type even states that the exponential and logarithmic maps as well as retractions and vector transports of the embedding can be used for the embedded manifold as well. See SymmetricMatrices
for an example.
In both cases of course check_manifold_point
and check_tangent_vector
have to be implemented.
Further Embeddings
A first embedding can also just be given implementing embed!
ann project!
for a manifold. This is considered to be the most usual or default embedding.
If you have two different embeddings for your manifold, a second one can be specified using the EmbeddedManifold
, a type that “couples” two manifolds, more precisely a manifold and its embedding, to define embedding and projection functions between these two manifolds.
Types
ManifoldsBase.AbstractEmbeddedManifold
— TypeAbstractEmbeddedManifold{𝔽,T<:AbstractEmbeddingType,𝔽} <: AbstractDecoratorManifold{𝔽}
This abstract type indicates that a concrete subtype is an embedded manifold with the additional property, that its points are given in the embedding. This also means, that the default implementation of embed
is just the identity, since the points are already stored in the form suitable for this embedding specified. This also holds true for tangent vectors.
Furthermore, depending on the AbstractEmbeddingType
different methods are transparently used from the embedding, for example the inner
product or even the distance
function. Specifying such an embedding type transparently passes the compuation onwards to the embedding (note again, that no embed
is required) and hence avoids to reimplement these methods in the manifold that is embedded.
This should be used for example for check_manifold_point
or check_tangent_vector
, which should first invoke the test of the embedding and then test further constraints the representation in the embedding has for these points to be valid.
Technically this is realised by making the AbstractEmbeddedManifold
is a decorator for the Manifold
s that are subtypes.
ManifoldsBase.AbstractEmbeddingType
— TypeAbstractEmbeddingType
A type used to specify properties of an AbstractEmbeddedManifold
.
ManifoldsBase.AbstractIsometricEmbeddingType
— TypeAbstractIsometricEmbeddingType <: AbstractEmbeddingType
Characterizes an embedding as isometric. For this case the inner
product is passed from the embedded manifold to the embedding.
ManifoldsBase.DefaultEmbeddingType
— TypeDefaultEmbeddingType <: AbstractEmbeddingType
A type of default embedding that does not have any special properties.
ManifoldsBase.DefaultIsometricEmbeddingType
— TypeDefaultIsometricEmbeddingType <: AbstractIsometricEmbeddingType
An isometric embedding type that acts as a default, i.e. it has no specifig properties beyond its isometric property.
ManifoldsBase.EmbeddedManifold
— TypeEmbeddedManifold{𝔽, MT <: Manifold, NT <: Manifold} <: AbstractDecoratorManifold{𝔽}
A type to represent an explicit embedding of a Manifold
M
of type MT
embedded into a manifold N
of type NT
.
!!!note This type is not required if a manifold M
is to be embedded in one specific manifold N
. One can then just implement embed!
and project!
. Only for a second –maybe considered non-default– embedding, this type should be considered in order to dispatch on different embed and project methods for different embeddings N
.
Fields
manifold
the manifold that is an embedded manifoldembedding
a second manifold, the first one is embedded into
Constructor
EmbeddedManifold(M, N)
Generate the EmbeddedManifold
of the Manifold
M
into the Manifold
N
.
ManifoldsBase.TransparentIsometricEmbedding
— TypeTransparentIsometricEmbedding <: AbstractIsometricEmbeddingType
Specify that an embedding is the default isometric embedding. This even inherits logarithmic and exponential map as well as retraction and inverse retractions from the embedding.
For an example, see SymmetricMatrices
which are isometrically embedded in the Euclidean space of matrices but also inherit exponential and logarithmic maps.
Functions
ManifoldsBase.base_manifold
— Methodbase_manifold(M::AbstractEmbeddedManifold, d::Val{N} = Val(-1))
Return the base manifold of M
that is enhanced with its embedding. While functions like inner
might be overwritten to use the (decorated) manifold representing the embedding, the basemanifold is the manifold itself in the sense that detemining e.g. the [`isdefault_metric](@ref) does not fall back to check with the embedding but with the manifold itself. For this abstract case, just
M` is returned.
ManifoldsBase.base_manifold
— Methodbase_manifold(M::EmbeddedManifold, d::Val{N} = Val(-1))
Return the base manifold of M
that is enhanced with its embedding. For this specific type the internally stored enhanced manifold M.manifold
is returned.
ManifoldsBase.check_manifold_point
— Methodcheck_manifold_point(M::AbstractEmbeddedManifold, p; kwargs)
check whether a point p
is a valid point on the AbstractEmbeddedManifold
, i.e. that embed(M, p)
is a valid point on the embedded manifold.
ManifoldsBase.check_tangent_vector
— Methodcheck_tangent_vector(M::AbstractEmbeddedManifold, p, X; check_base_point = true, kwargs...)
check that embed(M, p, X)
is a valid tangent to embed(M, p)
, where check_base_point
determines whether the validity of p
is checked, too.
ManifoldsBase.default_embedding_dispatch
— Methoddefault_embedding_dispatch(M::AbstractEmbeddedManifold)
This method indicates that an AbstractEmbeddedManifold
is the default and hence acts completely transparently and passes all functions transparently onwards. This is used by the AbstractDecoratorManifold
within default_decorator_dispatch
. By default this is set to Val(false)
.
ManifoldsBase.get_embedding
— Methodget_embedding(M::AbstractEmbeddedManifold)
Return the Manifold
N
an AbstractEmbeddedManifold
is embedded into.
ManifoldsBase.get_embedding
— Methodget_embedding(M::EmbeddedManifold)
Return the Manifold
N
an EmbeddedManifold
is embedded into.
DefaultManifold
DefaultManifold
is a simplified version of Euclidean
and demonstrates a basic interface implementation. It can be used to perform simple tests. Since when using Manifolds.jl
the Euclidean
is available, the DefaultManifold
itself is not exported.
ManifoldsBase.DefaultManifold
— TypeDefaultManifold <: Manifold
This default manifold illustrates the main features of the interface and provides a skeleton to build one's own manifold. It is a simplified/shortened variant of Euclidean
from Manifolds.jl
.
This manifold further illustrates how to type your manifold points and tangent vectors. Note that the interface does not require this, but it might be handy in debugging and educative situations to verify correctness of involved variabes.
- LorenziPennec2014
Lorenzi, M. and Pennec, X: Efficient parallel transport of deformations in time series of images: From Schild’s to pole ladder. Journal of Mathematical Imaging and Vision (2014), 50(1), pp. 5–17 doi 10.1007/s10851-013-0470-3, hal: hal-00870489
- Pennec2018
Pennec, X: Parallel Transport with Pole Ladder: a Third Order Scheme in Affine Connection Spaces which is Exact in Affine Symmetric Spaces. arXiv: 1805.11436
- EhlersPiraniSchild1972
Ehlers, J., Pirani, F.A.E., Schild, A.: The geometry of free fall and light propagation. In: O’Raifeartaigh, L. (ed.) General Relativity: Papers in Honour of J. L. Synge, pp. 63–84. Clarendon Press, Oxford (1972). reprint doi: 10.1007/s10714-012-1353-4