Skip to content

Commit

Permalink
Quaternionic unitary group (#506)
Browse files Browse the repository at this point in the history
* Quaternionic unitary group

* fixing

* merge QuaternionicUnitary into Unitary

* a small comment

* small fixes

* resolve ambiguity

* Update docs/src/misc/notation.md

Co-authored-by: Ronny Bergmann <[email protected]>

* move :constant to the first position

* put :constant first in group.md

* bump version

Co-authored-by: Ronny Bergmann <[email protected]>
  • Loading branch information
mateuszbaran and kellertuer authored Jul 22, 2022
1 parent 0cd7158 commit 595195f
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 56 deletions.
6 changes: 4 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Manifolds"
uuid = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e"
authors = ["Seth Axen <[email protected]>", "Mateusz Baran <[email protected]>", "Ronny Bergmann <[email protected]>", "Antoine Levitt <[email protected]>"]
version = "0.8.19"
version = "0.8.20"

[deps]
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
Expand All @@ -14,6 +14,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
ManifoldsBase = "3362f125-f0bb-47a3-aa74-596ffd7ef2fb"
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
MatrixEquations = "99c1a7ee-ab34-5fd5-8076-27c950a045f4"
Quaternions = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
Expand All @@ -31,9 +32,10 @@ Einsum = "0.4"
Graphs = "1.4"
HybridArrays = "0.4"
Kronecker = "0.4, 0.5"
MatrixEquations = "2.2"
ManifoldsBase = "0.13.13"
MatrixEquations = "2.2"
Plots = "1"
Quaternions = "0.5"
RecipesBase = "1.1"
RecursiveArrayTools = "2"
Requires = "0.5, 1"
Expand Down
7 changes: 4 additions & 3 deletions docs/src/manifolds/generalunitary.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@ Both [`OrthogonalMatrices`](@ref) and [`UnitaryMatrices`](@ref) are quite simila
```@autodocs
Modules = [Manifolds]
Pages = ["manifolds/Orthogonal.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

## Unitary Matrices

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


## [Common functions](@id generalunitarymatrices)

```@autodocs
Modules = [Manifolds]
Pages = ["manifolds/GeneralUnitaryMatrices.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```
34 changes: 17 additions & 17 deletions docs/src/manifolds/group.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ As a concrete wrapper for manifolds (e.g. when the manifold per se is a group ma
```@autodocs
Modules = [Manifolds]
Pages = ["groups/GroupManifold.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

### Generic Operations
Expand All @@ -52,39 +52,39 @@ For groups based on an addition operation or a group operation, several default
```@autodocs
Modules = [Manifolds]
Pages = ["groups/addition_operation.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

#### Multiplication Operation

```@autodocs
Modules = [Manifolds]
Pages = ["groups/multiplication_operation.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

### Circle group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/circle_group.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

### General linear group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/general_linear.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

### Heisenberg group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/heisenberg.jl"]
Order = [:type,:function]
Order = [:constant, :type, :function]
```

### (Special) Orthogonal and (Special) Unitary group
Expand All @@ -97,87 +97,87 @@ many common functions, these are also implemented on a common level.
```@autodocs
Modules = [Manifolds]
Pages = ["groups/general_unitary_groups.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

#### Orthogonal group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/orthogonal.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

#### Special orthogonal group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/special_orthogonal.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

#### Special unitary group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/special_unitary.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

#### Unitary group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/unitary.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

### Power group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/power_group.jl"]
Order = [:type, :function, :constant]
Order = [:constant, :type, :function]
```

### Product group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/product_group.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

### Semidirect product group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/semidirect_product_group.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

### Special Euclidean group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/special_euclidean.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

### Special linear group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/special_linear.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

### Translation group

```@autodocs
Modules = [Manifolds]
Pages = ["groups/translation_group.jl"]
Order = [:type, :function]
Order = [:constant, :type, :function]
```

## Group actions
Expand Down
2 changes: 1 addition & 1 deletion docs/src/misc/notation.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Within the documented functions, the utf8 symbols are used whenever possible, as
| ``\gamma`` | a geodesic | ``\gamma_{p;q}``, ``\gamma_{p,X}`` | connecting two points ``p,q`` or starting in ``p`` with velocity ``X``. |
| ``∇ f(p)`` | gradient of function ``f \colon \mathcal{M} \to \mathbb{R}`` at ``p \in \mathcal{M}`` | | |
| ``\circ`` | a group operation | |
| ``\cdot^\mathrm{H}`` | Hermitian or conjugate transposed| |
| ``\cdot^\mathrm{H}`` | Hermitian or conjugate transposed for both complex or quaternion matrices| |
| ``e`` | identity element of a group | |
| ``I_k`` | identity matrix of size ``k\times k`` | |
| ``k`` | indices | ``i,j`` | |
Expand Down
1 change: 1 addition & 0 deletions src/Manifolds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ using ManifoldsBase:
trait
using Markdown: @doc_str
using MatrixEquations: lyapc
using Quaternions
using Random
using RecipesBase
using RecipesBase: @recipe, @series
Expand Down
50 changes: 34 additions & 16 deletions src/groups/unitary.jl
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
@doc raw"""
Unitary{n,𝔽} = GeneralUnitaryMultiplicationGroup{n,,AbsoluteDeterminantOneMatrices}
Unitary{n,𝔽} = GeneralUnitaryMultiplicationGroup{n,𝔽,AbsoluteDeterminantOneMatrices}
The group of unitary matrices ``\mathrm{U}(n)``.
The group of unitary matrices ``\mathrm{U}(n, 𝔽)``, either complex (when 𝔽=ℂ) or quaternionic
(when 𝔽=ℍ)
The group consists of all points ``p ∈ \mathbb C^{n × n}`` where ``p^\mathrm{H}p = pp^\mathrm{H} = I``.
The group consists of all points ``p ∈ 𝔽^{n × n}`` where ``p^\mathrm{H}p = pp^\mathrm{H} = I``.
The tangent spaces are if the form
```math
T_p\mathrm{U}(x) = \bigl\{ X \in \mathbb C^{n×n} \big| X = pY \text{ where } Y = -Y^{\mathrm{H}} \bigr\}
T_p\mathrm{U}(n) = \bigl\{ X \in 𝔽^{n×n} \big| X = pY \text{ where } Y = -Y^{\mathrm{H}} \bigr\}
```
and we represent tangent vectors by just storing the [`SkewHermitianMatrices`](@ref) ``Y``,
or in other words we represent the tangent spaces employing the Lie algebra ``\mathfrak{u}(n)``.
or in other words we represent the tangent spaces employing the Lie algebra ``\mathfrak{u}(n, 𝔽)``.
Quaternionic unitary group is isomorphic to the compact symplectic group of the same dimension.
# Constructor
Unitary(n)
Unitary(n, 𝔽::AbstractNumbers=ℂ)
Construct ``\mathrm{U}(n)``.
Construct ``\mathrm{U}(n, 𝔽)``.
See also [`Orthogonal(n)`](@ref) for the real-valued case.
"""
const Unitary{n} = GeneralUnitaryMultiplicationGroup{n,,AbsoluteDeterminantOneMatrices}
const Unitary{n,𝔽} = GeneralUnitaryMultiplicationGroup{n,𝔽,AbsoluteDeterminantOneMatrices}

Unitary(n) = Unitary{n}(UnitaryMatrices(n))
Unitary(n, 𝔽::AbstractNumbers=) = Unitary{n,𝔽}(UnitaryMatrices(n, 𝔽))

@doc raw"""
exp_lie(G::Unitary{2}, X)
exp_lie(G::Unitary{2,ℂ}, X)
Compute the group exponential map on the [`Unitary(2)`](@ref) group, which is
Expand All @@ -35,15 +38,19 @@ Compute the group exponential map on the [`Unitary(2)`](@ref) group, which is
```
where ``θ = \frac{1}{2} \sqrt{4\det(X) - \operatorname{tr}(X)^2}``.
"""
exp_lie(::Unitary{2}, X)
"""
exp_lie(::Unitary{2,ℂ}, X)

function exp_lie(::Unitary{1,ℍ}, X::Number)
return exp(X)
end

function exp_lie!(::Unitary{1}, q, X)
q[1] = exp(X[1])
q[] = exp(X[])
return q
end

function exp_lie!(::Unitary{2}, q, X)
function exp_lie!(::Unitary{2,ℂ}, q, X)
size(X) === (2, 2) && size(q) === (2, 2) || throw(DomainError())
@inbounds a, d = imag(X[1, 1]), imag(X[2, 2])
@inbounds b = (X[2, 1] - X[1, 2]') / 2
Expand All @@ -69,7 +76,11 @@ function exp_lie!(G::Unitary, q, X)
end

function log_lie!(::Unitary{1}, X, p)
X[1] = log(p[1])
X[] = log(p[])
return X
end
function log_lie!(::Unitary{1}, X::AbstractMatrix, p::AbstractMatrix)
X[] = log(p[])
return X
end
function log_lie!(G::Unitary, X, p)
Expand All @@ -78,6 +89,13 @@ function log_lie!(G::Unitary, X, p)
return X
end

identity_element(::Unitary{1,ℍ}) = Quaternion(1.0)

function log_lie(::Unitary{1}, q::Number)
return log(q)
end

Base.inv(::Unitary, p) = adjoint(p)

show(io::IO, ::Unitary{n}) where {n} = print(io, "Unitary($(n))")
show(io::IO, ::Unitary{n,ℂ}) where {n} = print(io, "Unitary($(n))")
show(io::IO, ::Unitary{n,ℍ}) where {n} = print(io, "Unitary($(n), ℍ)")
2 changes: 2 additions & 0 deletions src/manifolds/GeneralUnitaryMatrices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ function default_estimation_method(
return GeodesicInterpolationWithinRadius/ 2 / 2)
end

embed(::GeneralUnitaryMatrices, p) = p

@doc raw"""
embed(M::GeneralUnitaryMatrices{n,𝔽}, p, X)
Expand Down
37 changes: 30 additions & 7 deletions src/manifolds/Unitary.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@

@doc raw"""
const UnitaryMatrices{n} = AbstarctUnitaryMatrices{n,,AbsoluteDeterminantOneMatrices}
const UnitaryMatrices{n,𝔽} = AbstarctUnitaryMatrices{n,𝔽,AbsoluteDeterminantOneMatrices}
The manifold ``U(n)`` of ``n×n`` complex matrices such that
The manifold ``U(n,𝔽)`` of ``n×n`` complex matrices (when 𝔽=ℂ) or quaternionic matrices
(when 𝔽=ℍ) such that
``p^{\mathrm{H}}p = \mathrm{I}_n,``
Expand All @@ -17,15 +18,37 @@ The tangent spaces are given by
\bigr\}
```
But note that tangent vectors are represented in the Lie algebra, i.e. just using ``Y`` in the representation above.
But note that tangent vectors are represented in the Lie algebra, i.e. just using ``Y`` in
the representation above.
# Constructor
UnitaryMatrices(n)
UnitaryMatrices(n, 𝔽::AbstractNumbers=ℂ)
see also [`OrthogonalMatrices`](@ref) for the real valued case.
"""
const UnitaryMatrices{n} = GeneralUnitaryMatrices{n,,AbsoluteDeterminantOneMatrices}
const UnitaryMatrices{n,𝔽} = GeneralUnitaryMatrices{n,𝔽,AbsoluteDeterminantOneMatrices}

UnitaryMatrices(n::Int) = UnitaryMatrices{n}()
UnitaryMatrices(n::Int, 𝔽::AbstractNumbers=) = UnitaryMatrices{n,𝔽}()

show(io::IO, ::UnitaryMatrices{n}) where {n} = print(io, "UnitaryMatrices($(n))")
check_size(::UnitaryMatrices{1,ℍ}, p::Number) = nothing
check_size(::UnitaryMatrices{1,ℍ}, p, X::Number) = nothing

embed(::UnitaryMatrices{1,ℍ}, p::Number) = SMatrix{1,1}(p)

embed(::UnitaryMatrices{1,ℍ}, p, X::Number) = SMatrix{1,1}(X)

function exp(::UnitaryMatrices{1,ℍ}, p, X::Number)
return p * exp(X)
end

function log(::UnitaryMatrices{1,ℍ}, p::Number, q::Number)
return log(conj(p) * q)
end

project(::UnitaryMatrices{1,ℍ}, p) = normalize(p)

project(::UnitaryMatrices{1,ℍ}, p, X) = (X - conj(X)) / 2

show(io::IO, ::UnitaryMatrices{n,ℂ}) where {n} = print(io, "UnitaryMatrices($(n))")
show(io::IO, ::UnitaryMatrices{n,ℍ}) where {n} = print(io, "UnitaryMatrices($(n), ℍ)")
Loading

2 comments on commit 595195f

@mateuszbaran
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/64825

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.8.20 -m "<description of version>" 595195fa6afdc9cae961a1d5715246fe26cc1655
git push origin v0.8.20

Please sign in to comment.