Added documentation fro Groups module

This commit is contained in:
Alberto Ramos 2023-01-31 15:52:19 +01:00
parent 63ff01a2be
commit 208d03d245
11 changed files with 294 additions and 31 deletions

8
docs/make.jl Normal file
View file

@ -0,0 +1,8 @@
using Documenter
import Pkg
Pkg.activate("../")
using LatticeGPU
makedocs(sitename="LatticeGPU", modules=[LatticeGPU], doctest=true,
repo = "https://igit.ific.uv.es/alramos/latticegpu.jl")

161
docs/src/groups.md Normal file
View file

@ -0,0 +1,161 @@
# Groups and Algebras
The module `Groups` contain generic data types to deal with group and
algebra elements. Group elements $$g\in SU(N)$$ are represented in
some compact notation. For the case $$N=2$$ we use two complex numbers
(Caley-Dickson representation, i.e. $$g=(z_1,z_2)$$ with
$$|z_1|^2 + |z_2|^2=1$$). For the case $$N=3$$ we only store two
rows of the $$N\times N$$ unitary matrix.
Group operations translate straightforwardly in matrix operations,
except for $$SU(2)$$, where we use
```math
\forall g=(z_1, z_2)\in SU(2)\, \Longrightarrow\, g^{-1} =
(\overline z_1, -z_2)
```
and
```math
\forall g=(z_1, z_2), g'=(w_1,w_2)\in SU(2)\, \Longrightarrow \, g g'= (z_1w_1 - \overline w_2 z_2, w_2z_1 + z_2\overline w_1)\,.
```
Group elements can be "casted" into arrays. The abstract type
[`GMatrix`](@ref) represent generic $$ N\\times N$$ complex arrays.
Algebra elements $$X \in \mathfrak{su}(N)$$ are traceless
anti-hermitian matrices represented trough $$N^2-1$$ real numbers
$$X^a$$. We have
```math
X = \sum_{a=1}^{N^2-1} X^a T^a
```
where $$T^a$$ are a basis of the $$\mathfrak{su}(N)$$ algebra with
the conventions
```math
(T^a)^+ = -T^a \,\qquad
{\rm Tr}(T^aT^b) = -\frac{1}{2}\delta_{ab}\,.
```
If we denote by $$\{\mathbf{e}_i\}$$ the usual ortonormal basis of
$$\mathbb R^N$$, the $$N^2-1$$ matrices $$T^a$$ can always be written in the
following way
1. symmetric matrices ($$N(N-1)/2$$)
```math
(T^a)_{ij} = \frac{\imath}{2}(\mathbf{e}_i\otimes\mathbf{e}_j +
\mathbf{e}_j\otimes \mathbf{e}_i)\quad (1\le i < j \le N)
```
1. anti-symmetric matrices ($$N(N-1)/2$$)
```math
(T^a)_{ij} = \frac{1}{2}(\mathbf{e}_i\otimes\mathbf{e}_j -
\mathbf{e}_j\otimes \mathbf{e}_i)\quad (1\le i < j \le N)
```
1. diagonal matrices ($$N-1$$). With $$l=1,...,N-1$$ and $$a=l+N(N-1)$$
```math
(T^a)_{ij} = \frac{\imath}{2}\sqrt{\frac{2}{l(l+1)}}
\left(\sum_{j=1}^l\mathbf{e}_j\otimes\mathbf{e}_j -
l\mathbf{e}_{l+1}\otimes \mathbf{e}_{l+1}\right)
\quad (l=1,\dots,N-1;\, a=l+N(N-1))
```
For example in the case of $$\mathfrak{su}(2)$$, and denoting the Pauli
matrices by $$\sigma^a$$ we have
```math
T^a = \frac{\imath}{2}\sigma^a \quad(a=1,2,3)\,,
```
while for $$\mathfrak{su}(3)$$ we have $$T^a=\imath \lambda^a/2$$ (with
$$\lambda^a$$ the Gell-Mann matrices) up to a permutation.
## Some examples
```@setup exs
import Pkg # hide
Pkg.activate("/home/alberto/code/julia/LatticeGPU/") # hide
using LatticeGPU # hide
```
Here we just show some example codes playing with groups and
elements. The objective is to get an idea on how group operations
We can generate some random group elements.
```@repl exs
# Generate random groups elements,
# check they are actually from the grup
g = rand(SU2{Float64})
println("Are we in a group?: ", isgroup(g))
g = rand(SU3{Float64})
println("Are we in a group?: ", isgroup(g))
```
We can also do some simple operations
```@repl exs
X = rand(SU3alg{Float64})
g1 = exp(X);
g2 = exp(X, -2.0); # e^{-2X}
g = g1*g1*g2;
println("Is this one? ", dev_one(g))
```
## Types
### Groups
The generic interface reads
```@docs
Group
```
Concrete supported implementations are
```@docs
SU2
SU3
```
### Algebras
The generic interface reads
```@docs
Algebra
```
With the following concrete implementations
```@docs
SU2alg
SU3alg
```
### GMatrix
The generic interface reads
```@docs
GMatrix
```
With the following concrete implementations
```@docs
M2x2
M3x3
```
## Generic `Group` methods
```@docs
inverse
dag
tr
dev_one
unitarize
isgroup
projalg
```
## Generic `Algebra` methods
```@docs
exp
expm
alg2mat
```

8
docs/src/index.md Normal file
View file

@ -0,0 +1,8 @@
# LatticeGPU.jl documentation
```@contents
```

View file

@ -11,6 +11,16 @@
SU2alg(x::T) where T <: AbstractFloat = SU2alg{T}(x,0.0,0.0) SU2alg(x::T) where T <: AbstractFloat = SU2alg{T}(x,0.0,0.0)
SU2alg(v::Vector{T}) where T <: AbstractFloat = SU2alg{T}(v[1],v[2],v[3]) SU2alg(v::Vector{T}) where T <: AbstractFloat = SU2alg{T}(v[1],v[2],v[3])
"""
projalg([z::Complex,] g::T) where T <: Union{Group, GMatrix}
Projects the group element/matrix `g` (or `zg`) to the algebra. This amounts to the following operation:
\`\` X = {\\rm projalg}(g) = -X^a\\frac{1}{2} {\\rm tr}\\{T^a(g - g^{\\dagger})\\} \`\`
where the substraction of group elements has to be understood in the matrix sense. This method returns an [`Algebra`](@ref) type. The generators of the algebra are the elements \`\` T^a\`\`.
"""
projalg(g::SU2{T}) where T <: AbstractFloat = SU2alg{T}(imag(g.t2), real(g.t2), imag(g.t1)) projalg(g::SU2{T}) where T <: AbstractFloat = SU2alg{T}(imag(g.t2), real(g.t2), imag(g.t1))
projalg(z::Complex{T}, g::SU2{T}) where T <: AbstractFloat = SU2alg{T}(imag(z*g.t2), real(z*g.t2), imag(z*g.t1)) projalg(z::Complex{T}, g::SU2{T}) where T <: AbstractFloat = SU2alg{T}(imag(z*g.t2), real(z*g.t2), imag(z*g.t1))
dot(a::SU2alg{T}, b::SU2alg{T}) where T <: AbstractFloat = a.t1*b.t1 + a.t2*b.t2 + a.t3*b.t3 dot(a::SU2alg{T}, b::SU2alg{T}) where T <: AbstractFloat = a.t1*b.t1 + a.t2*b.t2 + a.t3*b.t3
@ -26,6 +36,11 @@ Base.:*(a::SU2alg{T},b::Number) where T <: AbstractFloat = SU2alg{T}(a.t1*b,a
Base.:*(b::Number,a::SU2alg{T}) where T <: AbstractFloat = SU2alg{T}(a.t1*b,a.t2*b,a.t3*b) Base.:*(b::Number,a::SU2alg{T}) where T <: AbstractFloat = SU2alg{T}(a.t1*b,a.t2*b,a.t3*b)
Base.:/(a::SU2alg{T},b::Number) where T <: AbstractFloat = SU2alg{T}(a.t1/b,a.t2/b,a.t3/b) Base.:/(a::SU2alg{T},b::Number) where T <: AbstractFloat = SU2alg{T}(a.t1/b,a.t2/b,a.t3/b)
"""
alg2mat(a::T) where T <: Algebra
Returns the [`Algebra`](@ref) element as a [`GMatrix`](@ref) type.
"""
function alg2mat(a::SU2alg{T}) where T <: AbstractFloat function alg2mat(a::SU2alg{T}) where T <: AbstractFloat
u11::Complex{T} = complex(0.0, a.t3)/2 u11::Complex{T} = complex(0.0, a.t3)/2
@ -41,11 +56,10 @@ Base.:*(a::SU2,b::SU2alg) = a*alg2mat(b)
Base.:/(a::SU2alg,b::SU2) = alg2mat(a)/b Base.:/(a::SU2alg,b::SU2) = alg2mat(a)/b
Base.:\(a::SU2,b::SU2alg) = a\alg2mat(b) Base.:\(a::SU2,b::SU2alg) = a\alg2mat(b)
""" """
function Base.exp(a::T, t::Number=1) where {T <: Algebra} exp(a::T, t::Number=1) where {T <: Algebra}
Computes `exp(a)` Computes `exp(ta)`
""" """
function Base.exp(a::SU2alg{T}) where T <: AbstractFloat function Base.exp(a::SU2alg{T}) where T <: AbstractFloat
@ -83,9 +97,9 @@ end
""" """
function expm(g::G, a::A) where {G <: Algebra, A <: Algebra} expm(g::G, a::A, t=1) where {G <: Group, A <: Algebra}
Computes `exp(a)*g` Computes `g*exp(ta)`
""" """
function expm(g::SU2{T}, a::SU2alg{T}) where T <: AbstractFloat function expm(g::SU2{T}, a::SU2alg{T}) where T <: AbstractFloat
@ -105,12 +119,6 @@ function expm(g::SU2{T}, a::SU2alg{T}) where T <: AbstractFloat
return SU2{T}(t1,t2) return SU2{T}(t1,t2)
end end
"""
function expm(g::SU2, a::SU2alg, t::Float64)
Computes `exp(t*a)*g`
"""
function expm(g::SU2{T}, a::SU2alg{T}, t::T) where T <: AbstractFloat function expm(g::SU2{T}, a::SU2alg{T}, t::T) where T <: AbstractFloat
rm = t*sqrt( a.t1^2+a.t2^2+a.t3^2 )/2.0 rm = t*sqrt( a.t1^2+a.t2^2+a.t3^2 )/2.0

View file

@ -16,15 +16,39 @@
using CUDA, Random using CUDA, Random
SU2(a::T, b::T) where T <: AbstractFloat = SU2{T}(complex(a), complex(b)) SU2(a::T, b::T) where T <: AbstractFloat = SU2{T}(complex(a), complex(b))
"""
inverse(g::T) where T <: Group
Returns the group inverse of `g`.
"""
inverse(b::SU2{T}) where T <: AbstractFloat = SU2{T}(conj(b.t1), -b.t2) inverse(b::SU2{T}) where T <: AbstractFloat = SU2{T}(conj(b.t1), -b.t2)
"""
dag(g::T) where T <: Group
Returns the group inverse of `g`.
"""
dag(a::SU2{T}) where T <: AbstractFloat = inverse(a) dag(a::SU2{T}) where T <: AbstractFloat = inverse(a)
norm(a::SU2{T}) where T <: AbstractFloat = sqrt(abs2(a.t1) + abs2(a.t2)) norm(a::SU2{T}) where T <: AbstractFloat = sqrt(abs2(a.t1) + abs2(a.t2))
norm2(a::SU2{T}) where T <: AbstractFloat = abs2(a.t1) + abs2(a.t2) norm2(a::SU2{T}) where T <: AbstractFloat = abs2(a.t1) + abs2(a.t2)
tr(g::SU2{T}) where T <: AbstractFloat = complex(2.0*real(g.t1), 0.0)
"""
tr(g::T) where T <: Group
Returns the trace of the groups element `g`.
"""
tr(g::SU2{T}) where T <: AbstractFloat = complex(2*real(g.t1), 0.0)
"""
dev_one(T) where T <: Group
Returns the distance to the unit group element
"""
dev_one(g::SU2{T}) where T <: AbstractFloat = sqrt(( abs2(g.t1 - one(T)) + abs2(g.t2))/2) dev_one(g::SU2{T}) where T <: AbstractFloat = sqrt(( abs2(g.t1 - one(T)) + abs2(g.t2))/2)
""" """
function unitarize(a::T) where {T <: Group} unitarize(a::T) where {T <: Group}
Return a unitarized element of the group. Return a unitarized element of the group.
""" """
@ -40,6 +64,11 @@ Base.:*(a::SU2{T},b::SU2{T}) where T <: AbstractFloat = SU2{T}(a.t1*b.t1-a.t2*co
Base.:/(a::SU2{T},b::SU2{T}) where T <: AbstractFloat = SU2{T}(a.t1*conj(b.t1)+a.t2*conj(b.t2),-a.t1*b.t2+a.t2*b.t1) Base.:/(a::SU2{T},b::SU2{T}) where T <: AbstractFloat = SU2{T}(a.t1*conj(b.t1)+a.t2*conj(b.t2),-a.t1*b.t2+a.t2*b.t1)
Base.:\(a::SU2{T},b::SU2{T}) where T <: AbstractFloat = SU2{T}(conj(a.t1)*b.t1+a.t2*conj(b.t2),conj(a.t1)*b.t2-a.t2*conj(b.t1)) Base.:\(a::SU2{T},b::SU2{T}) where T <: AbstractFloat = SU2{T}(conj(a.t1)*b.t1+a.t2*conj(b.t2),conj(a.t1)*b.t2-a.t2*conj(b.t1))
"""
isgroup(g::T) where T <: Group
Returns `true` if `g` is a group element, `false` otherwise.
"""
function isgroup(a::SU2{T}) where T <: AbstractFloat function isgroup(a::SU2{T}) where T <: AbstractFloat
tol = 1.0E-10 tol = 1.0E-10
if (abs2(a.t1) + abs2(a.t2) - 1.0 < 1.0E-10) if (abs2(a.t1) + abs2(a.t2) - 1.0 < 1.0E-10)

View file

@ -64,20 +64,9 @@ Base.:/(a::U1alg{T},b::Number) where T <: AbstractFloat = U1alg{T}(a.t/b)
isgroup(a::U1{T}) where T <: AbstractFloat = (abs(a.t) -1.0) < 1.0E-10 isgroup(a::U1{T}) where T <: AbstractFloat = (abs(a.t) -1.0) < 1.0E-10
"""
function Base.exp(a::U1alg, t::Number=1)
Computes `exp(a)`
"""
Base.exp(a::U1alg{T}) where T <: AbstractFloat = U1{T}(CUDA.cos(a.t), CUDA.sin(a.t)) Base.exp(a::U1alg{T}) where T <: AbstractFloat = U1{T}(CUDA.cos(a.t), CUDA.sin(a.t))
Base.exp(a::U1alg{T}, t::T) where T <: AbstractFloat = U1{T}(CUDA.cos(t*a.t), CUDA.sin(t*a.t)) Base.exp(a::U1alg{T}, t::T) where T <: AbstractFloat = U1{T}(CUDA.cos(t*a.t), CUDA.sin(t*a.t))
"""
function expm(g::U1, a::U1alg; t=1)
Computes `exp(a)*g`
"""
expm(g::U1{T}, a::U1alg{T}) where T <: AbstractFloat = U1{T}(CUDA.cos(a.t), CUDA.sin(a.t))*g expm(g::U1{T}, a::U1alg{T}) where T <: AbstractFloat = U1{T}(CUDA.cos(a.t), CUDA.sin(a.t))*g
expm(g::U1{T}, a::U1alg{T}, t::T) where T <: AbstractFloat = U1{T}(CUDA.cos(t*a.t), CUDA.sin(t*a.t))*g expm(g::U1{T}, a::U1alg{T}, t::T) where T <: AbstractFloat = U1{T}(CUDA.cos(t*a.t), CUDA.sin(t*a.t))*g

View file

@ -16,10 +16,39 @@ using CUDA, Random
import Base.:*, Base.:+, Base.:-,Base.:/,Base.:\,Base.exp,Base.one,Base.zero import Base.:*, Base.:+, Base.:-,Base.:/,Base.:\,Base.exp,Base.one,Base.zero
import Random.rand import Random.rand
"""
abstract type Group
This abstract type encapsulates group types (i.e. \`\`SU(N)\`\`). The following operations/methods are assumed to be defined for a each group.
- `*,/,\\`: Usual group operations.
- [`inverse`](@ref), [`dag`](@ref): The group inverse.
- [`tr`](@ref)
- [`dev_one`](@ref)
- [`unitarize`](@ref)
- [`isgroup`](@ref)
- [`projalg`](@ref)
"""
abstract type Group end abstract type Group end
"""
abstract type Algebra
This abstract type encapsulates algebra types (i.e. \`\` {\\rm su}(N)\`\`). The following operations/methods are assumed to be defined for each algebra:
- `+,-`: Usual operation of Algebra elements.
- `*,/`: Multiplication/division by Numbers
- `*`: Multiplication of [`Algebra`](@ref) and [`Group`](@ref) or [`GMatrix`](@ref) elements. These routines use the matrix form of the group elements, and return a [`GMatrix`](@ref) type.
- [`exp`](@ref), [`expm`](@ref): Exponential map. Returns a [`Group`](@ref) element.
"""
abstract type Algebra end abstract type Algebra end
export Group, Algebra """
abstract type GM
This abstract type encapsulates \`\` N\\times N \`\` matrix types. The usual matrix operations (`+,-,*,/`) are expected to be defined for this case.
"""
abstract type GMatrix end
export Group, Algebra, GMatrix
## ##
# SU(2) and 2x2 matrix operations # SU(2) and 2x2 matrix operations

View file

@ -9,18 +9,34 @@
### created: Sun Oct 3 09:22:48 2021 ### created: Sun Oct 3 09:22:48 2021
### ###
"""
struct SU2{T} <: Group
\`\`SU(2)\`\` elements. The type `T <: AbstractFloat` can be used to define single or double precision elements.
"""
struct SU2{T} <: Group struct SU2{T} <: Group
t1::Complex{T} t1::Complex{T}
t2::Complex{T} t2::Complex{T}
end end
struct M2x2{T} """
struct M2x2{T} <: GMatrix
Generic \`\` 2\\times 2\`\` complex matrix.
"""
struct M2x2{T} <: GMatrix
u11::Complex{T} u11::Complex{T}
u12::Complex{T} u12::Complex{T}
u21::Complex{T} u21::Complex{T}
u22::Complex{T} u22::Complex{T}
end end
"""
struct SU2alg{T} <: Algebra
\`\`{\\rm su}(2)\`\` Algebra elements.
"""
struct SU2alg{T} <: Algebra struct SU2alg{T} <: Algebra
t1::T t1::T
t2::T t2::T

View file

@ -20,6 +20,11 @@
import Base.convert import Base.convert
"""
struct SU3{T} <: Group
\`\`SU(3)\`\` elements. The type `T <: AbstractFloat` can be used to define single or double precision elements.
"""
struct SU3{T} <: Group struct SU3{T} <: Group
u11::Complex{T} u11::Complex{T}
u12::Complex{T} u12::Complex{T}
@ -30,7 +35,12 @@ struct SU3{T} <: Group
end end
Base.one(::Type{SU3{T}}) where T <: AbstractFloat = SU3{T}(one(T),zero(T),zero(T),zero(T),one(T),zero(T)) Base.one(::Type{SU3{T}}) where T <: AbstractFloat = SU3{T}(one(T),zero(T),zero(T),zero(T),one(T),zero(T))
struct M3x3{T} """
struct M3x3{T} <: Group
3x3 Complex matrix. The type `T <: AbstractFloat` can be used to define single or double precision elements.
"""
struct M3x3{T} <: GMatrix
u11::Complex{T} u11::Complex{T}
u12::Complex{T} u12::Complex{T}
u13::Complex{T} u13::Complex{T}
@ -44,6 +54,11 @@ end
Base.one(::Type{M3x3{T}}) where T <: AbstractFloat = M3x3{T}(one(T),zero(T),zero(T),zero(T),one(T),zero(T),zero(T),zero(T),one(T)) Base.one(::Type{M3x3{T}}) where T <: AbstractFloat = M3x3{T}(one(T),zero(T),zero(T),zero(T),one(T),zero(T),zero(T),zero(T),one(T))
Base.zero(::Type{M3x3{T}}) where T <: AbstractFloat = M3x3{T}(zero(T),zero(T),zero(T),zero(T),zero(T),zero(T),zero(T),zero(T),zero(T)) Base.zero(::Type{M3x3{T}}) where T <: AbstractFloat = M3x3{T}(zero(T),zero(T),zero(T),zero(T),zero(T),zero(T),zero(T),zero(T),zero(T))
"""
struct SU3alg{T} <: Group
\`\`su(3)\`\` elements. The type `T <: AbstractFloat` can be used to define single or double precision elements.
"""
struct SU3alg{T} <: Algebra struct SU3alg{T} <: Algebra
t1::T t1::T
t2::T t2::T

View file

@ -15,7 +15,7 @@ module LatticeGPU
include("Groups/Groups.jl") include("Groups/Groups.jl")
using .Groups using .Groups
export Group, Algebra export Group, Algebra, GMatrix
export SU2, SU2alg, SU3, SU3alg, M3x3, M2x2, U1, U1alg, SU3fund export SU2, SU2alg, SU3, SU3alg, M3x3, M2x2, U1, U1alg, SU3fund
export dot, expm, exp, dag, unitarize, inverse, tr, projalg, norm, norm2, isgroup, alg2mat, dev_one export dot, expm, exp, dag, unitarize, inverse, tr, projalg, norm, norm2, isgroup, alg2mat, dev_one