Meta Manifolds

While the interface does not provide concrete manifolds itself, it does provide several manifolds that can be built based on a given AbstractManifold instance.

(Abstract) power manifold

A power manifold is constructed like higher dimensional vector spaces are formed from the real line, just that for every point $p = (p_1,\ldots,p_n) ∈ \mathcal M^n$ on the power manifold $\mathcal M^n$ the entries of $p$ are points $p_1,\ldots,p_n ∈ \mathcal M$ on some manifold $\mathcal M$. Note that $n$ can also be replaced by multiple values, such that $p$ is not a vector but a matrix or a multi-index array of points.

ManifoldsBase.PowerManifold — Type
PowerManifold{𝔽,TM<:AbstractManifold,TSize,TPR<:AbstractPowerRepresentation} <: AbstractPowerManifold{𝔽,TM,TPR}

The power manifold $\mathcal M^{n_1× n_2 × … × n_d}$ with power geometry. TSize defines the number of elements along each axis, either statically using TypeParameter or storing it in a field.

For example, a manifold-valued time series would be represented by a power manifold with $d$ equal to 1 and $n_1$ equal to the number of samples. A manifold-valued image (for example in diffusion tensor imaging) would be represented by a two-axis power manifold ($d=2$) with $n_1$ and $n_2$ equal to width and height of the image.

While the size of the manifold is static, points on the power manifold would not be represented by statically-sized arrays.

Constructor

PowerManifold(M::PowerManifold, N_1, N_2, ..., N_d; parameter::Symbol=_parameter_symbol(M))PowerManifold(M::AbstractManifold, NestedPowerRepresentation(), N_1, N_2, ..., N_d; parameter::Symbol=:field)M^(N_1, N_2, ..., N_d)

Generate the power manifold $M^{N_1 × N_2 × … × N_d}$. By default, a PowerManifold is expanded further, i.e. for M=PowerManifold(N, 3) PowerManifold(M, 2) is equivalent to PowerManifold(N, 3, 2). Points are then 3×2 matrices of points on N. Providing a NestedPowerRepresentation as the second argument to the constructor can be used to nest manifold, i.e. PowerManifold(M, NestedPowerRepresentation(), 2) represents vectors of length 2 whose elements are vectors of length 3 of points on N in a nested array representation.

The third signature M^(...) is equivalent to the first one, and hence either yields a combination of power manifolds to one larger power manifold, or a power manifold with the default representation.

Since there is no default AbstractPowerRepresentation within this interface, the ^ operator is only available for PowerManifolds and concatenates dimensions.

parameter: whether a type parameter should be used to store n. By default size is stored in a field, unless M is a PowerManifold, then its storage is inherited. Value can either be :field or :type.

source
Base.copyto! — Method
copyto!(M::PowerManifoldNested, Y, p, X)

Copy the values elementwise, i.e. call copyto!(M.manifold, B, a, A) for all elements A, a and B of X, p, and Y, respectively.

source
Base.copyto! — Method
copyto!(M::PowerManifoldNested, q, p)

Copy the values elementwise, i.e. call copyto!(M.manifold, b, a) for all elements a and b of p and q, respectively.

source
Base.fill! — Method
fill!(P, p, M::AbstractPowerManifold)

Fill a point P on the AbstractPowerManifold M, setting every entry to p.

Note

while usually the manifold is the first argument in all functions in ManifoldsBase.jl, we follow the signature of fill!, where the power manifold serves as the size information.

source
Base.fill — Method
fill(p, M::AbstractPowerManifold)

Create a point on the AbstractPowerManifold M, where every entry is set to the point p.

Note

while usually the manifold is a first argument in all functions in ManifoldsBase.jl, we follow the signature of fill, where the power manifold serves as the size information.

source
Base.view — Method
view(p, M::PowerManifoldNested, i::Union{Integer,Colon,AbstractVector}...)

Get the view of the element(s) at index [i...] of a point p on an AbstractPowerManifold M by linear or multidimensional indexing.

source
ManifoldsBase.check_power_size — Method
check_power_size(M, p)
check_power_size(M, p, X)

Check whether p has the right size to represent points on M generically, i.e. just checking the overall sizes, not the individual ones per manifold.

source
ManifoldsBase.distance — Function
distance(M::AbstractPowerManifold, p, q, r::Real=2)
distance(M::AbstractPowerManifold, p, q, m::AbstractInverseRetractionMethod=LogarithmicInverseRetraction(), r::Real=2)

Compute the distance between q and p on an AbstractPowerManifold.

First, the componentwise distances are computed using the Riemannian distance function on M.manifold. These can be approximated using the norm of an AbstractInverseRetractionMethod m. This yields an array of distance values.

Second, we compute the r-norm on this array of distances. This is also the only place where the r is used.

source
ManifoldsBase.distance — Method
distance(M::AbstractPowerManifold, p, q, r::Real=2)
distance(M::AbstractPowerManifold, p, q, m::AbstractInverseRetractionMethod=LogarithmicInverseRetraction(), r::Real=2)

Compute the distance between q and p on an AbstractPowerManifold.

First, the componentwise distances are computed using the Riemannian distance function on M.manifold. These can be approximated using the norm of an AbstractInverseRetractionMethod m. This yields an array of distance values.

Second, we compute the r-norm on this array of distances. This is also the only place where the r is used.

source
ManifoldsBase.inner — Method
inner(M::AbstractPowerManifold, p, X, Y)

Compute the inner product of X and Y from the tangent space at p on an AbstractPowerManifold M. For each arrays entry the tangent vector entries from X and Y are in the tangent space of the corresponding element from p. The inner product is then the sum of the elementwise inner products.

source
ManifoldsBase.manifold_dimension — Method
manifold_dimension(M::PowerManifold)

Returns the manifold-dimension of a PowerManifold M $=\mathcal N = (\mathcal M)^{n_1,…,n_d}$, i.e. with $n=(n_1,…,n_d)$ the array size of the power manifold and $d_{\mathcal M}$ the dimension of the base manifold $\mathcal M$, the manifold is of dimension

\[\dim(\mathcal N) = \dim(\mathcal M)\prod_{i=1}^d n_i = n_1n_2⋅…⋅ n_d \dim(\mathcal M).\]

source
ManifoldsBase.sectional_curvature — Method
sectional_curvature(M::AbstractPowerManifold, p, X, Y; atol::Real=abs(eps(number_eltype(X))))

Compute the sectional curvature of a power manifold $\mathcal M$ at a point $p \in \mathcal M$ on two linearly independent tangent vectors at $p$. It may be 0 for a power of a non-flat manifold if projections of X and Y on subspaces corresponding to component manifolds are not linearly independent. For linearly dependent X and Y it returns 0.

atol is the absolute tolerance for checking linear independence of X and Y.

source

Product Manifold

ManifoldsBase.ProductManifold — Type
ProductManifold{𝔽,TM<:Tuple} <: AbstractDecoratorManifold{𝔽}

Product manifold $M_1 × M_2 × … × M_n$ with product geometry.

Constructor

ProductManifold(M_1, M_2, ..., M_n)

generates the product manifold $M_1 × M_2 × … × M_n$. Alternatively, the same manifold can be constructed using the × operator: M_1 × M_2 × M_3.

source
LinearAlgebra.cross — Method
×(M, N)
cross(M, N)
cross(M1, M2, M3,...)

Return the ProductManifold For two AbstractManifolds M and N, where for the case that one of them is a ProductManifold itself, the other is either prepended (if N is a product) or appended (if M) is. If both are product manifold, they are combined into one product manifold, keeping the order.

For the case that more than one is a product manifold of these is build with the same approach as above

source
ManifoldsBase.check_vector — Method
check_vector(M::ProductManifold, p, X; kwargs... )

Check whether X is a tangent vector to p on the ProductManifold M, i.e. all projections to base manifolds must be respective tangent vectors. If X is not a tangent vector to p on M a CompositeManifoldError.consisting of all error messages of the components, for which the tests fail is returned.

The tolerance for the last test can be set using the kwargs....

source
ManifoldsBase.sectional_curvature — Method
sectional_curvature(M::ProductManifold, p, X, Y; atol::Real = sqrt(eps(number_eltype(X))))

Compute the sectional curvature of a manifold $\mathcal M$ at a point $p \in \mathcal M$ on two linearly independent tangent vectors at $p$. It may be 0 for a product of non-flat manifolds if projections of X and Y on subspaces corresponding to component manifolds are not linearly independent. For linearly dependent X and Y it returns 0.

atol is the absolute tolerance for the test of linear independence of X and Y.

source
ManifoldsBase.sectional_curvature_max — Method
sectional_curvature_max(M::ProductManifold)

Upper bound on sectional curvature of ProductManifold M. It is the maximum of sectional curvatures of component manifolds and 0 in case there are two or more component manifolds, as the sectional curvature corresponding to the plane spanned by vectors (X_1, 0) and (0, X_2) is 0.

source
ManifoldsBase.sectional_curvature_min — Method
sectional_curvature_min(M::ProductManifold)

Lower bound on sectional curvature of ProductManifold M. It is the minimum of sectional curvatures of component manifolds and 0 in case there are two or more component manifolds, as the sectional curvature corresponding to the plane spanned by vectors (X_1, 0) and (0, X_2) is 0.

source
ManifoldsBase.select_from_tuple — Method
select_from_tuple(t::NTuple{N, Any}, positions::Val{P})

Selects elements of tuple t at positions specified by the second argument. For example select_from_tuple(("a", "b", "c"), Val((3, 1, 1))) returns ("c", "a", "a").

source
ManifoldsBase.submanifold — Method
submanifold(M::ProductManifold, i::Val)
submanifold(M::ProductManifold, i::AbstractVector)

Extract the factor of the product manifold M indicated by indices in i. For example, for i equal to Val((1, 3)) the product manifold constructed from the first and the third factor is returned.

The version with AbstractVector is not type-stable, for better performance use Val.

source
ManifoldsBase.ziptuples — Method
ziptuples(a, b[, c[, d[, e]]])

Zips tuples a, b, and remaining in a fast, type-stable way. If they have different lengths, the result is trimmed to the length of the shorter tuple.

source

Quotient manifolds

A manifold $\mathcal M$ is then a quotient manifold of another manifold $\mathcal N$, i.e. for an equivalence relation $∼$ on $\mathcal N$ we have

\[ \mathcal M = \mathcal N / ∼ = \bigl\{ [p] : p ∈ \mathcal N \bigr\},\]

where $[p] ≔ \{ q ∈ \mathcal N : q ∼ p\}$ denotes the equivalence class containing $p$. For more details see Subsection 3.4.1 [AMS08].

This manifold type models an explicit quotient structure. This should be done if either the default implementation of $\mathcal M$ uses another representation different from the quotient structure or if it provides a (default) quotient structure that is different from the one introduced here.

ManifoldsBase.canonical_project! — Method
canonical_project(M::AbstractManifold, p)
canonical_project!(M::AbstractManifold, q, p)

Compute the canonical projection $π$ on a quotient manifold $\mathcal M$. The canonical (or natural) projection $π$ from the total space $\mathcal N$ onto $\mathcal M$ given by

\[ π = π_{\mathcal N, \mathcal M} : \mathcal N → \mathcal M, p ↦ π_{\mathcal N, \mathcal M}(p) = [p].\]

in other words, this function implicitly assumes, that the total space $\mathcal N$ is given.

source
ManifoldsBase.canonical_project — Method
canonical_project(M::AbstractManifold, p)
canonical_project!(M::AbstractManifold, q, p)

Compute the canonical projection $π$ on a quotient manifold $\mathcal M$. The canonical (or natural) projection $π$ from the total space $\mathcal N$ onto $\mathcal M$ given by

\[ π = π_{\mathcal N, \mathcal M} : \mathcal N → \mathcal M, p ↦ π_{\mathcal N, \mathcal M}(p) = [p].\]

in other words, this function implicitly assumes, that the total space $\mathcal N$ is given.

source
ManifoldsBase.horizontal_lift! — Method
horizontal_lift(N::AbstractManifold, q, X)
horizontal_lift!(N::AbstractManifold, Y, q, X)

Compute a tangent vector Y in the horizontal space at q of the total space N.

Given a point q in total space of the quotient manifold N such that $p=π(q)$ is a point on a quotient manifold M (implicitly given for the first case) and a tangent vector X this method computes a tangent vector Y on the horizontal space of $T_q\mathcal N$, i.e. the subspace that is orthogonal to the kernel of $Dπ(q)$.

source
ManifoldsBase.horizontal_lift — Method
horizontal_lift(N::AbstractManifold, q, X)
horizontal_lift!(N::AbstractManifold, Y, q, X)

Compute a tangent vector Y in the horizontal space at q of the total space N.

Given a point q in total space of the quotient manifold N such that $p=π(q)$ is a point on a quotient manifold M (implicitly given for the first case) and a tangent vector X this method computes a tangent vector Y on the horizontal space of $T_q\mathcal N$, i.e. the subspace that is orthogonal to the kernel of $Dπ(q)$.

source

Fiber

ManifoldsBase.Fiber — Type
Fiber{𝔽,TFiber<:FiberType,TM<:AbstractManifold,TX} <: AbstractManifold{𝔽}

A fiber of a fiber bundle at a point p on the manifold.

This fiber itself is also a manifold. For vector fibers it's by default flat and hence isometric to the Euclidean manifold.

Fields

  • manifold – base space of the fiber bundle
  • point – a point $p$ from the base space; the fiber corresponds to the preimage by bundle projection $\pi^{-1}(\{p\})$.
  • fiber_type – the FiberType of the fiber

Constructor

Fiber(M::AbstractManifold, p, fiber_type::FiberType; field::AbstractNumbers = ℝ)

A fiber of type fiber_type at point p from the manifold M. The number system field of the fiber defaults to ℝ.

source

Tangent Space

Base.exp — Method
exp(TpM::TangentSpace, X, V)

Exponential map of tangent vectors X from TpM and a direction V, which is also from the TangentSpace TpM since we identify the tangent space of TpM with TpM. The exponential map then simplifies to the sum X+V.

source
ManifoldsBase.inner — Method
inner(M::TangentSpace, X, V, W)

For any $X ∈ T_p\mathcal M$ we identify the tangent space $T_X(T_p\mathcal M)$ with $T_p\mathcal M$ again. Hence an inner product of $V,W$ is just the inner product of the tangent space itself. $⟨V,W⟩_X = ⟨V,W⟩_p$.

source
ManifoldsBase.parallel_transport_to — Method
parallel_transport_to(::TangentSpace, X, V, Y)

Transport the tangent vector $Z ∈ T_X(T_p\mathcal M)$ from X to Y. Since we identify $T_X(T_p\mathcal M) = T_p\mathcal M$ and the tangent space is a vector space, parallel transport simplifies to the identity, so this function yields $V$ as a result.

source
ManifoldsBase.project — Method
project(TpM::TangentSpace, X, V)

Project the vector V from the embedding of the tangent space TpM (identified with $T_X(T_p\mathcal M)$), that is project the vector V onto the tangent space at TpM.point.

source