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.

DefaultManifold <: AbstractManifold

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 variables.


DefaultManifold(n::Int...; field = ℝ, parameter::Symbol = :field)


  • 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 store n. By default size is stored in a field. Value can either be :field or :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 IsEmbeddedManifold Trait

For the implicit case, your manifold has to be a subtype of the AbstractDecoratorManifold. Adding a method to the active_traits function for a manifold that returns an AbstractTrait IsEmbeddedManifold, makes that manifold an embedded manifold. You just have to also define get_embedding so that appropriate functions are passed on to that embedding. 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.

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.


  • manifold the manifold that is an embedded manifold
  • embedding a second manifold, the first one is embedded into


EmbeddedManifold(M, N)

Generate the EmbeddedManifold of the AbstractManifold M into the AbstractManifold N.

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.



Most metric-related functionality is currently defined in Manifolds.jl but a few basic types are defined here.


Abstract type for the pseudo-Riemannian metric tensor $g$, a family of smoothly varying inner products on the tangent space. See inner.



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 availabe. If M is already a metric manifold, the inner manifold with the new metric is returned.

EuclideanMetric <: RiemannianMetric

A 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.

RiemannianMetric <: AbstractMetric

Abstract 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.

change_metric(M::AbstractcManifold, 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.\]

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)\]


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.

ValidationManifold{𝔽,M<:AbstractManifold{𝔽}} <: AbstractDecoratorManifold{𝔽}

A manifold to encapsulate manifolds working on array representations of AbstractManifoldPoints and TVectors 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 AbstractManifold M with types points, vectors, and covectors.


ValidationManifold(M::AbstractManifold; error::Symbol = :error)

Generate the Validation manifold, where error is used as the symbol passed to all checks. This :errors by default but could also be set to :warn for example