mirror of
https://github.com/kalmarek/Groups.jl.git
synced 2024-11-19 06:30:29 +01:00
add tests for automorphisms and iteration benchmarks
This commit is contained in:
parent
1c7f0a5f01
commit
c0c688ed2d
@ -20,6 +20,7 @@ julia = "1.3, 1.4, 1.5"
|
||||
|
||||
[extras]
|
||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
|
||||
|
||||
[targets]
|
||||
test = ["Test"]
|
||||
test = ["Test", "BenchmarkTools"]
|
||||
|
184
test/automorphisms.jl
Normal file
184
test/automorphisms.jl
Normal file
@ -0,0 +1,184 @@
|
||||
@testset "Automorphisms" begin
|
||||
|
||||
@testset "Transvections" begin
|
||||
|
||||
@test New.Transvection(:ϱ, 1, 2) isa New.GSymbol
|
||||
@test New.Transvection(:ϱ, 1, 2) isa New.Transvection
|
||||
@test New.Transvection(:λ, 1, 2) isa New.GSymbol
|
||||
@test New.Transvection(:λ, 1, 2) isa New.Transvection
|
||||
t = New.Transvection(:ϱ, 1, 2)
|
||||
@test inv(t) isa New.GSymbol
|
||||
@test inv(t) isa New.Transvection
|
||||
|
||||
@test t != inv(t)
|
||||
|
||||
s = New.Transvection(:ϱ, 1, 2)
|
||||
@test t == s
|
||||
@test hash(t) == hash(s)
|
||||
|
||||
s_ = New.Transvection(:ϱ, 1, 3)
|
||||
@test s_ != s
|
||||
@test hash(s_) != hash(s)
|
||||
|
||||
@test New.gersten_alphabet(3) isa Alphabet
|
||||
A = New.gersten_alphabet(3)
|
||||
@test length(A) == 12
|
||||
end
|
||||
|
||||
A4 = Alphabet(
|
||||
[:a,:A,:b,:B,:c,:C,:d,:D],
|
||||
[ 2, 1, 4, 3, 6, 5, 8, 7]
|
||||
)
|
||||
|
||||
A5 = Alphabet(
|
||||
[:a,:A,:b,:B,:c,:C,:d,:D,:e,:E],
|
||||
[ 2, 1, 4, 3, 6, 5, 8, 7,10, 9]
|
||||
)
|
||||
|
||||
F4 = New.FreeGroup([:a, :b, :c, :d], A4)
|
||||
A = New.SpecialAutomorphismGroup(F4, maxrules=1000)
|
||||
|
||||
a,b,c,d = gens(F4)
|
||||
D = ntuple(i->gens(F4, i), 4)
|
||||
|
||||
@testset "Transvection action correctness" begin
|
||||
i,j = 1,2
|
||||
r = New.Transvection(:ϱ,i,j)
|
||||
l = New.Transvection(:λ,i,j)
|
||||
|
||||
(t::New.Transvection)(v::Tuple) = New.evaluate!(v, t, A4)
|
||||
|
||||
@test r(deepcopy(D)) == (a*b, b, c, d)
|
||||
@test inv(r)(deepcopy(D)) == (a*b^-1,b, c, d)
|
||||
@test l(deepcopy(D)) == (b*a, b, c, d)
|
||||
@test inv(l)(deepcopy(D)) == (b^-1*a,b, c, d)
|
||||
|
||||
i,j = 3,1
|
||||
r = New.Transvection(:ϱ,i,j)
|
||||
l = New.Transvection(:λ,i,j)
|
||||
@test r(deepcopy(D)) == (a, b, c*a, d)
|
||||
@test inv(r)(deepcopy(D)) == (a, b, c*a^-1,d)
|
||||
@test l(deepcopy(D)) == (a, b, a*c, d)
|
||||
@test inv(l)(deepcopy(D)) == (a, b, a^-1*c,d)
|
||||
|
||||
i,j = 4,3
|
||||
r = New.Transvection(:ϱ,i,j)
|
||||
l = New.Transvection(:λ,i,j)
|
||||
@test r(deepcopy(D)) == (a, b, c, d*c)
|
||||
@test inv(r)(deepcopy(D)) == (a, b, c, d*c^-1)
|
||||
@test l(deepcopy(D)) == (a, b, c, c*d)
|
||||
@test inv(l)(deepcopy(D)) == (a, b, c, c^-1*d)
|
||||
|
||||
i,j = 2,4
|
||||
r = New.Transvection(:ϱ,i,j)
|
||||
l = New.Transvection(:λ,i,j)
|
||||
@test r(deepcopy(D)) == (a, b*d, c, d)
|
||||
@test inv(r)(deepcopy(D)) == (a, b*d^-1,c, d)
|
||||
@test l(deepcopy(D)) == (a, d*b, c, d)
|
||||
@test inv(l)(deepcopy(D)) == (a, d^-1*b,c, d)
|
||||
end
|
||||
|
||||
@testset "AutomorphismGroup constructors" begin
|
||||
@test A isa New.AbstractFPGroup
|
||||
@test A isa New.AutomorphismGroup
|
||||
@test KnuthBendix.alphabet(A) isa Alphabet
|
||||
@test New.relations(A) isa Vector{<:Pair}
|
||||
|
||||
end
|
||||
|
||||
@testset "Automorphisms: hash and evaluate" begin
|
||||
@test New.domain(gens(A, 1)) == D
|
||||
g, h = gens(A, 1), gens(A, 8)
|
||||
|
||||
@test New.evaluate(g*h) == New.evaluate(h*g)
|
||||
@test (g*h).savedhash == zero(UInt)
|
||||
|
||||
a = g*h
|
||||
b = h*g
|
||||
@test hash(a) != zero(UInt)
|
||||
@test hash(a) == hash(b)
|
||||
@test a.savedhash == b.savedhash
|
||||
|
||||
@test length(unique([a,b])) == 1
|
||||
@test length(unique([g*h, h*g])) == 1
|
||||
|
||||
# Not so simple arithmetic: applying starting on the left:
|
||||
# ϱ₁₂*ϱ₂₁⁻¹*λ₁₂*ε₂ == σ₂₁₃₄
|
||||
|
||||
g = gens(A, 1)
|
||||
x1, x2, x3, x4 = New.domain(g)
|
||||
@test New.evaluate(g) == (x1*x2, x2, x3, x4)
|
||||
|
||||
g = g*inv(gens(A, 4)) # ϱ₂₁
|
||||
@test New.evaluate(g) == (x1*x2, x1^-1, x3, x4)
|
||||
|
||||
g = g*gens(A, 13)
|
||||
@test New.evaluate(g) == (x2, x1^-1, x3, x4)
|
||||
end
|
||||
|
||||
@testset "Automorphisms: SAut(F₄)" begin
|
||||
N = 4
|
||||
G = New.SpecialAutomorphismGroup(New.FreeGroup(N))
|
||||
|
||||
S = gens(G)
|
||||
@test S isa Vector{<:New.FPGroupElement{<:New.AutomorphismGroup{<:New.FreeGroup}}}
|
||||
|
||||
@test length(S) == 2*N*(N-1)
|
||||
@test length(unique(S)) == length(S)
|
||||
|
||||
S_sym = [S; inv.(S)]
|
||||
@test length(S_sym) == length(unique(S_sym))
|
||||
|
||||
pushfirst!(S_sym, one(G))
|
||||
|
||||
B_2 = [i*j for (i,j) in Base.product(S_sym, S_sym)]
|
||||
@test length(B_2) == 2401
|
||||
@test length(unique(B_2)) == 1777
|
||||
|
||||
@test all(g->isone(inv(g)*g), B_2)
|
||||
@test all(g->isone(g*inv(g)), B_2)
|
||||
end
|
||||
|
||||
@testset "GroupsCore conformance" begin
|
||||
test_Group_interface(A)
|
||||
g = A(rand(1:length(KnuthBendix.alphabet(A)), 10))
|
||||
h = A(rand(1:length(KnuthBendix.alphabet(A)), 10))
|
||||
|
||||
test_GroupElement_interface(g, h)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# using Random
|
||||
# using GroupsCore
|
||||
#
|
||||
# A = New.SpecialAutomorphismGroup(New.FreeGroup(4), maxrules=2000, ordering=KnuthBendix.RecursivePathOrder)
|
||||
#
|
||||
# # for seed in 1:1000
|
||||
# let seed = 68
|
||||
# N = 14
|
||||
# Random.seed!(seed)
|
||||
# g = A(rand(1:length(KnuthBendix.alphabet(A)), N))
|
||||
# h = A(rand(1:length(KnuthBendix.alphabet(A)), N))
|
||||
# @info "seed=$seed" g h
|
||||
# @time isone(g*inv(g))
|
||||
# @time isone(inv(g)*g)
|
||||
# @info "" length(New.word(New.normalform!(g*inv(g)))) length(New.word(New.normalform!(inv(g)*g)))
|
||||
# a = commutator(g, h, g)
|
||||
# b = conj(inv(g), h) * conj(conj(g, h), g)
|
||||
#
|
||||
# @info length(New.word(a))
|
||||
# @info length(New.word(b))
|
||||
#
|
||||
# w = a*inv(b)
|
||||
# @info length(New.word(w))
|
||||
# New.normalform!(w)
|
||||
# @info length(New.word(w))
|
||||
#
|
||||
#
|
||||
# #
|
||||
# # @time ima = New.evaluate(a)
|
||||
# # @time imb = New.evaluate(b)
|
||||
# # @info "" a b ima imb
|
||||
# # @time a == b
|
||||
# end
|
72
test/benchmarks.jl
Normal file
72
test/benchmarks.jl
Normal file
@ -0,0 +1,72 @@
|
||||
using BenchmarkTools
|
||||
using Test
|
||||
|
||||
using Groups
|
||||
using Groups.New
|
||||
|
||||
function wl_ball(F; radius::Integer)
|
||||
g, state = iterate(F)
|
||||
while length(New.word(g)) <= radius
|
||||
res = iterate(F, state)
|
||||
isnothing(res) && break
|
||||
g, state = res
|
||||
end
|
||||
elts = collect(state.seen)
|
||||
elts = resize!(elts, length(elts)-1)
|
||||
return elts
|
||||
end
|
||||
|
||||
@testset "Benchmarks" begin
|
||||
N = 4
|
||||
|
||||
@testset "iteration: FreeGroup" begin
|
||||
FN = New.FreeGroup(N)
|
||||
R = 8
|
||||
|
||||
let G = FN
|
||||
S = unique([gens(G); inv.(gens(G))])
|
||||
|
||||
sizes1 = last(Groups.wlmetric_ball(S, radius=R, threading=false))
|
||||
sizes2 = last(Groups.wlmetric_ball(S, radius=R, threading=true))
|
||||
|
||||
l = length(wl_ball(G, radius=R))
|
||||
|
||||
@test sizes1 == sizes2
|
||||
@test last(sizes1) == l
|
||||
|
||||
@info "Ball of radius $R in $(parent(first(S)))" sizes=sizes1
|
||||
@info "serial"
|
||||
@time Groups.wlmetric_ball(S, radius=R, threading=false)
|
||||
@info "threaded"
|
||||
@time Groups.wlmetric_ball(S, radius=R, threading=true)
|
||||
@info "iteration"
|
||||
@time wl_ball(G, radius=R)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "iteration: SAut(F_n)" begin
|
||||
R = 4
|
||||
FN = New.FreeGroup(N)
|
||||
SAutFN = New.SpecialAutomorphismGroup(FN)
|
||||
|
||||
let G = SAutFN
|
||||
S = unique([gens(G); inv.(gens(G))])
|
||||
|
||||
sizes1 = last(Groups.wlmetric_ball(S, radius=R, threading=false))
|
||||
sizes2 = last(Groups.wlmetric_ball(S, radius=R, threading=true))
|
||||
|
||||
l = length(wl_ball(G, radius=R))
|
||||
|
||||
@test sizes1 == sizes2
|
||||
@test last(sizes1) == l
|
||||
|
||||
@info "Ball of radius $R in $(parent(first(S)))" sizes=sizes1
|
||||
@info "serial"
|
||||
@time Groups.wlmetric_ball(S, radius=R, threading=false)
|
||||
@info "threaded"
|
||||
@time Groups.wlmetric_ball(S, radius=R, threading=true)
|
||||
@info "iteration"
|
||||
@time wl_ball(G, radius=R)
|
||||
end
|
||||
end
|
||||
end
|
@ -33,12 +33,11 @@
|
||||
return w
|
||||
end
|
||||
|
||||
@time k = test_iteration(F3, 10)
|
||||
k = test_iteration(F3, 10)
|
||||
@test k == a*b^-1
|
||||
|
||||
k = test_iteration(F3, 1000)
|
||||
@test k == (a^2)*c^2*a^-1
|
||||
@time k = test_iteration(F3, 1000)
|
||||
@test k == (a^2)*c^2*a^-1
|
||||
end
|
||||
|
||||
@testset "wl_ball" begin
|
||||
@ -58,9 +57,10 @@
|
||||
@test length(E4) == 937
|
||||
@test New.word(last(E4)) == Word([6])^4
|
||||
|
||||
@time E8 = wl_ball(F3, radius=8)
|
||||
E8, t, _ = @timed wl_ball(F3, radius=8)
|
||||
@test length(E8) == 585937
|
||||
@test New.word(last(E8)) == Word([6])^8
|
||||
@test t/10^9 < 1
|
||||
end
|
||||
|
||||
@testset "GroupsCore conformance" begin
|
||||
|
@ -33,5 +33,7 @@ using LinearAlgebra
|
||||
|
||||
include("free_groups.jl")
|
||||
include("fp_groups.jl")
|
||||
include("automorphisms.jl")
|
||||
include("benchmarks.jl")
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user