diff --git a/src/matrix_groups/Spn.jl b/src/matrix_groups/Spn.jl index 2361050..7bcfbce 100644 --- a/src/matrix_groups/Spn.jl +++ b/src/matrix_groups/Spn.jl @@ -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 diff --git a/src/matrix_groups/abstract.jl b/src/matrix_groups/abstract.jl index 3caca2c..ac2b625 100644 --- a/src/matrix_groups/abstract.jl +++ b/src/matrix_groups/abstract.jl @@ -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 diff --git a/src/matrix_groups/eltary_matrices.jl b/src/matrix_groups/eltary_matrices.jl index 42b582d..8181b11 100644 --- a/src/matrix_groups/eltary_matrices.jl +++ b/src/matrix_groups/eltary_matrices.jl @@ -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) diff --git a/src/matrix_groups/eltary_symplectic.jl b/src/matrix_groups/eltary_symplectic.jl index 91ab941..1f70a5c 100644 --- a/src/matrix_groups/eltary_symplectic.jl +++ b/src/matrix_groups/eltary_symplectic.jl @@ -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)