# The Manifold interface

## The `AbstractManifold`

The main type is the `AbstractManifold`

. It represents the manifold per se. Throughout the documentation of `ManifoldsBase.jl`

we might use the Euclidean Space and the Sphere (both implemented in Manifolds.jl) as easy examples to illustrate properties and features of this interface on concrete examples.

`ManifoldsBase.AbstractManifold`

— Type`AbstractManifold{𝔽}`

A type to represent a (Riemannian) manifold. The `AbstractManifold`

is a central type of this interface. It allows to distinguish different implementations of functions like the `exp`

onential and `log`

arithmic map for different manifolds. Usually, the manifold is the first parameter in any of these functions within `ManifoldsBase.jl`

. Based on these, say “elementary” functions, as the two mentioned above, more general functions are built, for example the `shortest_geodesic`

and the `geodesic`

. These should only be overwritten (reimplemented) if for a certain manifold specific, more efficient implementations are possible, that do not just call the elementary functions.

The [`AbstractManifold`

] is parametrized by `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.

which should store information about the manifold, for example parameters inherent to the manifold.

## Points on a manifold

Points do not necessarily have to be typed. Usually one can just use any type. When a manifold has multiple representations, these should be distinguished by point and vector types.

`ManifoldsBase.AbstractManifoldPoint`

— Type`AbstractManifoldPoint`

Type for a point on a manifold. While an `AbstractManifold`

does not necessarily require this type, for example when it is implemented for `Vector`

s or `Matrix`

type elements, this type can be used either

- for more complicated representations,
- semantic verification, or
- when dispatching on different representations of points on a manifold.

Since semantic verification and different representations usually might still only store a matrix internally, it is possible to use `@manifold_element_forwards`

and `@default_manifold_fallbacks`

to reduce implementation overhead.

Converting points between different representations can be performed using the `convert`

function with either two or three arguments (`convert(T, M, p)`

or `convert(T, p)`

). For some manifolds providing `M`

may be necessary. The first variant falls back to the second variant.

## Tangent and Cotangent spaces

`ManifoldsBase.AbstractFibreVector`

— Type`AbstractFibreVector{TType<:VectorSpaceType}`

Type for a vector from a vector space (fibre of a vector bundle) of type `TType`

of a manifold. While a `AbstractManifold`

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.

You may use macro `@manifold_vector_forwards`

to introduce commonly used method definitions for your subtype of `AbstractFibreVector`

.

`ManifoldsBase.CoTVector`

— Type`CoTVector = AbstractFibreVector{CotangentSpaceType}`

Type for a cotangent vector of a manifold. While a `AbstractManifold`

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.FVector`

— Type`FVector(type::VectorSpaceType, data, basis::AbstractBasis)`

Decorator indicating that the vector `data`

contains coordinates of a vector from a fiber of a vector bundle of type `type`

. `basis`

is an object describing the basis of that space in which the coordinates are given.

Conversion between `FVector`

representation and the default representation of an object (for example a tangent vector) for a manifold should be done using `get_coordinates`

and `get_vector`

.

**Examples**

```
julia> using Manifolds
julia> M = Sphere(2)
Sphere(2, ℝ)
julia> p = [1.0, 0.0, 0.0]
3-element Vector{Float64}:
1.0
0.0
0.0
julia> X = [0.0, 2.0, -1.0]
3-element Vector{Float64}:
0.0
2.0
-1.0
julia> B = DefaultOrthonormalBasis()
DefaultOrthonormalBasis(ℝ)
julia> fX = TFVector(get_coordinates(M, p, X, B), B)
TFVector([2.0, -1.0], DefaultOrthonormalBasis(ℝ))
julia> X_back = get_vector(M, p, fX.data, fX.basis)
3-element Vector{Float64}:
-0.0
2.0
-1.0
```

`ManifoldsBase.TVector`

— Type`TVector = AbstractFibreVector{TangentSpaceType}`

Type for a tangent vector of a manifold. While a `AbstractManifold`

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.

`ManifoldsBase.vector_space_dimension`

— Method`vector_space_dimension(M::AbstractManifold, V::VectorSpaceType)`

Dimension of the vector space of type `V`

on manifold `M`

.

This interface also covers a large variety how to model bases in tangent spaces.

Converting tangent vectors between different representations can be performed using the `convert`

function with either three or four arguments (`convert(T, M, p, X)`

or `convert(T, p, X)`

). For some manifolds providing `M`

may be necessary. The first variant falls back to the second variant.

## Macros for automatic forwards for simple points/tangent vectors

When distinguishing different representations of points or tangent vectors on one manifold, it might happen that both a subtype of `AbstractManifoldPoint`

and a subtype of `TVector`

are just encapsulating a value

This is taken into account by the following macros, that forward several actions just to this field. Most prominently vector operations for the tangent vectors. If there is still a default case, a macro sets this type to be equivalent to calling the manifold functions just with the types field that carries the value.

`ManifoldsBase.@default_manifold_fallbacks`

— Macro`default_manifold_fallbacks(TM, TP, TV, pfield::Symbol, vfield::Symbol)`

Introduce default fallbacks for all basic functions on manifolds, for manifold of type `TM`

, points of type `TP`

, tangent vectors of type `TV`

, with forwarding to fields `pfield`

and `vfield`

for point and tangent vector functions, respectively.

`ManifoldsBase.@manifold_element_forwards`

— Macro```
manifold_element_forwards(T, field::Symbol)
manifold_element_forwards(T, Twhere, field::Symbol)
```

Introduce basic fallbacks for type `T`

(which can be a subtype of `Twhere`

) that represents points or vectors for a manifold. Fallbacks will work by forwarding to the field passed in `field`

`

List of forwarded functions:

`allocate`

,`copy`

,`copyto!`

,`number_eltype`

(only for values, not the type itself),`similar`

,`size`

,`==`

.

`ManifoldsBase.@manifold_vector_forwards`

— Macro```
manifold_vector_forwards(T, field::Symbol)
manifold_vector_forwards(T, Twhere, field::Symbol)
```

Introduce basic fallbacks for type `T`

that represents vectors from a vector bundle for a manifold. `Twhere`

is put into `where`

clause of each method. Fallbacks work by forwarding to field passed as `field`

.

List of forwarded functions:

- basic arithmetic (
`*`

,`/`

,`\`

,`+`

,`-`

), - all things from
`@manifold_element_forwards`

, - broadcasting support.

**example**

`@eval @manifold_vector_forwards ValidationFibreVector{TType} TType value`

## Number Systems

The `AbstractManifold`

has one parameter to distinguish the number system a manifold is based on.

`ManifoldsBase.AbstractNumbers`

— Type`AbstractNumbers`

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`

— Type```
ComplexNumbers <: AbstractNumbers
ℂ = ComplexNumbers()
```

The field of complex numbers.

`ManifoldsBase.QuaternionNumbers`

— Type```
QuaternionNumbers <: AbstractNumbers
ℍ = QuaternionNumbers()
```

The division algebra of quaternions.

`ManifoldsBase.RealNumbers`

— Type```
RealNumbers <: 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`

— Method`number_system(M::AbstractManifold{𝔽})`

Return the number system the manifold `M`

is based on, i.e. the parameter `𝔽`

.

`ManifoldsBase.real_dimension`

— Method`real_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.

## Type Parameter

Concrete `AbstractManifold`

s usually correspond to families of manifolds that are parameterized by some numbers, for example determining their `manifold_dimension`

. Those numbers can either be stored in a field or as a type parameter of the structure. The `TypeParameter`

offers the flexibility to have this parameter either as type parameter or a field.

`ManifoldsBase.TypeParameter`

— Type`TypeParameter{T}`

Represents numeric parameters of a manifold type as type parameters, allowing for static specialization of methods.

`ManifoldsBase.wrap_type_parameter`

— Function`wrap_type_parameter(parameter::Symbol, data)`

Wrap `data`

in `TypeParameter`

if `parameter`

is `:type`

or return `data`

unchanged if `parameter`

is `:field`

. Intended for use in manifold constructors, see `DefaultManifold`

for an example.