# Bases for tangent spaces

The following functions and types provide support for bases of the tangent space of different manifolds. Moreover, bases of the cotangent space are also supported, though this description focuses on the tangent space. An orthonormal basis of the tangent space $T_p \mathcal M$ of (real) dimension $n$ has a real-coefficient basis $e_1, e_2, …, e_n$ if $\mathrm{Re}(g_p(e_i, e_j)) = δ_{ij}$ for each $i,j ∈ \{1, 2, …, n\}$ where $g_p$ is the Riemannian metric at point $p$. A vector $X$ from the tangent space $T_p \mathcal M$ can be expressed in Einstein notation as a sum $X = X^i e_i$, where (real) coefficients $X^i$ are calculated as $X^i = \mathrm{Re}(g_p(X, e_i))$.

The main types are:

`DefaultOrthonormalBasis`

, which is designed to work when no special properties of the tangent space basis are required. It is designed to make`get_coordinates`

and`get_vector`

fast.`DiagonalizingOrthonormalBasis`

, which diagonalizes the curvature tensor and makes the curvature in the selected direction equal to 0.`ProjectedOrthonormalBasis`

, which projects a basis of the ambient space and orthonormalizes projections to obtain a basis in a generic way.`CachedBasis`

, which stores (explicitly or implicitly) a precomputed basis at a certain point.

The main functions are:

`get_basis`

precomputes a basis at a certain point.`get_coordinates`

returns coordinates of a tangent vector.`get_vector`

returns a vector for the specified coordinates.`get_vectors`

returns a vector of basis vectors. Calling it should be avoided for high-dimensional manifolds.

`ManifoldsBase.AbstractBasis`

— Type`AbstractBasis{𝔽,VST<:VectorSpaceType}`

Abstract type that represents a basis of vector space of type `VST`

on a manifold or a subset of it.

The type parameter `𝔽`

denotes the `AbstractNumbers`

that will be used for the vectors elements.

**See also**

`ManifoldsBase.AbstractOrthogonalBasis`

— Type`AbstractOrthogonalBasis{𝔽,VST<:VectorSpaceType}`

Abstract type that represents an orthonormal basis of vector space of type `VST`

on a manifold or a subset of it.

The type parameter `𝔽`

denotes the `AbstractNumbers`

that will be used for the vectors elements.

**See also**

`ManifoldsBase.AbstractOrthonormalBasis`

— Type`AbstractOrthonormalBasis{𝔽,VST<:VectorSpaceType}`

Abstract type that represents an orthonormal basis of vector space of type `VST`

on a manifold or a subset of it.

The type parameter `𝔽`

denotes the `AbstractNumbers`

that will be used for the vectors elements.

**See also**

`ManifoldsBase.CachedBasis`

— Type`CachedBasis{𝔽,V,<:AbstractBasis{𝔽}} <: AbstractBasis{𝔽}`

A cached version of the given `basis`

with precomputed basis vectors. The basis vectors are stored in `data`

, either explicitly (like in cached variants of `ProjectedOrthonormalBasis`

) or implicitly.

**Constructor**

`CachedBasis(basis::AbstractBasis, data)`

`ManifoldsBase.CotangentSpaceType`

— Type`struct CotangentSpaceType <: VectorSpaceType end`

A type that indicates that a `Fiber`

is a `CotangentSpace`

.

`ManifoldsBase.DefaultBasis`

— Type`DefaultBasis{𝔽,VST<:VectorSpaceType}`

An arbitrary basis of vector space of type `VST`

on a manifold. This will usually be the fastest basis available for a manifold.

The type parameter `𝔽`

denotes the `AbstractNumbers`

that will be used for the vectors elements.

**See also**

`ManifoldsBase.DefaultOrthogonalBasis`

— Type`DefaultOrthogonalBasis{𝔽,VST<:VectorSpaceType}`

An arbitrary orthogonal basis of vector space of type `VST`

on a manifold. This will usually be the fastest orthogonal basis available for a manifold.

The type parameter `𝔽`

denotes the `AbstractNumbers`

that will be used for the vectors elements.

**See also**

`ManifoldsBase.DefaultOrthonormalBasis`

— Type`DefaultOrthonormalBasis(𝔽::AbstractNumbers = ℝ, vs::VectorSpaceType = TangentSpaceType())`

An arbitrary orthonormal basis of vector space of type `VST`

on a manifold. This will usually be the fastest orthonormal basis available for a manifold.

The type parameter `𝔽`

denotes the `AbstractNumbers`

that will be used for the vectors elements.

**See also**

`ManifoldsBase.DiagonalizingOrthonormalBasis`

— Type`DiagonalizingOrthonormalBasis{𝔽,TV} <: AbstractOrthonormalBasis{𝔽,TangentSpaceType}`

An orthonormal basis `Ξ`

as a vector of tangent vectors (of length determined by `manifold_dimension`

) in the tangent space that diagonalizes the curvature tensor $R(u,v)w$ and where the direction `frame_direction`

$v$ has curvature `0`

.

The type parameter `𝔽`

denotes the `AbstractNumbers`

that will be used for the vectors elements.

**Constructor**

`DiagonalizingOrthonormalBasis(frame_direction, 𝔽::AbstractNumbers = ℝ)`

`ManifoldsBase.GramSchmidtOrthonormalBasis`

— Type`GramSchmidtOrthonormalBasis{𝔽} <: AbstractOrthonormalBasis{𝔽}`

An orthonormal basis obtained from a basis.

**Constructor**

`GramSchmidtOrthonormalBasis(𝔽::AbstractNumbers = ℝ)`

`ManifoldsBase.ProjectedOrthonormalBasis`

— Type`ProjectedOrthonormalBasis(method::Symbol, 𝔽::AbstractNumbers = ℝ)`

An orthonormal basis that comes from orthonormalization of basis vectors of the ambient space projected onto the subspace representing the tangent space at a given point.

The type parameter `𝔽`

denotes the `AbstractNumbers`

that will be used for the vectors elements.

Available methods:

`:gram_schmidt`

uses a modified Gram-Schmidt orthonormalization.`:svd`

uses SVD decomposition to orthogonalize projected vectors. The SVD-based method should be more numerically stable at the cost of an additional assumption (local metric tensor at a point where the basis is calculated has to be diagonal).

`ManifoldsBase.TangentSpaceType`

— Type`struct TangentSpaceType <: VectorSpaceType end`

A type that indicates that a `Fiber`

is a `TangentSpace`

.

`ManifoldsBase.VectorSpaceType`

— Type`VectorSpaceType`

Abstract type for tangent spaces, cotangent spaces, their tensor products, exterior products, etc.

Every vector space `fiber`

is supposed to provide:

- a method of constructing vectors,
- basic operations: addition, subtraction, multiplication by a scalar and negation (unary minus),
`zero_vector(fiber, p)`

to construct zero vectors at point`p`

,`allocate(X)`

and`allocate(X, T)`

for vector`X`

and type`T`

,`copyto!(X, Y)`

for vectors`X`

and`Y`

,`number_eltype(v)`

for vector`v`

,`vector_space_dimension`

.

Optionally:

- inner product via
`inner`

(used to provide Riemannian metric on vector bundles), `flat`

and`sharp`

,`norm`

(by default uses`inner`

),`project`

(for embedded vector spaces),`representation_size`

,- broadcasting for basic operations.

`ManifoldsBase.allocate_coordinates`

— Method`allocate_coordinates(M::AbstractManifold, p, T, n::Int)`

Allocate vector of coordinates of length `n`

of type `T`

of a vector at point `p`

on manifold `M`

.

`ManifoldsBase.allocation_promotion_function`

— Method`allocation_promotion_function(M::AbstractManifold, f, args::Tuple)`

Determine the function that must be used to ensure that the allocated representation is of the right type. This is needed for `get_vector`

when a point on a complex manifold is represented by a real-valued vectors with a real-coefficient basis, so that a complex-valued vector representation is allocated.

`ManifoldsBase.change_basis`

— Method`change_basis(M::AbstractManifold, p, c, B_in::AbstractBasis, B_out::AbstractBasis)`

Given a vector with coordinates `c`

at point `p`

from manifold `M`

in basis `B_in`

, compute coordinates of the same vector in basis `B_out`

.

`ManifoldsBase.coordinate_eltype`

— Method`coordinate_eltype(M::AbstractManifold{M𝔽}, p, 𝔽::AbstractNumbers) where {M𝔽}`

Get the element type for 𝔽-field coordinates of the tangent space at a point `p`

from manifold `M`

. This default assumes that usually complex bases of complex manifolds have real coordinates but it can be overridden by a more specific method.

`ManifoldsBase.dual_basis`

— Method`dual_basis(M::AbstractManifold, p, B::AbstractBasis)`

Get the dual basis to `B`

, a basis of a vector space at point `p`

from manifold `M`

.

The dual to the $i$th vector $v_i$ from basis `B`

is a vector $v^i$ from the dual space such that $v^i(v_j) = δ^i_j$, where $δ^i_j$ is the Kronecker delta symbol:

\[δ^i_j = \begin{cases} 1 & \text{ if } i=j, \\ 0 & \text{ otherwise.} \end{cases}\]

`ManifoldsBase.get_basis`

— Method`get_basis(M::AbstractManifold, p, B::AbstractBasis; kwargs...) -> CachedBasis`

Compute the basis vectors of the tangent space at a point on manifold `M`

represented by `p`

.

Returned object derives from `AbstractBasis`

and may have a field `.vectors`

that stores tangent vectors or it may store them implicitly, in which case the function `get_vectors`

needs to be used to retrieve the basis vectors.

See also: `get_coordinates`

, `get_vector`

`ManifoldsBase.get_coordinates`

— Method```
get_coordinates(M::AbstractManifold, p, X, B::AbstractBasis)
get_coordinates(M::AbstractManifold, p, X, B::CachedBasis)
```

Compute a one-dimensional vector of coefficients of the tangent vector `X`

at point denoted by `p`

on manifold `M`

in basis `B`

.

Depending on the basis, `p`

may not directly represent a point on the manifold. For example if a basis transported along a curve is used, `p`

may be the coordinate along the curve. If a `CachedBasis`

is provided, their stored vectors are used, otherwise the user has to provide a method to compute the coordinates.

For the `CachedBasis`

keep in mind that the reconstruction with `get_vector`

requires either a dual basis or the cached basis to be selfdual, for example orthonormal

See also: `get_vector`

, `get_basis`

`ManifoldsBase.get_vector`

— Method`X = get_vector(M::AbstractManifold, p, c, B::AbstractBasis)`

Convert a one-dimensional vector of coefficients in a basis `B`

of the tangent space at `p`

on manifold `M`

to a tangent vector `X`

at `p`

.

Depending on the basis, `p`

may not directly represent a point on the manifold. For example if a basis transported along a curve is used, `p`

may be the coordinate along the curve.

For the `CachedBasis`

keep in mind that the reconstruction from `get_coordinates`

requires either a dual basis or the cached basis to be selfdual, for example orthonormal

See also: `get_coordinates`

, `get_basis`

`ManifoldsBase.get_vectors`

— Method`get_vectors(M::AbstractManifold, p, B::AbstractBasis)`

Get the basis vectors of basis `B`

of the tangent space at point `p`

.

`ManifoldsBase.gram_schmidt`

— Method```
gram_schmidt(M::AbstractManifold{𝔽}, p, B::AbstractBasis{𝔽}) where {𝔽}
gram_schmidt(M::AbstractManifold, p, V::AbstractVector)
```

Compute an ONB in the tangent space at `p`

on the [`AbstractManifold`

](@ref} `M`

from either an `AbstractBasis`

basis ´B´ or a set of (at most) `manifold_dimension`

`(M)`

many vectors. Note that this method requires the manifold and basis to work on the same `AbstractNumbers`

`𝔽`

, i.e. with real coefficients.

The method always returns a basis, i.e. linearly dependent vectors are removed.

**Keyword arguments**

`warn_linearly_dependent`

(`false`

) – warn if the basis vectors are not linearly independent`skip_linearly_dependent`

(`false`

) – whether to just skip (`true`

) a vector that is linearly dependent to the previous ones or to stop (`false`

, default) at that point`return_incomplete_set`

(`false`

) – throw an error if the resulting set of vectors is not a basis but contains less vectors

further keyword arguments can be passed to set the accuracy of the independence test. Especially `atol`

is raised slightly by default to `atol = 5*1e-16`

.

**Return value**

When a set of vectors is orthonormalized a set of vectors is returned. When an `AbstractBasis`

is orthonormalized, a `CachedBasis`

is returned.

`ManifoldsBase.hat`

— Method`hat(M::AbstractManifold, p, Xⁱ)`

Given a basis $e_i$ on the tangent space at a point `p`

and tangent component vector $X^i ∈ ℝ$, compute the equivalent vector representation $X=X^i e_i$, where Einstein summation notation is used:

\[∧ : X^i ↦ X^i e_i\]

For array manifolds, this converts a vector representation of the tangent vector to an array representation. The `vee`

map is the `hat`

map's inverse.

`ManifoldsBase.number_of_coordinates`

— Method```
number_of_coordinates(M::AbstractManifold{𝔽}, B::AbstractBasis)
number_of_coordinates(M::AbstractManifold{𝔽}, ::𝔾)
```

Compute the number of coordinates in basis of field type `𝔾`

on a manifold `M`

. This also corresponds to the number of vectors represented by `B`

, or stored within `B`

in case of a `CachedBasis`

.

`ManifoldsBase.number_system`

— Method`number_system(::AbstractBasis)`

The number system for the vectors of the given basis.

`ManifoldsBase.requires_caching`

— Method`requires_caching(B::AbstractBasis)`

Return whether basis `B`

can be used in `get_vector`

and `get_coordinates`

without calling `get_basis`

first.

`ManifoldsBase.vee`

— Method`vee(M::AbstractManifold, p, X)`

Given a basis $e_i$ on the tangent space at a point `p`

and tangent vector `X`

, compute the vector components $X^i ∈ ℝ$, such that $X = X^i e_i$, where Einstein summation notation is used:

\[\vee : X^i e_i ↦ X^i\]

For array manifolds, this converts an array representation of the tangent vector to a vector representation. The `hat`

map is the `vee`

map's inverse.