Skip to content

Commit

Permalink
Symplectic Grassmann (#700)
Browse files Browse the repository at this point in the history
* Start documentation of the symplectic Grassmann.
* Finish manifold doc string by adding the tangent spaces.
* A bit of work on the symplectic inverse.
* Adapt a few docs and default shows, implement symplectic Grassmann checkls.
* Further work on Symplectic Grasmann
* Unify notation to use UTF8 where possible and use J for the symplectic element instead of Q and/or J.
* implement `rand!` for Hamiltonians. Deprecate  `rand_hamiltonian`.
* Implement exp and the Caley retraction in the quivalence class representation on symplectic Grassmann.
* Apply suggestions from code review
* Replace \to with → in LaTeX formulae.
* Fiinalise PR by fixing rand on Hamiltonian and update the docs for SpGr.
* bump version.

---------

Co-authored-by: Mateusz Baran <mateuszbaran89@gmail.com>
  • Loading branch information
kellertuer and mateuszbaran committed Jan 25, 2024
1 parent 64ae41a commit 95e90c8
Show file tree
Hide file tree
Showing 166 changed files with 2,848 additions and 2,073 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/documenter.yml
Expand Up @@ -9,7 +9,7 @@ jobs:
docs:
name: Documentation
runs-on: ubuntu-latest
if: "contains( github.event.pull_request.labels.*.name, 'preview docs') || github.ref == 'refs/heads/master' || contains(github.ref, 'refs/tags/')"
if: contains( github.event.pull_request.labels.*.name, 'preview docs') || github.ref == 'refs/heads/master' || contains(github.ref, 'refs/tags/')
steps:
- uses: actions/checkout@v4
- uses: quarto-dev/quarto-actions/setup@v2
Expand Down
17 changes: 16 additions & 1 deletion NEWS.md
Expand Up @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.9.13] – 2024-01-24

### Added

* added the real symplectic Grassmann manifold `SymplecticGrassmann`
* Introduce the manifold of `HamiltonianMatrices` and a wrapper for `Hamiltonian` matrices
* introduce `rand(:HamiltonianMatrices)`
* extend `rand` to also `rand!` for `HamiltonianMatrices`, `SymplecticMatrices` and `SymplecticStiefel`
* implement `riemannian_gradient` conversion for `SymplecticMatrices` and `SymplecticGrassmann`

### Deprecated

* Rename `Symplectic` to `SimplecticMatrices` in order to have a `Symplectic` wrapper for such matrices as well in the future for the next breaking change.
* Rename `SymplecticMatrix` to `SymplecticElement` to clarify that it is the special matrix ``J_{2n}`` and not an arbitrary symplectic matrix.

## [0.9.12] – 2024-01-21

### Fixed
Expand Down Expand Up @@ -43,7 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* Improved distribution of random vector generation for rotation matrices and complex circle.

## [0.9.7] - 2023-11-14
## [0.9.7] 2023-11-14

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion Project.toml
@@ -1,7 +1,7 @@
name = "Manifolds"
uuid = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e"
authors = ["Seth Axen <seth.axen@gmail.com>", "Mateusz Baran <mateuszbaran89@gmail.com>", "Ronny Bergmann <manopt@ronnybergmann.net>", "Antoine Levitt <antoine.levitt@gmail.com>"]
version = "0.9.12"
version = "0.9.13"

[deps]
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Expand Down
4 changes: 3 additions & 1 deletion docs/make.jl
Expand Up @@ -113,6 +113,7 @@ makedocs(;
"Generalized Stiefel" => "manifolds/generalizedstiefel.md",
"Generalized Grassmann" => "manifolds/generalizedgrassmann.md",
"Grassmann" => "manifolds/grassmann.md",
"Hamiltonian" => "manifolds/hamiltonian.md",
"Hyperbolic space" => "manifolds/hyperbolic.md",
"Lorentzian manifold" => "manifolds/lorentz.md",
"Multinomial doubly stochastic matrices" => "manifolds/multinomialdoublystochastic.md",
Expand All @@ -133,7 +134,8 @@ makedocs(;
"Symmetric positive definite" => "manifolds/symmetricpositivedefinite.md",
"SPD, fixed determinant" => "manifolds/spdfixeddeterminant.md",
"Symmetric positive semidefinite fixed rank" => "manifolds/symmetricpsdfixedrank.md",
"Symplectic" => "manifolds/symplectic.md",
"Symplectic Grassmann" => "manifolds/symplecticgrassmann.md",
"Symplectic matrices" => "manifolds/symplectic.md",
"Symplectic Stiefel" => "manifolds/symplecticstiefel.md",
"Torus" => "manifolds/torus.md",
"Tucker" => "manifolds/tucker.md",
Expand Down
8 changes: 4 additions & 4 deletions docs/src/features/atlases.md
@@ -1,6 +1,6 @@
# [Atlases and charts](@id atlases_and_charts)

Atlases on an ``n``-dimensional manifold $\mathcal M$ are collections of charts ``\mathcal A = \{(U_i, φ_i) \colon i \in I\}``, where ``I`` is a (finite or infinte) index family, such that ``U_i \subseteq \mathcal M`` is an open set and each chart ``φ_i: U_i \to \mathbb{R}^n`` is a homeomorphism. This means, that ``φ_i`` is bijective – sometimes also called one-to-one and onto - and continuous, and its inverse ``φ_i^{-1}`` is continuous as well.
Atlases on an ``n``-dimensional manifold ``mathcal M``are collections of charts ``\mathcal A = \{(U_i, φ_i) \colon i \in I\}``, where ``I`` is a (finite or infinte) index family, such that ``U_i \subseteq \mathcal M`` is an open set and each chart ``φ_i: U_i → ℝ^n`` is a homeomorphism. This means, that ``φ_i`` is bijective – sometimes also called one-to-one and onto - and continuous, and its inverse ``φ_i^{-1}`` is continuous as well.
The inverse ``φ_i^{-1}`` is called (local) parametrization.
The resulting _parameters_ ``a=φ(p)`` of ``p`` (with respect to the chart ``φ``) are in the literature also called “(local) coordinates”. To distinguish the parameter ``a`` from [`get_coordinates`](@ref) in a basis, we use the terminology parameter in this package.

Expand All @@ -11,9 +11,9 @@ For an atlas ``\mathcal A`` we further require that
```

We say that ``φ_i`` is a chart about ``p``, if ``p\in U_i``.
An atlas provides a connection between a manifold and the Euclidean space ``\mathbb{R}^n``, since
An atlas provides a connection between a manifold and the Euclidean space ``^n``, since
locally, a chart about ``p`` can be used to identify its neighborhood (as long as you stay in ``U_i``) with a subset of a Euclidean space.
Most manifolds we consider are smooth, i.e. any change of charts ``φ_i \circ φ_j^{-1}: \mathbb{R}^n\to\mathbb{R}^n``, where ``i,j\in I``, is a smooth function. These changes of charts are also called transition maps.
Most manifolds we consider are smooth, i.e. any change of charts ``φ_i \circ φ_j^{-1}: ℝ^n → ℝ^n``, where ``i,j\in I``, is a smooth function. These changes of charts are also called transition maps.

Most operations on manifolds in `Manifolds.jl` avoid operating in a chart through appropriate embeddings and formulas derived for particular manifolds, though atlases provide the most general way of working with manifolds.
Compared to these approaches, using an atlas is often more technical and time-consuming.
Expand All @@ -28,7 +28,7 @@ Operations using atlases and charts are available through the following function
* [`get_parameters`](@ref Main.Manifolds.get_parameters) converts a point to its parameters with respect to the chart in a chart.
* [`get_point`](@ref Main.Manifolds.get_point) converts parameters (local coordinates) in a chart to the point that corresponds to them.
* [`induced_basis`](@ref Main.Manifolds.induced_basis) returns a basis of a given vector space at a point induced by a chart ``φ``.
* [`transition_map`](@ref Main.Manifolds.transition_map) converts coordinates of a point between two charts, e.g. computes ``φ_i\circ φ_j^{-1}: \mathbb{R}^n\to\mathbb{R}^n``, ``i,j\in I``.
* [`transition_map`](@ref Main.Manifolds.transition_map) converts coordinates of a point between two charts, e.g. computes ``φ_i\circ φ_j^{-1}: ℝ^n → ℝ^n``, ``i,j\in I``.

While an atlas could store charts as explicit functions, it is favourable, that the [`get_parameters`] actually implements a chart ``φ``, [`get_point`](@ref) its inverse, the prametrization ``φ^{-1}``.

Expand Down
2 changes: 1 addition & 1 deletion docs/src/features/utilities.md
Expand Up @@ -2,7 +2,7 @@

## Ease of notation

The following terms introduce a nicer notation for some operations, for example using the ∈ operator, $p ∈ \mathcal M$, to determine whether $p$ is a point on the [`AbstractManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/types.html#ManifoldsBase.AbstractManifold) $\mathcal M$.
The following terms introduce a nicer notation for some operations, for example using the ∈ operator, ``p ∈ \mathcal M`` to determine whether ``p`` is a point on the [`AbstractManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/types.html#ManifoldsBase.AbstractManifold) ``\mathcal M``.

````@docs
in
Expand Down
2 changes: 1 addition & 1 deletion docs/src/manifolds/connection.md
@@ -1,6 +1,6 @@
# [Connection manifold](@id ConnectionSection)

A connection manifold always consists of a [topological manifold](https://en.wikipedia.org/wiki/Topological_manifold) together with a [connection](https://en.wikipedia.org/wiki/Connection_(mathematics)) $\Gamma$.
A connection manifold always consists of a [topological manifold](https://en.wikipedia.org/wiki/Topological_manifold) together with a [connection](https://en.wikipedia.org/wiki/Connection_(mathematics)) ``Γ``.

However, often there is an implicitly assumed (default) connection, like the [`LeviCivitaConnection`](@ref) connection on a Riemannian manifold.
It is not necessary to use this decorator if you implement just one (or the first) connection.
Expand Down
2 changes: 1 addition & 1 deletion docs/src/manifolds/essentialmanifold.md
@@ -1,5 +1,5 @@
# Essential Manifold
The essential manifold is modeled as an [`AbstractPowerManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.AbstractPowerManifold) of the $3\times3$ [`Rotations`](@ref) and uses [`NestedPowerRepresentation`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.NestedPowerRepresentation).
The essential manifold is modeled as an [`AbstractPowerManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.AbstractPowerManifold) of the ``3×3`` [`Rotations`](@ref) and uses [`NestedPowerRepresentation`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.NestedPowerRepresentation).

```@autodocs
Modules = [Manifolds]
Expand Down
4 changes: 2 additions & 2 deletions docs/src/manifolds/euclidean.md
@@ -1,7 +1,7 @@
# [Euclidean space](@id EuclideanSection)

The Euclidean space $ℝ^n$ is a simple model space, since it has curvature constantly zero everywhere; hence, nearly all operations simplify.
The easiest way to generate an Euclidean space is to use a field, i.e. [`AbstractNumbers`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/types.html#number-system), e.g. to create the $ℝ^n$ or $ℝ^{n\times n}$ you can simply type `M = ℝ^n` or `ℝ^(n,n)`, respectively.
The Euclidean space ``ℝ^n`` is a simple model space, since it has curvature constantly zero everywhere; hence, nearly all operations simplify.
The easiest way to generate an Euclidean space is to use a field, i.e. [`AbstractNumbers`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/types.html#number-system), e.g. to create the ``ℝ^n`` or ``ℝ^{n×n}`` you can simply type `M = ℝ^n` or `ℝ^(n,n)`, respectively.

```@autodocs
Modules = [Manifolds]
Expand Down
6 changes: 3 additions & 3 deletions docs/src/manifolds/fiber_bundle.md
@@ -1,10 +1,10 @@
# [Fiber bundles](@id FiberBundleSection)

Fiber bundle $E$ is a manifold that is built on top of another manifold $\mathcal M$ (base space).
It is characterized by a continuous function $Π : E → \mathcal M$. For each point $p ∈ \mathcal M$ the preimage of $p$ by $Π$, $Π^{-1}(\{p\})$ is called a fiber $F$.
Fiber bundle ``E`` is a manifold that is built on top of another manifold ``\mathcal M`` (base space).
It is characterized by a continuous function ``Π : E → \mathcal M``. For each point ``p ∈ \mathcal M`` the preimage of ``p`` by ``Π``, ``Π^{-1}(\{p\})`` is called a fiber ``F``.
Bundle projection can be performed using function [`bundle_projection`](@ref).

`Manifolds.jl` primarily deals with the case of trivial bundles, where $E$ can be identified with a product $M \times F$.
`Manifolds.jl` primarily deals with the case of trivial bundles, where ``E`` can be topologically identified with a product ``M×F``.

[Vector bundles](@ref VectorBundleSection) is a special case of a fiber bundle. Other examples include unit tangent bundle. Note that in general fiber bundles don't have a canonical Riemannian structure but can at least be equipped with an [Ehresmann connection](https://en.wikipedia.org/wiki/Ehresmann_connection), providing notions of parallel transport and curvature.

Expand Down
6 changes: 3 additions & 3 deletions docs/src/manifolds/graph.md
@@ -1,11 +1,11 @@
# Graph manifold

For a given graph $G(V,E)$ implemented using [`Graphs.jl`](https://juliagraphs.github.io/Graphs.jl/latest/), the [`GraphManifold`](@ref) models a [`PowerManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.PowerManifold) either on the nodes or edges of the graph, depending on the [`GraphManifoldType`](@ref).
i.e., it's either a $\mathcal M^{\lvert V \rvert}$ for the case of a vertex manifold or a $\mathcal M^{\lvert E \rvert}$ for the case of a edge manifold.
For a given graph ``G(V,E)`` implemented using [`Graphs.jl`](https://juliagraphs.github.io/Graphs.jl/latest/), the [`GraphManifold`](@ref) models a [`PowerManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.PowerManifold) either on the nodes or edges of the graph, depending on the [`GraphManifoldType`](@ref).
i.e., it's either a ``\mathcal M^{\lvert V \rvert}`` for the case of a vertex manifold or a ``\mathcal M^{\lvert E \rvert}`` for the case of a edge manifold.

## Example

To make a graph manifold over $ℝ^2$ with three vertices and two edges, one can use
To make a graph manifold over ``ℝ^2`` with three vertices and two edges, one can use

```@example
using Manifolds
Expand Down
2 changes: 1 addition & 1 deletion docs/src/manifolds/grassmann.md
Expand Up @@ -10,7 +10,7 @@ Order = [:type,:function]

```@autodocs
Modules = [Manifolds]
Pages = ["GrassmannStiefel.jl"]
Pages = ["manifolds/GrassmannStiefel.jl"]
Order = [:type,:function]
```

Expand Down
7 changes: 7 additions & 0 deletions docs/src/manifolds/hamiltonian.md
@@ -0,0 +1,7 @@
# Hamiltonian matrices

```@autodocs
Modules = [Manifolds]
Pages = ["manifolds/Hamiltonian.jl"]
Order = [:type, :function]
```
4 changes: 2 additions & 2 deletions docs/src/manifolds/metric.md
@@ -1,6 +1,6 @@
# Metric manifold

A Riemannian manifold always consists of a [topological manifold](https://en.wikipedia.org/wiki/Topological_manifold) together with a smoothly varying metric $g$.
A Riemannian manifold always consists of a [topological manifold](https://en.wikipedia.org/wiki/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`](@ref) space.
This decorator takes this into account.
Expand All @@ -17,7 +17,7 @@ Pages = ["metric.md"]
Depth = 2
```

Note that a metric manifold is has a [`IsConnectionManifold`](@ref) trait referring to the [`LeviCivitaConnection`](@ref) of the metric $g$, and thus a large part of metric manifold's functionality relies on this.
Note that a metric manifold is has a [`IsConnectionManifold`](@ref) trait referring to the [`LeviCivitaConnection`](@ref) 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.

Expand Down
4 changes: 2 additions & 2 deletions docs/src/manifolds/oblique.md
@@ -1,7 +1,7 @@
# Oblique manifold

The oblique manifold $\mathcal{OB}(n,m)$ is modeled as an [`AbstractPowerManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.AbstractPowerManifold) of the (real-valued) [`Sphere`](@ref) and uses [`ArrayPowerRepresentation`](@ref).
Points on the torus are hence matrices, $x ∈ ℝ^{n,m}$.
The oblique manifold ``\mathcal{OB}(n,m)`` is modeled as an [`AbstractPowerManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.AbstractPowerManifold) of the (real-valued) [`Sphere`](@ref) and uses [`ArrayPowerRepresentation`](@ref).
Points on the torus are hence matrices, ``x ∈ ℝ^{n,m}``.

```@autodocs
Modules = [Manifolds]
Expand Down
8 changes: 4 additions & 4 deletions docs/src/manifolds/power.md
@@ -1,8 +1,8 @@
# [Power manifold](@id PowerManifoldSection)

A power manifold is based on a [`AbstractManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/types.html#ManifoldsBase.AbstractManifold) $\mathcal M$ to build a $\mathcal M^{n_1 \times n_2 \times \cdots \times n_m}$.
In the case where $m=1$ we can represent a manifold-valued vector of data of length $n_1$, for example a time series.
The case where $m=2$ is useful for representing manifold-valued matrices of data of size $n_1 \times n_2$, for example certain types of images.
A power manifold is based on a [`AbstractManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/types.html#ManifoldsBase.AbstractManifold) ``\mathcal M`` to build a ``\mathcal M^{n_1×n_2 ×⋯×n_m}``.
In the case where ``m=1`` we can represent a manifold-valued vector of data of length ``n_1``, for example a time series.
The case where ``m=2`` is useful for representing manifold-valued matrices of data of size ``n_1×n_2``, for example certain types of images.

There are three available representations for points and vectors on a power manifold:

Expand All @@ -17,7 +17,7 @@ Below are some examples of usage of these representations.
There are two ways to store the data: in a multidimensional array or in a nested array.

Let's look at an example for both.
Let $\mathcal M$ be `Sphere(2)` the 2-sphere and we want to look at vectors of length 4.
Let ``\mathcal M`` be `Sphere(2)` the 2-sphere and we want to look at vectors of length 4.

### `ArrayPowerRepresentation`

Expand Down
4 changes: 2 additions & 2 deletions docs/src/manifolds/product.md
@@ -1,7 +1,7 @@
# [Product manifold](@id ProductManifoldSection)

Product manifold $\mathcal M = \mathcal{M}_1 × \mathcal{M}_2 × … × \mathcal{M}_n$ of manifolds $\mathcal{M}_1, \mathcal{M}_2, …, \mathcal{M}_n$.
Points on the product manifold can be constructed using `ArrayPartition` (from `RecursiveArrayTools.jl`) with canonical projections $Π_i : \mathcal{M} → \mathcal{M}_i$ for $i ∈ 1, 2, …, n$ provided by [`submanifold_component`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/metamanifolds/#ManifoldsBase.submanifold_component-Tuple).
Product manifold ``\mathcal M = \mathcal{M}_1 × \mathcal{M}_2 × … × \mathcal{M}_n`` of manifolds ``\mathcal{M}_1, \mathcal{M}_2, …, \mathcal{M}_n``.
Points on the product manifold can be constructed using `ArrayPartition` (from `RecursiveArrayTools.jl`) with canonical projections ``Π_i : \mathcal{M} → \mathcal{M}_i`` for ``i ∈ 1, 2, …, n`` provided by [`submanifold_component`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/metamanifolds/#ManifoldsBase.submanifold_component-Tuple).

```@autodocs
Modules = [Manifolds]
Expand Down

0 comments on commit 95e90c8

Please sign in to comment.