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:
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}
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user