Manifolds
While the interface ManifoldsBase.jl does not cover concrete manifolds, it provides a few helpers to build or create manifolds based on existing manifolds
A default manifold
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 — Type
DefaultManifold <: AbstractManifoldThis 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 variables.
Constructor
DefaultManifold(n::Int...; field = ℝ, parameter::Symbol = :field)Arguments:
n: shape of array representing points on the manifold.field: field over which the manifold is defined. Eitherℝ,ℂorℍ.parameter: whether a type parameter should be used to storen. By default size is stored in a field. Value can either be:fieldor:type.
Embedded manifold
The embedded manifold is a manifold $\mathcal M$ which is modelled explicitly specifying its embedding $\mathcal N$ in which the points and tangent vectors are represented. Most prominently is_point and is_vector of an embedded manifold are implemented to check whether the point is a valid point in the embedding. This can of course still be extended by further tests. ManifoldsBase.jl provides two possibilities of easily introducing this in order to dispatch some functions to the embedding.
Implicit case: the decorator Trait
For the implicit case, your manifold has to be a subtype of the AbstractDecoratorManifold and specifying the get_embedding_type makes that manifold an embedded manifold. You just have to also define get_embedding so that appropriate functions are passed on to that embedding. Which are passed on also depends on the AbstractForwardingType you specify. This is the implicit case, since the manifold type itself does not carry any information about the embedding, just the trait and the function definition do.
Explicit case: the EmbeddedManifold
The EmbeddedManifold itself is an AbstractDecoratorManifold so it is a case of the implicit embedding itself, but internally stores both the original manifold and the embedding. They are also parameters of the type. This way, an additional embedding of one manifold in another can be modelled. That is, if the manifold is implemented using the implicit embedding approach from before but can also be implemented using a different embedding, then this method should be chosen, since you can dispatch functions that you want to implement in this embedding then on the type which explicitly has the manifold and its embedding as parameters.
Hence this case should be used for any further embedding after the first or if the default implementation works without an embedding and the alternative needs one.
ManifoldsBase.EmbeddedManifold — Type
EmbeddedManifold{𝔽, MT <: AbstractManifold, NT <: AbstractManifold} <: AbstractDecoratorManifold{𝔽}A type to represent an explicit embedding of a AbstractManifold M of type MT embedded into a manifold N of type NT. By default, an embedded manifold is set to be embedded, but neither isometrically embedded nor a submanifold.
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!. You can further pass functions to the embedding, for example, when it is an isometric embedding, by using an AbstractDecoratorManifold. 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
manifoldthe manifold that is an embedded manifoldembeddinga second manifold, the first one is embedded into
Constructor
EmbeddedManifold(M, N)Generate the EmbeddedManifold of the AbstractManifold M into the AbstractManifold N.
ManifoldsBase.decorated_manifold — Method
decorated_manifold(M::EmbeddedManifold, d::Val{N} = Val(-1))Return the manifold of M that is decorated with its embedding. For this specific type the internally stored enhanced manifold M.manifold is returned.
See also base_manifold, where this is used to (potentially) completely undecorate the manifold.
ManifoldsBase.get_embedding — Method
get_embedding(M::EmbeddedManifold)Return the embedding EmbeddedManifold N of M, if it exists.
ManifoldsBase.get_embedding_type — Method
get_embedding_type(::EmbeddedManifold)Specify the type of embedding. This by default returns EmbeddedManifoldType(). It can be further specified by dispatching in the parameters of the EmbeddedManifold.
Connections
Most connection-related functionality previously defined in Manifolds.jl is currently available here.
ManifoldsBase.AbstractAffineConnection — Type
AbstractAffineConnectionAbstract type for affine connections on a manifold.
ManifoldsBase.ConnectionManifold — Type
ConnectionManifold{𝔽,,M<:AbstractManifold{𝔽},G<:AbstractAffineConnection} <: AbstractDecoratorManifold{𝔽}Constructor
ConnectionManifold(M, C)Decorate the AbstractManifold M with AbstractAffineConnection C.
ManifoldsBase.LeviCivitaConnection — Type
LeviCivitaConnectionThe Levi-Civita connection of a Riemannian manifold.
ManifoldsBase.connection — Method
connection(M::AbstractManifold)Get the connection (an object of a subtype of AbstractAffineConnection) of AbstractManifold M.
The global default connection is the LeviCivitaConnection.
ManifoldsBase.connection — Method
connection(M::ConnectionManifold)Return the connection associated with ConnectionManifold M.
ManifoldsBase.is_default_connection — Method
is_default_connection(M::AbstractManifold, c::AbstractAffineConnection)returns whether an AbstractAffineConnection is the default metric on the manifold M or not.
This function falls back to check whether connection(M) == c.
Metrics
Most metric-related functionality is available here. A few additional functions are defined in Manifolds.jl.
ManifoldsBase.AbstractMetric — Type
AbstractMetricAbstract type for the pseudo-Riemannian metric tensor $g$, a family of smoothly varying inner products on the tangent space. See inner.
Functor
(metric::Metric)(M::AbstractManifold)
(metric::Metric)(M::MetricManifold)Generate the MetricManifold that wraps the manifold M with given metric. This works for both a variable containing the metric as well as a subtype T<:AbstractMetric, where a zero parameter constructor T() is available. If M is already a metric manifold, the inner manifold with the new metric is returned.
ManifoldsBase.DefaultMetric — Type
DefaultMetric <: AbstractMetricIndicating that a manifold uses the default metric, that one has implicitly assumed when defining the manifold
ManifoldsBase.EuclideanMetric — Type
EuclideanMetric <: RiemannianMetricA general type for any manifold that employs the Euclidean Metric, for example the Euclidean manifold itself, or the Sphere, where every tangent space (as a plane in the embedding) uses this metric (in the embedding).
Since the metric is independent of the field type, this metric is also used for the Hermitian metrics, i.e. metrics that are analogous to the EuclideanMetric but where the field type of the manifold is ℂ.
This metric is the default metric for example for the Euclidean manifold.
ManifoldsBase.MetricManifold — Type
MetricManifold{𝔽,M<:AbstractManifold{𝔽},G<:AbstractMetric} <: AbstractDecoratorManifold{𝔽}Equip a AbstractManifold explicitly with an AbstractMetric G.
If the AbstractMetric G yields closed form formulae for the exponential map or another function, you can implement it directly. Otherwise, you can use chart-based solvers, see for example solve_chart_exp_ode.
Constructor
MetricManifold(M, G)Generate the AbstractManifold M as a manifold with the AbstractMetric G.
ManifoldsBase.RiemannianMetric — Type
RiemannianMetric <: AbstractMetricAbstract type for Riemannian metrics, a family of positive definite inner products. The positive definite property means that for $X ∈ T_p \mathcal M$, the inner product $g(X, X) > 0$ whenever $X$ is not the zero vector.
Base.log — Method
log(N::MetricManifold{M,G}, p, q)Compute the logarithmic map on the AbstractManifold M equipped with the AbstractMetric G.
If the metric was declared the default metric, this method falls back to log(M, p, q). Otherwise, you have to provide an implementation for the non-default AbstractMetric G metric within its MetricManifold{M,G}.
ManifoldsBase.change_metric! — Method
change_metric!(M::AbstractManifold, Y, G2::AbstractMetric, p, X)Compute the change_metric in place of Y.
ManifoldsBase.change_metric — Method
change_metric(M::AbstractManifold, G2::AbstractMetric, p, X)On the AbstractManifold M with implicitly given metric $g_1$ and a second AbstractMetric $g_2$ this function performs a change of metric in the sense that it returns the tangent vector $Z=BX$ such that the linear map $B$ fulfills
\[g_2(Y_1,Y_2) = g_1(BY_1,BY_2) \quad \text{for all } Y_1, Y_2 ∈ T_p\mathcal M.\]
ManifoldsBase.change_representer! — Method
change_representer!(M::AbstractManifold, Y, G2::AbstractMetric, p, X)Compute the change_metric in place of Y.
ManifoldsBase.change_representer — Method
change_representer(M::AbstractManifold, G2::AbstractMetric, p, X)Convert the representer X of a linear function (in other words a cotangent vector at p) in the tangent space at p on the AbstractManifold M given with respect to the AbstractMetric G2 into the representer with respect to the (implicit) metric of M.
In order to convert X into the representer with respect to the (implicitly given) metric $g_1$ of M, we have to find the conversion function $c: T_p\mathcal M \to T_p\mathcal M$ such that
\[ g_2(X,Y) = g_1(c(X),Y)\]
ManifoldsBase.inner — Method
inner(N::MetricManifold{M,G}, p, X, Y)Compute the inner product of X and Y from the tangent space at p on the AbstractManifold M using the AbstractMetric G.
\[g_p(X, Y) = ⟨X, G_p Y⟩,\]
where $G_p$ is the local matrix representation of the AbstractMetric G.
ManifoldsBase.inverse_retract — Method
inverse_retract(M::MetricManifold, p, q)
inverse_retract!(M::MetricManifold, X, p, q)Compute the inverse retraction on the MetricManifold M. Since every inverse retraction is an inverse retraction with respect to any logarithmic map (induced by the metric), this method falls back to calling inverse_retract on the base manifold. The two exceptions are the LogarithmicInverseRetraction and ShootingInverseRetraction, in which case the method falls back to the default, that is to calling, respectively, log(::AbstractManifold, ::Any, ::Any) and inverse_retract_shooting!.
ManifoldsBase.is_default_metric — Method
is_default_metric(M::AbstractManifold, G::AbstractMetric)Return whether an AbstractMetric is the default metric on the manifold M or not.
If M is a |MetricManifold](@ref) this indicates whether the metric now used is the same as the default one on the wrapped manifold.
ManifoldsBase.metric — Method
metric(M::MetricManifold)Get the metric $g$ of the AbstractManifold(M).
ManifoldsBase.retract — Method
retract(M::MetricManifold, p, X)
retract!(M::MetricManifold, q, p, X)Compute the retraction on the MetricManifold M. Since every retraction is a retraction with respect to any exponential map (here induced by the metric), this method falls back to calling retract on the inner manifold. The one exception is the ExponentialRetraction, in which case the method falls back to the default, i.e. to calling exp(::AbstractManifold, ::Any, ::Any) but still on M.
ManifoldsBase.vector_transport_direction — Method
vector_transport_direction(M::MetricManifold, p, X, d)
vector_transport_direction!(M::MetricManifold, Y, p, X, d)Compute the vector transport of the tangent vector X at point p in the direction d on the MetricManifold M.
Since a vector transport is usually defined with respect to a retraction, cf. e.g. [AMS08], and the vector transport is closely related to an affine connection, it is to some extent metric dependent. Therefore, this method only falls back to calling its corresponding method on the base manifold, if the metric is the default one.
ManifoldsBase.vector_transport_to — Method
vector_transport_to(M::MetricManifold, p, X, d)
vector_transport_to!(M::MetricManifold, Y, p, X, d)Compute the vector transport of the tangent vector X at point p to a point q on the MetricManifold M.
Since a vector transport is usually defined with respect to a retraction, cf. e.g. [AMS08], and the vector transport is closely related to an affine connection, it is to some extent metric dependent. Therefore, this method only falls back to calling its corresponding method on the base manifold, if the metric is the default one.
A manifold for validation
ValidationManifold is a simple decorator using the AbstractDecoratorManifold that “decorates” a manifold with tests that all involved points and vectors are valid for the wrapped manifold. For example involved input and output paratemers are checked before and after running a function, repectively. This is done by calling is_point or is_vector whenever applicable.
ManifoldsBase.ValidationCotangentVector — Type
ValidationCotangentVector = ValidationFibreVector{CotangentSpaceType}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 ValidationMPoints vectors of other types.
ManifoldsBase.ValidationFibreVector — Type
ValidationFibreVector{TType<:VectorSpaceType,V,P} <: AbstractFibreVector{TType}Represent a tangent vector to a point on an ValidationManifold. The original vector of the manifold is stored internally. The corresponding base point of the fibre can be stored as well.
The TType indicates the type of fibre, for example TangentSpaceType or CotangentSpaceType.
Fields
value::V: the internally stored vector on the fibrepoint::P: the point the vector is associated with
Constructor
ValidationFibreVector{TType}(value, point=nothing)ManifoldsBase.ValidationMPoint — Type
ValidationMPoint{P} <: AbstractManifoldPointRepresent a point on an ValidationManifold. The point is stored internally.
Fields
value::P: the internally stored point on a manifold
Constructor
ValidationMPoint(value)Create a point on the manifold with the value value.
ManifoldsBase.ValidationManifold — Type
ValidationManifold{𝔽,M<:AbstractManifold{𝔽}} <: AbstractDecoratorManifold{𝔽}A manifold to add tests to input and output values of functions defined in the interface.
Additionally the points and tangent vectors can also be encapsulated, cf. ValidationMPoint, ValidationTangentVector, and ValidationCotangentVector. These types can be used to see where some data is assumed to be from, when working on manifolds where both points and tangent vectors are represented as (plain) arrays.
Using the ignore_contexts keyword allows to specify a single Symbol or a vector of Symbols Of which contexts to ignore.
Current contexts are
:All: disable all checks:Point: checks for points:Vector: checks for vectors:Output: checks for output:Input: checks for input variables
Using the ignore_functions keyword (dictionary) allows to disable/ignore certain checks within single functions for this manifold. The key of the dictionary has to be the Function to exclude something in. The value is either a single symbol or a vector of symbols with the same meaning as the ignore_contexts keyword, but limited to this function
Examples
exp => :Alldisables all checks in theexpfunctionexp => :Pointexcludes point checks in theexpfunctionexp => [:Point, :Vector]excludes point and vector checks in theexpfunction
This manifold is a decorator for a manifold, i.e. it decorates a AbstractManifold M with types points, vectors, and covectors.
Fields
manifold::M: The manifold to be decoratedmode::Symbol: The mode to be used for error handling, either:erroror:warnignore_contexts::AbstractVector{Symbol}: store contexts to be ignored of validation.ignore_functions::Dict{<:Function,<:Union{Symbol,<:AbstractVector{Symbol}}: store contexts to be ignored with in a function or its mutating variant.
Constructors
ValidationManifold(M::AbstractManifold; kwargs...)Generate the Validation manifold
ValidationManifold(M::AbstractManifold, V::ValidationManifold; kwargs...)Generate the Validation manifold for M with the default values of V.
Keyword arguments
error::Symbol=:error: specify how errors in the validation should be reported. this is passed tois_pointandis_vectoras theerrorkeyword argument. Available values are:error,:warn,:info, and:none. Every other value is treated as:none.store_base_point::Bool=false: specify whether or not to store the pointpa tangent or cotangent vector is associated with. This can be useful for debugging purposes.ignore_contexts = Vector{Symbol}()a vector to indicate which validation contexts should not be performed.ignore_functions=Dict{Function,Union{Symbol,Vector{Symbol}}}()a dictionary to disable certain contexts within functions. The key here is the non-mutating function variant (if it exists). The contexts are thre same as inignore_contexts.
ManifoldsBase.ValidationTangentVector — Type
ValidationTangentVector = ValidationFibreVector{TangentSpaceType}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 ValidationMPoints vectors of other types.
ManifoldsBase._msg — Method
_msg(str; error=:None, within::Union{Nothing,<:Function} = nothing,
context::Union{NTuple{N,Symbol} where N} = NTuple{0,Symbol}())issue a message str according to the mode mode (as @error, @warn, @info).
ManifoldsBase._vMc — Function
_vMc(M::ValidationManifold, f::Function, context::Symbol)
_vMc(M::ValidationManifold, f::Function, context::NTuple{N,Symbol}) where {N}Return whether a check should be performed within f and the context(s) provided.
This function returns false and hence indicates not to check, when
- (one of the)
context(s) is in the ignore list forfwithinignore_functions - (one of the)
context(s) is in theignore_contextslist
Otherwise the test is active.
!!! Note This function is internal and used very often, co it has a very short name; _vMc stands for "ValidationManifold check".
ManifoldsBase.internal_value — Method
internal_value(p)Return the internal value of an ValidationMPoint, ValidationTangentVector, or ValidationCotangentVector if the value p is encapsulated as such. Return p if it is already an a (plain) value on a manifold.
ManifoldsBase.is_point — Method
is_point(M::ValidationManifold, p; kwargs...)Perform is_point on a ValidationManifold, where two additional keywords can be used
within=nothingto specify a function from within which this call was issuedcontext::NTuple{N,Symbol} where N=()to specify one or more contexts, this call was issued in. The context:Pointis added before checking whether the test should be performed
all other keywords are passed on.
ManifoldsBase.is_vector — Function
is_vector(M::ValidationManifold, p, X, cbp=true; kwargs...)perform is_vector on a ValidationManifold, where two additional keywords can be used
within=nothingto specify a function from within which this call was issuedcontext::NTuple{N,Symbol} where N=()to specify one or more contexts, this call was issued in. The context:Pointis added before checking whether the test should be performed
all other keywords are passed on.