Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quaternionic unitary group #506

Merged
merged 11 commits into from
Jul 22, 2022
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=ℂ)
kellertuer marked this conversation as resolved.
Show resolved Hide resolved

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