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

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

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