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

.

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