mirror of
https://github.com/kalmarek/Groups.jl.git
synced 2025-01-09 13:32:33 +01:00
format MatrixGroups module
This commit is contained in:
parent
a0d2186477
commit
29af9659d9
@ -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}
|
function Base.show(io::IO, ::MIME"text/plain", ::SymplecticGroup{N}) where {N}
|
||||||
return print(io, "group of $N×$N symplectic matrices")
|
return print(io, "group of $N×$N symplectic matrices")
|
||||||
end
|
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!"))
|
iseven(N) || throw(ArgumentError("N needs to be even!"))
|
||||||
n = N ÷ 2
|
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]
|
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]
|
S = [a_ijs; b_is; c_ijs]
|
||||||
|
|
||||||
@ -49,11 +55,16 @@ function _std_symplectic_form(m::AbstractMatrix)
|
|||||||
n = r ÷ 2
|
n = r ÷ 2
|
||||||
𝕆 = zeros(eltype(m), n, n)
|
𝕆 = zeros(eltype(m), n, n)
|
||||||
𝕀 = one(eltype(m)) * LinearAlgebra.I
|
𝕀 = one(eltype(m)) * LinearAlgebra.I
|
||||||
Ω = [𝕆 -𝕀
|
Ω = [
|
||||||
𝕀 𝕆]
|
𝕆 -𝕀
|
||||||
|
𝕀 𝕆
|
||||||
|
]
|
||||||
return Ω
|
return Ω
|
||||||
end
|
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
|
return Ω == transpose(mat) * Ω * mat
|
||||||
end
|
end
|
||||||
|
@ -1,26 +1,31 @@
|
|||||||
abstract type AbstractMatrixGroup{N,T} <: Groups.AbstractFPGroup end
|
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} =
|
function Base.isone(g::MatrixGroupElement{N,T}) where {N,T}
|
||||||
isone(word(g)) || isone(matrix(g))
|
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
|
parent(m1) === parent(m2) || return false
|
||||||
word(m1) == word(m2) && return true
|
word(m1) == word(m2) && return true
|
||||||
return matrix(m1) == matrix(m2)
|
return matrix(m1) == matrix(m2)
|
||||||
end
|
end
|
||||||
|
|
||||||
Base.size(m::MatrixGroupElement{N}) where {N} = (N, N)
|
Base.size(::MatrixGroupElement{N}) where {N} = (N, N)
|
||||||
Base.eltype(m::MatrixGroupElement{N,T}) where {N,T} = T
|
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
|
# three structural assumptions about matrix groups
|
||||||
Groups.word(sl::MatrixGroupElement) = sl.word
|
Groups.word(m::MatrixGroupElement) = m.word
|
||||||
Base.parent(sl::MatrixGroupElement) = sl.parent
|
Base.parent(m::MatrixGroupElement) = m.parent
|
||||||
Groups.alphabet(M::MatrixGroup) = M.alphabet
|
Groups.alphabet(M::AbstractMatrixGroup) = M.alphabet
|
||||||
Groups.rewriting(M::MatrixGroup) = alphabet(M)
|
Groups.rewriting(M::AbstractMatrixGroup) = alphabet(M)
|
||||||
|
|
||||||
Base.hash(m::MatrixGroupElement, h::UInt) =
|
Base.hash(m::MatrixGroupElement, h::UInt) = hash(matrix(m), hash(parent(m), h))
|
||||||
hash(matrix(m), hash(parent(m), h))
|
|
||||||
|
|
||||||
function matrix(m::MatrixGroupElement{N,T}) where {N,T}
|
function matrix(m::MatrixGroupElement{N,T}) where {N,T}
|
||||||
if isone(word(m))
|
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))
|
return prod(matrix(A[l]) for l in word(m))
|
||||||
end
|
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(
|
function Base.rand(
|
||||||
rng::Random.AbstractRNG,
|
rng::Random.AbstractRNG,
|
||||||
rs::Random.SamplerTrivial{<:AbstractMatrixGroup},
|
rs::Random.SamplerTrivial{<:AbstractMatrixGroup},
|
||||||
)
|
)
|
||||||
Mgroup = rs[]
|
Mgroup = rs[]
|
||||||
S = gens(Mgroup)
|
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
|
end
|
||||||
|
|
||||||
function Base.show(io::IO, M::AbstractMatrixGroup)
|
function Base.show(io::IO, M::AbstractMatrixGroup)
|
||||||
g = gens(M, 1)
|
g = gens(M, 1)
|
||||||
N = size(g, 1)
|
N = size(g, 1)
|
||||||
print(io, "H ⩽ GL{$N,$(eltype(g))}")
|
return print(io, "H ⩽ GL{$N,$(eltype(g))}")
|
||||||
end
|
end
|
||||||
|
|
||||||
function Base.show(io::IO, ::MIME"text/plain", M::AbstractMatrixGroup)
|
function Base.show(io::IO, ::MIME"text/plain", M::AbstractMatrixGroup)
|
||||||
N = size(gens(M, 1), 1)
|
N = size(gens(M, 1), 1)
|
||||||
ng = GroupsCore.ngens(M)
|
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
|
end
|
||||||
|
|
||||||
Base.show(io::IO, mat::Groups.AbstractFPGroupElement{<:AbstractMatrixGroup}) =
|
function Base.show(
|
||||||
KnuthBendix.print_repr(io, word(mat), alphabet(mat))
|
io::IO,
|
||||||
|
mat::Groups.AbstractFPGroupElement{<:AbstractMatrixGroup},
|
||||||
|
)
|
||||||
|
return KnuthBendix.print_repr(io, word(mat), alphabet(mat))
|
||||||
|
end
|
||||||
|
|
||||||
function Base.show(
|
function Base.show(
|
||||||
io::IO,
|
io::IO,
|
||||||
::MIME"text/plain",
|
::MIME"text/plain",
|
||||||
mat::Groups.AbstractFPGroupElement{<:AbstractMatrixGroup{N}}
|
mat::Groups.AbstractFPGroupElement{<:AbstractMatrixGroup{N}},
|
||||||
) where {N}
|
) where {N}
|
||||||
Groups.normalform!(mat)
|
Groups.normalform!(mat)
|
||||||
KnuthBendix.print_repr(io, word(mat), alphabet(mat))
|
KnuthBendix.print_repr(io, word(mat), alphabet(mat))
|
||||||
println(io, " ∈ ", parent(mat))
|
println(io, " ∈ ", parent(mat))
|
||||||
Base.print_array(io, matrix(mat))
|
return Base.print_array(io, matrix(mat))
|
||||||
end
|
end
|
||||||
|
@ -2,23 +2,27 @@ struct ElementaryMatrix{N,T} <: Groups.GSymbol
|
|||||||
i::Int
|
i::Int
|
||||||
j::Int
|
j::Int
|
||||||
val::T
|
val::T
|
||||||
ElementaryMatrix{N}(i, j, val=1) where {N} =
|
function ElementaryMatrix{N}(i, j, val = 1) where {N}
|
||||||
(@assert i ≠ j; new{N,typeof(val)}(i, j, val))
|
return (@assert i ≠ j; new{N,typeof(val)}(i, j, val))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Base.show(io::IO, e::ElementaryMatrix)
|
function Base.show(io::IO, e::ElementaryMatrix)
|
||||||
print(io, 'E', Groups.subscriptify(e.i), Groups.subscriptify(e.j))
|
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
|
end
|
||||||
|
|
||||||
Base.:(==)(e::ElementaryMatrix{N}, f::ElementaryMatrix{N}) where {N} =
|
function Base.:(==)(e::ElementaryMatrix{N}, f::ElementaryMatrix{N}) where {N}
|
||||||
e.i == f.i && e.j == f.j && e.val == f.val
|
return e.i == f.i && e.j == f.j && e.val == f.val
|
||||||
|
end
|
||||||
|
|
||||||
Base.hash(e::ElementaryMatrix, h::UInt) =
|
function Base.hash(e::ElementaryMatrix, h::UInt)
|
||||||
hash(typeof(e), hash((e.i, e.j, e.val), h))
|
return hash(typeof(e), hash((e.i, e.j, e.val), h))
|
||||||
|
end
|
||||||
|
|
||||||
Base.inv(e::ElementaryMatrix{N}) where {N} =
|
function Base.inv(e::ElementaryMatrix{N}) where {N}
|
||||||
ElementaryMatrix{N}(e.i, e.j, -e.val)
|
return ElementaryMatrix{N}(e.i, e.j, -e.val)
|
||||||
|
end
|
||||||
|
|
||||||
function matrix(e::ElementaryMatrix{N,T}) where {N,T}
|
function matrix(e::ElementaryMatrix{N,T}) where {N,T}
|
||||||
m = StaticArrays.MMatrix{N,N,T}(LinearAlgebra.I)
|
m = StaticArrays.MMatrix{N,N,T}(LinearAlgebra.I)
|
||||||
|
@ -3,7 +3,12 @@ struct ElementarySymplectic{N,T} <: Groups.GSymbol
|
|||||||
i::Int
|
i::Int
|
||||||
j::Int
|
j::Int
|
||||||
val::T
|
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 s ∈ (:A, :B)
|
||||||
@assert iseven(N)
|
@assert iseven(N)
|
||||||
n = N ÷ 2
|
n = N ÷ 2
|
||||||
@ -19,7 +24,7 @@ end
|
|||||||
function Base.show(io::IO, s::ElementarySymplectic)
|
function Base.show(io::IO, s::ElementarySymplectic)
|
||||||
i, j = Groups.subscriptify(s.i), Groups.subscriptify(s.j)
|
i, j = Groups.subscriptify(s.i), Groups.subscriptify(s.j)
|
||||||
print(io, s.symbol, i, j)
|
print(io, s.symbol, i, j)
|
||||||
!isone(s.val) && print(io, "^$(s.val)")
|
return !isone(s.val) && print(io, "^$(s.val)")
|
||||||
end
|
end
|
||||||
|
|
||||||
_ind(s::ElementarySymplectic{N}) where {N} = (s.i, s.j)
|
_ind(s::ElementarySymplectic{N}) where {N} = (s.i, s.j)
|
||||||
@ -41,21 +46,27 @@ function _dual_ind(N_half, i, j)
|
|||||||
return i, j
|
return i, j
|
||||||
end
|
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
|
N == M || return false
|
||||||
s.symbol == t.symbol || return false
|
s.symbol == t.symbol || return false
|
||||||
s.val == t.val || return false
|
s.val == t.val || return false
|
||||||
return _ind(t) == _ind(s) || _ind(t) == _dual_ind(s)
|
return _ind(t) == _ind(s) || _ind(t) == _dual_ind(s)
|
||||||
end
|
end
|
||||||
|
|
||||||
Base.hash(s::ElementarySymplectic, h::UInt) =
|
function Base.hash(s::ElementarySymplectic, h::UInt)
|
||||||
hash(Set([_ind(s); _dual_ind(s)]), hash(s.symbol, hash(s.val, h)))
|
return hash(Set([_ind(s); _dual_ind(s)]), hash(s.symbol, hash(s.val, h)))
|
||||||
|
end
|
||||||
|
|
||||||
LinearAlgebra.transpose(s::ElementarySymplectic{N}) where {N} =
|
function LinearAlgebra.transpose(s::ElementarySymplectic{N}) where {N}
|
||||||
ElementarySymplectic{N}(s.symbol, s.j, s.i, s.val)
|
return ElementarySymplectic{N}(s.symbol, s.j, s.i, s.val)
|
||||||
|
end
|
||||||
|
|
||||||
Base.inv(s::ElementarySymplectic{N}) where {N} =
|
function Base.inv(s::ElementarySymplectic{N}) where {N}
|
||||||
ElementarySymplectic{N}(s.symbol, s.i, s.j, -s.val)
|
return ElementarySymplectic{N}(s.symbol, s.i, s.j, -s.val)
|
||||||
|
end
|
||||||
|
|
||||||
function matrix(s::ElementarySymplectic{N,T}) where {N,T}
|
function matrix(s::ElementarySymplectic{N,T}) where {N,T}
|
||||||
@assert iseven(N)
|
@assert iseven(N)
|
||||||
|
Loading…
Reference in New Issue
Block a user