# Metric manifold

A Riemannian manifold always consists of a topological manifold together with a smoothly varying metric $g$.

However, often there is an implicitly assumed (default) metric, like the usual inner product on `Euclidean`

space. This decorator takes this into account. It is not necessary to use this decorator if you implement just one (or the first) metric. If you later introduce a second, the old (first) metric can be used with the (non `MetricManifold`

) `AbstractManifold`

, i.e. without an explicitly stated metric.

This manifold decorator serves two purposes:

- to implement different metrics (e.g. in closed form) for one
`AbstractManifold`

- to provide a way to compute geodesics on manifolds, where this
`AbstractMetric`

does not yield closed formula.

Note that a metric manifold is has a `IsConnectionManifold`

trait referring to the `LeviCivitaConnection`

of the metric $g$, and thus a large part of metric manifold's functionality relies on this.

Let's first look at the provided types.

## Types

`Manifolds.AbstractMetric`

— Type`AbstractMetric`

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

.

**Functor**

```
(metric::Metric)(M::AbstractManifold)
(metric::Metric)(M::MetricManifold)
```

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.

`Manifolds.IsDefaultMetric`

— Type`IsDefaultMetric{G<:AbstractMetric}`

Specify that a certain `AbstractMetric`

is the default metric for a manifold. This way the corresponding `MetricManifold`

falls back to the default methods of the manifold it decorates.

`Manifolds.IsMetricManifold`

— Type`IsMetricManifold <: AbstractTrait`

Specify that a certain decorated Manifold is a metric manifold in the sence that it provides explicit metric properties, extending/changing the default metric properties of a manifold.

`Manifolds.MetricManifold`

— Type`MetricManifold{𝔽,M<:AbstractManifold{𝔽},G<:AbstractMetric} <: AbstractDecoratorManifold{𝔽}`

Equip a `AbstractManifold`

explicitly with a `AbstractMetric`

`G`

.

For a Metric AbstractManifold, by default, assumes, that you implement the linear form from `local_metric`

in order to evaluate the exponential map.

If the corresponding `AbstractMetric`

`G`

yields closed form formulae for e.g. the exponential map and this is implemented directly (without solving the ode), you can of course still implement that directly.

**Constructor**

`MetricManifold(M, G)`

Generate the `AbstractManifold`

`M`

as a manifold with the `AbstractMetric`

`G`

.

`Manifolds.RiemannianMetric`

— Type`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.

## Implement Different Metrics on the same Manifold

In order to distinguish different metrics on one manifold, one can introduce two `AbstractMetric`

s and use this type to dispatch on the metric, see `SymmetricPositiveDefinite`

. To avoid overhead, one `AbstractMetric`

can then be marked as being the default, i.e. the one that is used, when no `MetricManifold`

decorator is present. This avoids reimplementation of the first existing metric, access to the metric-dependent functions that were implemented using the undecorated manifold, as well as the transparent fallback of the corresponding `MetricManifold`

with default metric to the undecorated implementations. This does not cause any runtime overhead. Introducing a default `AbstractMetric`

serves a better readability of the code when working with different metrics.

## Implementation of Metrics

For the case that a `local_metric`

is implemented as a bilinear form that is positive definite, the following further functions are provided, unless the corresponding `AbstractMetric`

is marked as default – then the fallbacks mentioned in the last section are used for e.g. the exponential map.

`Base.log`

— Method`log(N::MetricManifold{M,G}, p, q)`

Copute the logarithmic map on the `AbstractManifold`

`M`

equipped with the `AbstractMetric`

`G`

.

If the metric was declared the default metric using the `IsDefaultMetric`

trait or `is_default_metric`

, this method falls back to `log(M,p,q)`

. Otherwise, you have to provide an implementation for the non-default `AbstractMetric`

`G`

metric within its `MetricManifold`

`{M,G}`

.

`Manifolds.change_metric`

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

If both metrics are given in their `local_metric`

(symmetric positive defintie) matrix representations $G_1 = C_1C_1^{\mathrm{H}}$ and $G_2 = C_2C_2^{\mathrm{H}}$, where $C_1,C_2$ denote their respective Cholesky factors, then solving $C_2C_2^{\mathrm{H}} = G_2 = B^{\mathrm{H}}G_1B = B^{\mathrm{H}}C_1C_1^{\mathrm{H}}B$ yields $B = (C_1 \backslash C_2)^{\mathrm{H}}$, where $\cdot^{\mathrm{H}}$ denotes the conjugate transpose.

This function returns `Z = BX`

.

**Examples**

`change_metric(Sphere(2), EuclideanMetric(), p, X)`

Since the metric in $T_p\mathbb S^2$ is the Euclidean metric from the embedding restricted to $T_p\mathbb S^2$, this just returns `X`

`change_metric(SymmetricPOsitiveDefinite(3), EuclideanMetric, p, X)`

Here, the default metric in $\mathcal P(3)$ is the `LinearAffineMetric`

and the transformation can be computed as $B=p$

`Manifolds.change_representer`

— Method`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)\]

If both metrics are given in their `local_metric`

(symmetric positive defintie) matrix representations $G_1$ and $G_2$ and $x,y$ are the local coordinates with respect to the same basis of the tangent space, the equation reads

\[ x^{\mathrm{H}}G_2y = c(x)^{\mathrm{H}}G_1 y \quad \text{for all } y \in ℝ^d,\]

where $\cdot^{\mathrm{H}}$ denotes the conjugate transpose. We obtain $c(X) = (G_1\backslash G_2)^{\mathrm{H}}X$

For example `X`

could be the gradient $\operatorname{grad}f$ of a real-valued function $f: \mathcal M \to ℝ$, i.e.

\[ g_2(X,Y) = Df(p)[Y] \quad \text{for all } Y ∈ T_p\mathcal M.\]

and we would change the Riesz representer `X`

to the representer with respect to the metric $g_1$.

**Examples**

`change_representer(Sphere(2), EuclideanMetric(), p, X)`

Since the metric in $T_p\mathbb S^2$ is the Euclidean metric from the embedding restricted to $T_p\mathbb S^2$, this just returns `X`

`change_representer(SymmetricPositiveDefinite(3), EuclideanMetric(), p, X)`

Here, the default metric in $\mathcal P(3)$ is the `LinearAffineMetric`

and the transformation can be computed as $pXp$

`Manifolds.connection`

— Method`connection(::MetricManifold)`

Return the `LeviCivitaConnection`

for a metric manifold.

`Manifolds.det_local_metric`

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

Return the determinant of local matrix representation of the metric tensor $g$, i.e. of the matrix $G(p)$ representing the metric in the tangent space at $p$ with as a matrix.

See also `local_metric`

`Manifolds.einstein_tensor`

— Method`einstein_tensor(M::AbstractManifold, p, B::AbstractBasis; backend::AbstractDiffBackend = diff_badefault_differential_backendckend())`

Compute the Einstein tensor of the manifold `M`

at the point `p`

, see https://en.wikipedia.org/wiki/Einstein_tensor

`Manifolds.flat`

— Method`flat(N::MetricManifold{M,G}, p, X::TFVector)`

Compute the musical isomorphism to transform the tangent vector `X`

from the `AbstractManifold`

`M`

equipped with `AbstractMetric`

`G`

to a cotangent by computing

\[X^♭= G_p X,\]

where $G_p$ is the local matrix representation of `G`

, see `local_metric`

`Manifolds.inverse_local_metric`

— Method`inverse_local_metric(M::AbstractcManifold{𝔽}, p, B::AbstractBasis)`

Return the local matrix representation of the inverse metric (cometric) tensor of the tangent space at `p`

on the `AbstractManifold`

`M`

with respect to the `AbstractBasis`

basis `B`

.

The metric tensor (see `local_metric`

) is usually denoted by $G = (g_{ij}) ∈ 𝔽^{d×d}$, where $d$ is the dimension of the manifold.

Then the inverse local metric is denoted by $G^{-1} = g^{ij}$.

`Manifolds.is_default_metric`

— Method`is_default_metric(M::AbstractManifold, G::AbstractMetric)`

returns whether an `AbstractMetric`

is the default metric on the manifold `M`

or not. This can be set by defining this function, or setting the `IsDefaultMetric`

trait for an `AbstractDecoratorManifold`

.

`Manifolds.local_metric`

— Method`local_metric(M::AbstractManifold{𝔽}, p, B::AbstractBasis)`

Return the local matrix representation at the point `p`

of the metric tensor $g$ with respect to the `AbstractBasis`

`B`

on the `AbstractManifold`

`M`

. Let $d$denote the dimension of the manifold and $b_1,\ldots,b_d$ the basis vectors. Then the local matrix representation is a matrix $G\in 𝔽^{n\times n}$ whose entries are given by $g_{ij} = g_p(b_i,b_j), i,j\in\{1,…,d\}$.

This yields the property for two tangent vectors (using Einstein summation convention) $X = X^ib_i, Y=Y^ib_i \in T_p\mathcal M$ we get $g_p(X, Y) = g_{ij} X^i Y^j$.

`Manifolds.local_metric_jacobian`

— Method```
local_metric_jacobian(
M::AbstractManifold,
p,
B::AbstractBasis;
backend::AbstractDiffBackend,
)
```

Get partial derivatives of the local metric of `M`

at `p`

in basis `B`

with respect to the coordinates of `p`

, $\frac{∂}{∂ p^k} g_{ij} = g_{ij,k}$. The dimensions of the resulting multi-dimensional array are ordered $(i,j,k)$.

`Manifolds.log_local_metric_density`

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

Return the natural logarithm of the metric density $ρ$ of `M`

at `p`

, which is given by $ρ = \log \sqrt{|\det [g_{ij}]|}$ for the metric tensor expressed in basis `B`

.

`Manifolds.metric`

— Method`metric(M::MetricManifold)`

Get the metric $g$ of the manifold `M`

.

`Manifolds.ricci_curvature`

— Method`ricci_curvature(M::AbstractManifold, p, B::AbstractBasis; backend::AbstractDiffBackend = default_differential_backend())`

Compute the Ricci scalar curvature of the manifold `M`

at the point `p`

using basis `B`

. The curvature is computed as the trace of the Ricci curvature tensor with respect to the metric, that is $R=g^{ij}R_{ij}$ where $R$ is the scalar Ricci curvature at `p`

, $g^{ij}$ is the inverse local metric (see `inverse_local_metric`

) at `p`

and $R_{ij}$ is the Riccie curvature tensor, see `ricci_tensor`

. Both the tensor and inverse local metric are expressed in local coordinates defined by `B`

, and the formula uses the Einstein summation convention.

`Manifolds.sharp`

— Method`sharp(N::MetricManifold{M,G}, p, ξ::CoTFVector)`

Compute the musical isomorphism to transform the cotangent vector `ξ`

from the `AbstractManifold`

`M`

equipped with `AbstractMetric`

`G`

to a tangent by computing

\[ξ^♯ = G_p^{-1} ξ,\]

where $G_p$ is the local matrix representation of `G`

, i.e. one employs `inverse_local_metric`

here to obtain $G_p^{-1}$.

`ManifoldsBase.inner`

— Method`inner(N::MetricManifold{M,G}, p, X, Y)`

Compute the inner product of `X`

and `Y`

from the tangent space at `p`

on the `AbstractManifold`

`M`

using the `AbstractMetric`

`G`

. If `M`

has `G`

as its `IsDefaultMetric`

trait, this is done using `inner(M, p, X, Y)`

, otherwise the `local_metric`

`(M, p)`

is employed as

\[g_p(X, Y) = ⟨X, G_p Y⟩,\]

where $G_p$ is the loal matrix representation of the `AbstractMetric`

`G`

.

## Metrics, charts and bases of vector spaces

Metric-related functions, similarly to connection-related functions, need to operate in a basis of a vector space, see here.

Metric-related functions can take bases of associated tangent spaces as arguments. For example `local_metric`

can take the basis of the tangent space it is supposed to operate on instead of a custom basis of the space of symmetric bilinear operators.