diff --git a/src/AutGroup.jl b/src/AutGroup.jl index 1c9206a..2fd2185 100644 --- a/src/AutGroup.jl +++ b/src/AutGroup.jl @@ -297,24 +297,28 @@ function reduce!(w::Automorphism) return W end -function linear_repr(A::Automorphism{N}, hom=matrix_repr) where N - return reduce(*, linear_repr.(A.symbols, N, hom), init=hom(Identity(),N,1)) -end +############################################################################### +# +# Abelianization (natural Representation to GL(N,Z)) +# -linear_repr(a::AutSymbol, n::Int, hom) = hom(a.fn, n, a.pow) +abelianize(A::Automorphism{N}) where N = image(A, abelianize; n=N) -function matrix_repr(a::Union{RTransvect, LTransvect}, n::Int, pow) +# homomorphism definition +abelianize(; n::Integer=1) = Matrix{Int}(I, n, n) +abelianize(a::AutSymbol; n::Int=1) = abelianize(a.fn, n, a.pow) + +function abelianize(a::Union{RTransvect, LTransvect}, n::Int, pow) x = Matrix{Int}(I, n, n) x[a.i,a.j] = pow return x end -function matrix_repr(a::FlipAut, n::Int, pow) +function abelianize(a::FlipAut, n::Int, pow) x = Matrix{Int}(I, n, n) - x[a.i,a.i] = -1^pow + x[a.i,a.i] = -1 return x end -matrix_repr(a::PermAut, n::Int, pow) = Matrix{Int}(I, n, n)[(a.perm^pow).d, :] - -matrix_repr(a::Identity, n::Int, pow) = Matrix{Int}(I, n, n) +abelianize(a::PermAut, n::Integer, pow) = Matrix{Int}(I, n, n)[(a.perm^pow).d, :] +abelianize(a::Identity, n::Integer, pow) = abelianize(;n=n) diff --git a/src/Groups.jl b/src/Groups.jl index 443dd46..9dc67cb 100644 --- a/src/Groups.jl +++ b/src/Groups.jl @@ -13,6 +13,7 @@ import Base: deepcopy_internal using LinearAlgebra using Markdown +export gens, FreeGroup, Aut, SAut include("types.jl") @@ -89,4 +90,17 @@ function generate_balls(S::AbstractVector{T}, center::T=one(first(S)); return c.*B, sizes end +@doc doc""" + image(A::GWord, homomorphism; kwargs...) +Evaluate homomorphism `homomorphism` on a GWord `A`. +`homomorphism` needs implement + > `hom(s; kwargs...)`, +where `hom(;kwargs...)` evaluates the value at the identity element. +""" +function image(w::GWord, hom; kwargs...) + return reduce(*, + (hom(s; kwargs...) for s in syllables(w)), + init = hom(;kwargs...)) +end + end # of module Groups diff --git a/test/AutGroup-tests.jl b/test/AutGroup-tests.jl index 8699874..b4e5a63 100644 --- a/test/AutGroup-tests.jl +++ b/test/AutGroup-tests.jl @@ -9,7 +9,7 @@ @test isa(f, Groups.GSymbol) @test isa(f, Groups.AutSymbol) @test isa(Groups.AutSymbol(perm"(4)"), Groups.AutSymbol) - @test isa(Groups.AutSymbol([2,3,4,1]), Groups.AutSymbol) + @test isa(Groups.AutSymbol(perm"(1,2,3,4)"), Groups.AutSymbol) @test isa(Groups.transvection_R(1,2), Groups.AutSymbol) @test isa(Groups.transvection_R(3,4), Groups.AutSymbol) @test isa(Groups.flip(3), Groups.AutSymbol) @@ -205,48 +205,48 @@ @test length(unique(B_2)) == 1777 end - @testset "linear_repr tests" begin - N = 3 + @testset "abelianization homomorphism" begin + N = 4 G = AutGroup(FreeGroup(N)) S = unique([gens(G); inv.(gens(G))]) R = 3 - @test Groups.linear_repr(one(G)) isa Matrix{Int} - @test Groups.linear_repr(one(G)) == Matrix{Int}(I, N, N) + @test Groups.abelianize(one(G)) isa Matrix{Int} + @test Groups.abelianize(one(G)) == Matrix{Int}(I, N, N) M = Matrix{Int}(I, N, N) M[1,2] = 1 - ϱ₁₂ = G(Groups.transvection_R(1,2)) - λ₁₂ = G(Groups.transvection_R(1,2)) + ϱ₁₂ = G(Groups.ϱ(1,2)) + λ₁₂ = G(Groups.λ(1,2)) - @test Groups.linear_repr(ϱ₁₂) == M - @test Groups.linear_repr(λ₁₂) == M + @test Groups.abelianize(ϱ₁₂) == M + @test Groups.abelianize(λ₁₂) == M M[1,2] = -1 - @test Groups.linear_repr(ϱ₁₂^-1) == M - @test Groups.linear_repr(λ₁₂^-1) == M + @test Groups.abelianize(ϱ₁₂^-1) == M + @test Groups.abelianize(λ₁₂^-1) == M - @test Groups.linear_repr(ϱ₁₂*λ₁₂^-1) == Matrix{Int}(I, N, N) - @test Groups.linear_repr(λ₁₂^-1*ϱ₁₂) == Matrix{Int}(I, N, N) + @test Groups.abelianize(ϱ₁₂*λ₁₂^-1) == Matrix{Int}(I, N, N) + @test Groups.abelianize(λ₁₂^-1*ϱ₁₂) == Matrix{Int}(I, N, N) M = Matrix{Int}(I, N, N) M[2,2] = -1 ε₂ = G(Groups.flip(2)) - @test Groups.linear_repr(ε₂) == M - @test Groups.linear_repr(ε₂^2) == Matrix{Int}(I, N, N) + @test Groups.abelianize(ε₂) == M + @test Groups.abelianize(ε₂^2) == Matrix{Int}(I, N, N) - M = [0 1 0; 0 0 1; 1 0 0] + M = [0 1 0 0; 0 0 0 1; 0 0 1 0; 1 0 0 0] - σ = G(Groups.AutSymbol(perm"(1,2,3)")) - @test Groups.linear_repr(σ) == M - @test Groups.linear_repr(σ^3) == Matrix{Int}(I, 3, 3) - @test Groups.linear_repr(σ)^3 == Matrix{Int}(I, 3, 3) + σ = G(Groups.AutSymbol(perm"(1,2,4)")) + @test Groups.abelianize(σ) == M + @test Groups.abelianize(σ^3) == Matrix{Int}(I, N, N) + @test Groups.abelianize(σ)^3 == Matrix{Int}(I, N, N) function test_homomorphism(S, r) for elts in Iterators.product([[g for g in S] for _ in 1:r]...) - prod(Groups.linear_repr.(elts)) == Groups.linear_repr(prod(elts)) || error("linear representaton test failed at $elts") + prod(Groups.abelianize.(elts)) == Groups.abelianize(prod(elts)) || error("linear representaton test failed at $elts") end return 0 end