diff --git a/src/abelianize.jl b/src/abelianize.jl index b62595b..e059feb 100644 --- a/src/abelianize.jl +++ b/src/abelianize.jl @@ -21,3 +21,49 @@ function _abelianize( end end +function _abelianize( + i::Integer, + source::AutomorphismGroup{<:Groups.SurfaceGroup}, + target::MatrixGroups.SpecialLinearGroup{N, T}) where {N, T} + n = ngens(Groups.object(source)) + @assert n == N + g = alphabet(source)[i].autFn_word + result = one(target) + for l in word(g) + append!(word(result), _abelianize(l, parent(g), target)) + end + + return word(result) +end + +function Groups._abelianize( + i::Integer, + source::AutomorphismGroup{<:Groups.SurfaceGroup}, + target::MatrixGroups.SymplecticGroup{N, T} +) where {N, T} + @assert iseven(N) + As = alphabet(source) + At = alphabet(target) + + SlN = let genus = Groups.genus(Groups.object(source)) + @assert 2genus == N + MatrixGroups.SpecialLinearGroup{2genus}(T) + end + + ab = Groups.Homomorphism(Groups._abelianize, source, SlN, check=false) + + matrix_spn_map = let S = gens(target) + Dict(MatrixGroups.matrix_repr(g)=> word(g) for g in union(S, inv.(S))) + end + + # renumeration: + # (f1, f2, f3, f4, f5, f6) = (a₁, a₂, a₃, b₁, b₂, b₃) → + # → (b₃, a₃, b₂, a₂, b₁, a₁) + # hence p = [6, 4, 2, 5, 3, 1] + p = [reverse(2:2:N); reverse(1:2:N)] + + g = source([i]) + Mg = MatrixGroups.matrix_repr(ab(g))[p,p] + + return matrix_spn_map[Mg] +end diff --git a/src/matrix_groups/Spn.jl b/src/matrix_groups/Spn.jl index 66e658c..630a56a 100644 --- a/src/matrix_groups/Spn.jl +++ b/src/matrix_groups/Spn.jl @@ -28,19 +28,22 @@ function Base.show( ::MIME"text/plain", sp::Groups.AbstractFPGroupElement{<:SymplecticGroup{N}} ) where {N} + normalform!(sp) print(io, "$N×$N Symplectic matrix: ") KnuthBendix.print_repr(io, word(sp), alphabet(sp)) println(io) Base.print_array(io, matrix_repr(sp)) 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) 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 offdiagonal_indexing(n)] + 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 offdiagonal_indexing(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] diff --git a/test/homomorphisms.jl b/test/homomorphisms.jl index 8419b73..97f4736 100644 --- a/test/homomorphisms.jl +++ b/test/homomorphisms.jl @@ -2,8 +2,12 @@ function test_homomorphism(hom) F = hom.source @test isone(hom(one(F))) @test all(inv(hom(g)) == hom(inv(g)) for g in gens(F)) - @test all(isone(hom(g)*hom(inv(g))) for g in gens(F)) - @test all(hom(g*h) == hom(g)*hom(h) for g in gens(F) for h in gens(F)) + @test all(isone(hom(g) * hom(inv(g))) for g in gens(F)) + @test all(hom(g * h) == hom(g) * hom(h) for g in gens(F) for h in gens(F)) + @test all( + hom(inv(g * h)) == inv(hom(g * h)) == hom(inv(h)) * hom(inv(g)) for + g in gens(F) for h in gens(F) + ) end @testset "Homomorphisms" begin @@ -46,4 +50,22 @@ end test_homomorphism(hom) end + + @testset "Correctness of autπ₁Σ → SpN" begin + + GENUS = 3 + π₁Σ = Groups.SurfaceGroup(GENUS, 0) + autπ₁Σ = AutomorphismGroup(π₁Σ) + + SpN = MatrixGroups.SymplecticGroup{2GENUS}(Int8) + + hom = Groups.Homomorphism( + Groups._abelianize, + autπ₁Σ, + SpN, + check = false, + ) + + test_homomorphism(hom) + end end diff --git a/test/matrix_groups.jl b/test/matrix_groups.jl index fb13d6f..92555b2 100644 --- a/test/matrix_groups.jl +++ b/test/matrix_groups.jl @@ -33,4 +33,16 @@ using Groups.MatrixGroups end end end + + @testset "Sp(6, ℤ)" begin + Sp6 = MatrixGroups.SymplecticGroup{6}(Int8) + + @testset "GroupsCore conformance" begin + test_Group_interface(Sp6) + g = Sp6(rand(1:length(alphabet(Sp6)), 10)) + h = Sp6(rand(1:length(alphabet(Sp6)), 10)) + + test_GroupElement_interface(g, h) + end + end end