A Decorator for manifolds
Several properties of a manifold are often implicitly assumed, for example the choice of the (Riemannian) metric or the embedding. The latter shall serve as an example how to either implicitly or explicitly specify the embedding to avoid re-implementations and/or distinguish different embeddings.
The abstract decorator
When first implementing a manifold, it might be beneficial to dispatch certain computations to already existing manifolds. For an embedded manifold that is isometrically embedded this might be the inner
the manifold inherits in each tangent space from its embedding.
This means we would like to dispatch the default implementation of a function to some other manifold. We refer to this as implicit decoration, since one can not “see” explicitly that a certain manifold inherits this property. As an example consider the Sphere. At each point the tangent space can be identified with a subspace of the tangent space in the embedding, the Euclidean manifold which the unit vectors of the sphere belong to. Thus every tangent space inherits its metric from the embedding. Since in the default implementation in Manifolds.jl points are represented by unit vectors and tangent vectors at a point as vectors orthogonal to that point, we can just dispatch the inner product to the embedding without having to re-implement this. The manifold using such an implicit dispatch just has to be a subtype of AbstractDecoratorManifold
.
Traits with an inheritance hierarchy
The properties mentioned above might form a hierarchy. For embedded manifolds, again, we might have just a manifold whose points are represented in some embedding. If the manifold is even isometrically embedded, it is embedded but also inherits the Riemannian metric by restricting the metric from the embedding to the corresponding tangent space under consideration. But it also inherits the functions defined for the plain embedding, for example checking some conditions for the validity of points and vectors. If it is even a submanifold, also further functions are inherited like the shortest_geodesic
.
We use a variation of Tim Holy's Traits Trick (THTT) which takes into account kind of traits.
To be precise we have a generic AbstractForwardingType
to indicate that on the decorator manifold we want to (or not want to) forward a certain function. To add more semantics one can use subtypes of this type like AbstractEmbeddedForwardingType
to indicate how to forward certain functions for the embedding type.
ManifoldsBase.AbstractDecoratorManifold
— TypeAbstractDecoratorManifold{𝔽} <: AbstractManifold{𝔽}
Declare a manifold to be an abstract decorator. A manifold which is a subtype of is a decorated manifold, i.e. has
- certain additional properties or
- delegates certain properties to other manifolds.
Most prominently, a manifold might be an embedded manifold, i.e. points on a manifold $\mathcal M$ are represented by (some, maybe not all) points on another manifold $\mathcal N$. Depending on the type of embedding, several functions are dedicated to the embedding. For example if the embedding is isometric, then the inner
does not have to be implemented for $\mathcal M$ but can be automatically implemented by deligation to $\mathcal N$.
This is modelled by the AbstractDecoratorManifold
and traits. These are mapped to functions, which determine the types of transparencies.
The Manifold decorator
The idea of the decorator for a manifold is to allow to exchange certain functionality by a dispatch layer. For example that for an embedded manifold some functions are passed to the embedding, or that for a metric manifold decorator, all functions unrelated to the metric are passed to the original manifold. The following types, functions, and macros introduce the decorator trait which allows to decorate an arbitrary <:
AbstractDecoratorManifold
with further features.
ManifoldsBase.AbstractEmbeddedForwardingType
— TypeAbstractEmbeddedForwardingType
An abstract type to specify the forwarding behaviour of a function when it should forward to the embedding of a manifold.
ManifoldsBase.AbstractEmbeddingDirectness
— Typeabstract type AbstractEmbeddingDirectness end
Supertype for DirectEmbedding
and IndirectEmbedding
that indicate whether embed
on a manifold is an identity or not.
ManifoldsBase.AbstractEmbeddingType
— TypeAbstractEmbeddingType
Within all AbstractEmbeddedForwardingType
s this type is used to indicate different kinds of embeddings, for example the default fallback that NotEmbeddedManifoldType
a manifold is not embedded, that is is embedded using EmbeddedManifoldType
or even specifying further that it is isometrically embedded using IsometricallyEmbeddedManifoldType
or as furthermore a submanifold using EmbeddedSubmanifoldType
.
ManifoldsBase.AbstractForwardingType
— TypeAbstractForwardingType
An abstract type to specify the forwarding behaviour of a function for a decorator manifold or a trait within ManifoldsBase.jl
.
ManifoldsBase.DirectEmbedding
— Typestruct DirectEmbedding <: AbstractEmbeddingDirectness end
A struct indicating that embed
is an identity function on a manifold.
ManifoldsBase.EmbeddedForwardingType
— TypeEmbeddedForwardingType{TED<:AbstractEmbeddingDirectness} <: AbstractEmbeddedForwardingType
A property of an embedded manifold that indicates that embed
and project
are available and that a function using this trait type forwards to the embedding. The type parameter TED
, a subtype of AbstractEmbeddingDirectness
, indicates whether embed
on points and tangent vectors needs to be called or is an identity and can be skipped.
ManifoldsBase.EmbeddedManifoldType
— TypeEmbeddedManifoldType <: AbstractEmbeddingType
A property of an embedded manifold that indicates that embed
and project
are available.
ManifoldsBase.EmbeddedSubmanifoldType
— TypeEmbeddedSubmanifoldType <: AbstractEmbeddingType
A property to determine whether an AbstractDecoratorManifold
M
is an embedded submanifold. It is a special case of the IsometricallyEmbeddedManifoldType
property, i.e. it has all properties of this property.
In this property, additionally to the isometric embedded manifold, all retractions, inverse retractions, and vectors transports, especially exp
, log
, and parallel_transport_to
are passed to the embedding.
ManifoldsBase.IndirectEmbedding
— Typestruct IndirectEmbedding <: AbstractEmbeddingDirectness end
A struct indicating that embed
is not an identity function on a manifold.
ManifoldsBase.IsometricallyEmbeddedManifoldType
— TypeIsometricallyEmbeddedManifold <: AbstractEmbeddingType
A property to determine whether an AbstractDecoratorManifold
M
is an isometrically embedded manifold.
Here, additionally, metric related functions like inner
and norm
are passed to the embedding
ManifoldsBase.NotEmbeddedManifoldType
— TypeNotEmbeddedManifoldType <: AbstractEmbeddingType
A property of an embedded manifold that indicates that embed
and project
are not available.
ManifoldsBase.SimpleForwardingType
— TypeSimpleForwardingType <: AbstractForwardingType
A type that indicates forwarding to the wrapped manifold without any changes.
ManifoldsBase.StopForwardingType
— TypeStopForwardingType <: AbstractForwardingType
A type that indicates that a function should not forward to a certain other manifold, e.g. and embedding. This means that the user is asked to implement this function themselfes.
ManifoldsBase.decorated_manifold
— Methoddecorated_manifold(M::AbstractDecoratorManifold)
For a manifold M
that is decorated with some properties, this function returns the manifold without that manifold, i.e. the manifold that was decorated.
ManifoldsBase.get_embedding
— Methodget_embedding(M::AbstractDecoratorManifold)
get_embedding(M::AbstractDecoratorManifold, p)
Specify the embedding of a manifold that has abstract decorators. the embedding might depend on a point representation, where different point representations are distinguished as subtypes of AbstractManifoldPoint
. A unique or default representation might also just be an AbstractArray
.
ManifoldsBase.get_embedding_type
— Methodget_embedding_type(M::AbstractManifold)
get_embedding_type(M::AbstractManifold, p)
Get embedding type of AbstractManifold
M
. The returned value is an object of a subtype of AbstractEmbeddingType
, either of:
NotEmbeddedManifoldType
(default),EmbeddedManifoldType
,IsometricallyEmbeddedManifoldType
,EmbeddedSubmanifoldType
.
Point p
can be optionally specified if different point types correspond to different embeddings.
ManifoldsBase.get_forwarding_type
— Methodget_forwarding_type(M::AbstractManifold, f)
get_forwarding_type(M::AbstractManifold, f, p)
Get the type of forwarding to manifold wrapped by AbstractManifold
M
, for function f
. The returned value is an object of a subtype of AbstractForwardingType
.
Point p
can be optionally specified if different point types correspond to different representations of the manifold and hence possibly different embeddings.
For an example see the (implicit) embedded manifold.