1
0
mirror of https://github.com/kalmarek/Groups.jl.git synced 2024-11-19 14:35:28 +01:00

format MatrixGroups module

This commit is contained in:
Marek Kaluba 2023-03-15 18:32:27 +01:00
parent a0d2186477
commit 29af9659d9
No known key found for this signature in database
GPG Key ID: 8BF1A3855328FC15
4 changed files with 93 additions and 44 deletions

View File

@ -24,15 +24,21 @@ Base.show(io::IO, ::SymplecticGroup{N,T}) where {N,T} = print(io, "Sp{$N,$T}")
function Base.show(io::IO, ::MIME"text/plain", ::SymplecticGroup{N}) where {N}
return print(io, "group of $N×$N symplectic matrices")
end
_offdiag_idcs(n) = ((i, j) for i in 1:n for j in 1:n if i j)
function symplectic_gens(N, T=Int8)
function symplectic_gens(N, T = Int8)
iseven(N) || throw(ArgumentError("N needs to be even!"))
n = N ÷ 2
a_ijs = [ElementarySymplectic{N}(:A, i, j, one(T)) for (i, j) in _offdiag_idcs(n)]
_offdiag_idcs(n) = ((i, j) for i in 1:n for j in 1:n if i j)
a_ijs = [
ElementarySymplectic{N}(:A, i, j, one(T)) for (i, j) in _offdiag_idcs(n)
]
b_is = [ElementarySymplectic{N}(:B, n + i, i, one(T)) for i in 1:n]
c_ijs = [ElementarySymplectic{N}(:B, n + i, j, one(T)) for (i, j) in _offdiag_idcs(n)]
c_ijs = [
ElementarySymplectic{N}(:B, n + i, j, one(T)) for
(i, j) in _offdiag_idcs(n)
]
S = [a_ijs; b_is; c_ijs]
@ -49,11 +55,16 @@ function _std_symplectic_form(m::AbstractMatrix)
n = r ÷ 2
𝕆 = zeros(eltype(m), n, n)
𝕀 = one(eltype(m)) * LinearAlgebra.I
Ω = [𝕆 -𝕀
𝕀 𝕆]
Ω = [
𝕆 -𝕀
𝕀 𝕆
]
return Ω
end
function issymplectic(mat::M, Ω=_std_symplectic_form(mat)) where {M<:AbstractMatrix}
function issymplectic(
mat::M,
Ω = _std_symplectic_form(mat),
) where {M<:AbstractMatrix}
return Ω == transpose(mat) * Ω * mat
end

View File

@ -1,26 +1,31 @@
abstract type AbstractMatrixGroup{N,T} <: Groups.AbstractFPGroup end
const MatrixGroupElement{N,T} = Groups.AbstractFPGroupElement{<:AbstractMatrixGroup{N,T}}
const MatrixGroupElement{N,T} =
Groups.AbstractFPGroupElement{<:AbstractMatrixGroup{N,T}}
Base.isone(g::MatrixGroupElement{N,T}) where {N,T} =
isone(word(g)) || isone(matrix(g))
function Base.isone(g::MatrixGroupElement{N,T}) where {N,T}
return isone(word(g)) || isone(matrix(g))
end
function Base.:(==)(m1::M1, m2::M2) where {M1<:MatrixGroupElement,M2<:MatrixGroupElement}
function Base.:(==)(
m1::M1,
m2::M2,
) where {M1<:MatrixGroupElement,M2<:MatrixGroupElement}
parent(m1) === parent(m2) || return false
word(m1) == word(m2) && return true
return matrix(m1) == matrix(m2)
end
Base.size(m::MatrixGroupElement{N}) where {N} = (N, N)
Base.eltype(m::MatrixGroupElement{N,T}) where {N,T} = T
Base.size(::MatrixGroupElement{N}) where {N} = (N, N)
Base.size(::MatrixGroupElement{N}, d) where {N} = ifelse(d::Integer <= 2, N, 1)
Base.eltype(::MatrixGroupElement{N,T}) where {N,T} = T
# three structural assumptions about matrix groups
Groups.word(sl::MatrixGroupElement) = sl.word
Base.parent(sl::MatrixGroupElement) = sl.parent
Groups.alphabet(M::MatrixGroup) = M.alphabet
Groups.rewriting(M::MatrixGroup) = alphabet(M)
Groups.word(m::MatrixGroupElement) = m.word
Base.parent(m::MatrixGroupElement) = m.parent
Groups.alphabet(M::AbstractMatrixGroup) = M.alphabet
Groups.rewriting(M::AbstractMatrixGroup) = alphabet(M)
Base.hash(m::MatrixGroupElement, h::UInt) =
hash(matrix(m), hash(parent(m), h))
Base.hash(m::MatrixGroupElement, h::UInt) = hash(matrix(m), hash(parent(m), h))
function matrix(m::MatrixGroupElement{N,T}) where {N,T}
if isone(word(m))
@ -30,37 +35,55 @@ function matrix(m::MatrixGroupElement{N,T}) where {N,T}
return prod(matrix(A[l]) for l in word(m))
end
function Base.convert(
::Type{M},
m::MatrixGroupElement,
) where {M<:AbstractMatrix}
return convert(M, matrix(m))
end
(M::Type{<:AbstractMatrix})(m::MatrixGroupElement) = convert(M, m)
function Base.rand(
rng::Random.AbstractRNG,
rs::Random.SamplerTrivial{<:AbstractMatrixGroup},
)
Mgroup = rs[]
S = gens(Mgroup)
return prod(g -> rand(rng, Bool) ? g : inv(g), rand(rng, S, rand(rng, 1:30)))
return prod(
g -> rand(rng, Bool) ? g : inv(g),
rand(rng, S, rand(rng, 1:30)),
)
end
function Base.show(io::IO, M::AbstractMatrixGroup)
g = gens(M, 1)
N = size(g, 1)
print(io, "H ⩽ GL{$N,$(eltype(g))}")
return print(io, "H ⩽ GL{$N,$(eltype(g))}")
end
function Base.show(io::IO, ::MIME"text/plain", M::AbstractMatrixGroup)
N = size(gens(M, 1), 1)
ng = GroupsCore.ngens(M)
print(io, "subgroup of $N×$N invertible matrices with $(ng) generators")
return print(
io,
"subgroup of $N×$N invertible matrices with $(ng) generators",
)
end
Base.show(io::IO, mat::Groups.AbstractFPGroupElement{<:AbstractMatrixGroup}) =
KnuthBendix.print_repr(io, word(mat), alphabet(mat))
function Base.show(
io::IO,
mat::Groups.AbstractFPGroupElement{<:AbstractMatrixGroup},
)
return KnuthBendix.print_repr(io, word(mat), alphabet(mat))
end
function Base.show(
io::IO,
::MIME"text/plain",
mat::Groups.AbstractFPGroupElement{<:AbstractMatrixGroup{N}}
mat::Groups.AbstractFPGroupElement{<:AbstractMatrixGroup{N}},
) where {N}
Groups.normalform!(mat)
KnuthBendix.print_repr(io, word(mat), alphabet(mat))
println(io, "", parent(mat))
Base.print_array(io, matrix(mat))
return Base.print_array(io, matrix(mat))
end

View File

@ -2,23 +2,27 @@ struct ElementaryMatrix{N,T} <: Groups.GSymbol
i::Int
j::Int
val::T
ElementaryMatrix{N}(i, j, val=1) where {N} =
(@assert i j; new{N,typeof(val)}(i, j, val))
function ElementaryMatrix{N}(i, j, val = 1) where {N}
return (@assert i j; new{N,typeof(val)}(i, j, val))
end
end
function Base.show(io::IO, e::ElementaryMatrix)
print(io, 'E', Groups.subscriptify(e.i), Groups.subscriptify(e.j))
!isone(e.val) && print(io, "^$(e.val)")
return !isone(e.val) && print(io, "^$(e.val)")
end
Base.:(==)(e::ElementaryMatrix{N}, f::ElementaryMatrix{N}) where {N} =
e.i == f.i && e.j == f.j && e.val == f.val
function Base.:(==)(e::ElementaryMatrix{N}, f::ElementaryMatrix{N}) where {N}
return e.i == f.i && e.j == f.j && e.val == f.val
end
Base.hash(e::ElementaryMatrix, h::UInt) =
hash(typeof(e), hash((e.i, e.j, e.val), h))
function Base.hash(e::ElementaryMatrix, h::UInt)
return hash(typeof(e), hash((e.i, e.j, e.val), h))
end
Base.inv(e::ElementaryMatrix{N}) where {N} =
ElementaryMatrix{N}(e.i, e.j, -e.val)
function Base.inv(e::ElementaryMatrix{N}) where {N}
return ElementaryMatrix{N}(e.i, e.j, -e.val)
end
function matrix(e::ElementaryMatrix{N,T}) where {N,T}
m = StaticArrays.MMatrix{N,N,T}(LinearAlgebra.I)

View File

@ -3,7 +3,12 @@ struct ElementarySymplectic{N,T} <: Groups.GSymbol
i::Int
j::Int
val::T
function ElementarySymplectic{N}(s::Symbol, i::Integer, j::Integer, val=1) where {N}
function ElementarySymplectic{N}(
s::Symbol,
i::Integer,
j::Integer,
val = 1,
) where {N}
@assert s (:A, :B)
@assert iseven(N)
n = N ÷ 2
@ -19,7 +24,7 @@ end
function Base.show(io::IO, s::ElementarySymplectic)
i, j = Groups.subscriptify(s.i), Groups.subscriptify(s.j)
print(io, s.symbol, i, j)
!isone(s.val) && print(io, "^$(s.val)")
return !isone(s.val) && print(io, "^$(s.val)")
end
_ind(s::ElementarySymplectic{N}) where {N} = (s.i, s.j)
@ -41,21 +46,27 @@ function _dual_ind(N_half, i, j)
return i, j
end
function Base.:(==)(s::ElementarySymplectic{N}, t::ElementarySymplectic{M}) where {N,M}
function Base.:(==)(
s::ElementarySymplectic{N},
t::ElementarySymplectic{M},
) where {N,M}
N == M || return false
s.symbol == t.symbol || return false
s.val == t.val || return false
return _ind(t) == _ind(s) || _ind(t) == _dual_ind(s)
end
Base.hash(s::ElementarySymplectic, h::UInt) =
hash(Set([_ind(s); _dual_ind(s)]), hash(s.symbol, hash(s.val, h)))
function Base.hash(s::ElementarySymplectic, h::UInt)
return hash(Set([_ind(s); _dual_ind(s)]), hash(s.symbol, hash(s.val, h)))
end
LinearAlgebra.transpose(s::ElementarySymplectic{N}) where {N} =
ElementarySymplectic{N}(s.symbol, s.j, s.i, s.val)
function LinearAlgebra.transpose(s::ElementarySymplectic{N}) where {N}
return ElementarySymplectic{N}(s.symbol, s.j, s.i, s.val)
end
Base.inv(s::ElementarySymplectic{N}) where {N} =
ElementarySymplectic{N}(s.symbol, s.i, s.j, -s.val)
function Base.inv(s::ElementarySymplectic{N}) where {N}
return ElementarySymplectic{N}(s.symbol, s.i, s.j, -s.val)
end
function matrix(s::ElementarySymplectic{N,T}) where {N,T}
@assert iseven(N)