mirror of
https://github.com/kalmarek/Groups.jl.git
synced 2024-12-25 02:05:30 +01:00
add code for forward evaluation
This commit is contained in:
parent
0c60dce731
commit
a742bf32ec
@ -115,3 +115,61 @@ function evaluate!(
|
|||||||
end
|
end
|
||||||
|
|
||||||
evaluate!(t::NTuple{N, T}, s::GSymbol, A, tmp=one(first(t))) where {N, T} = throw("you need to implement `evaluate!(::$(typeof(t)), ::$(typeof(s)), ::Alphabet, tmp=one(first(t)))`")
|
evaluate!(t::NTuple{N, T}, s::GSymbol, A, tmp=one(first(t))) where {N, T} = throw("you need to implement `evaluate!(::$(typeof(t)), ::$(typeof(s)), ::Alphabet, tmp=one(first(t)))`")
|
||||||
|
|
||||||
|
# forward evaluate by substitution
|
||||||
|
|
||||||
|
struct LettersMap{T, A}
|
||||||
|
indices_map::Dict{Int, T}
|
||||||
|
A::A
|
||||||
|
end
|
||||||
|
|
||||||
|
function LettersMap(a::FPGroupElement{<:AutomorphismGroup})
|
||||||
|
dom = domain(a)
|
||||||
|
@assert all(isone ∘ length ∘ word, dom)
|
||||||
|
A = alphabet(first(dom))
|
||||||
|
first_letters = first.(word.(dom))
|
||||||
|
img = evaluate!(dom, a)
|
||||||
|
|
||||||
|
# (dom[i] → img[i] is a map from domain to images)
|
||||||
|
# we need a map from alphabet indices → (gens, gens⁻¹) → images
|
||||||
|
# here we do it for elements of the domai
|
||||||
|
# (trusting it's a set of generators that define a)
|
||||||
|
@assert length(dom) == length(img)
|
||||||
|
|
||||||
|
indices_map = Dict(A[A[fl]] => word(im) for (fl, im) in zip(first_letters, img))
|
||||||
|
# inverses of generators are dealt lazily in getindex
|
||||||
|
|
||||||
|
return LettersMap(indices_map, A)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function Base.getindex(lm::LettersMap, i::Integer)
|
||||||
|
# here i is an index of an alphabet
|
||||||
|
@boundscheck 1 ≤ i ≤ length(KnuthBendix.letters(lm.A))
|
||||||
|
|
||||||
|
if !haskey(lm.indices_map, i)
|
||||||
|
img = if haskey(lm.indices_map, inv(lm.A, i))
|
||||||
|
inv(lm.A, lm.indices_map[inv(lm.A, i)])
|
||||||
|
else
|
||||||
|
@warn "LetterMap: neither $i nor its inverse has assigned value"
|
||||||
|
one(valtype(lm.indices_map))
|
||||||
|
end
|
||||||
|
lm.indices_map[i] = img
|
||||||
|
end
|
||||||
|
return lm.indices_map[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
function (a::FPGroupElement{<:AutomorphismGroup})(g::FPGroupElement)
|
||||||
|
@assert object(parent(a)) === parent(g)
|
||||||
|
img_w = evaluate(word(g), LettersMap(a))
|
||||||
|
return parent(g)(img_w)
|
||||||
|
end
|
||||||
|
|
||||||
|
evaluate(w::AbstractWord, lm::LettersMap) = evaluate!(one(w), w, lm)
|
||||||
|
|
||||||
|
function evaluate!(res::AbstractWord, w::AbstractWord, lm::LettersMap)
|
||||||
|
for i in w
|
||||||
|
append!(res, lm[i])
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
@ -144,6 +144,36 @@
|
|||||||
@test all(g->isone(g*inv(g)), B_2)
|
@test all(g->isone(g*inv(g)), B_2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@testset "Forward evaluate" begin
|
||||||
|
N = 3
|
||||||
|
F = FreeGroup(N)
|
||||||
|
G = SpecialAutomorphismGroup(F)
|
||||||
|
|
||||||
|
a = gens(G, 1) # ϱ₁₂
|
||||||
|
|
||||||
|
f = gens(F)
|
||||||
|
|
||||||
|
@test a(f[1]) == f[1]*f[2]
|
||||||
|
@test all(a(f[i]) == f[i] for i in 2:length(f))
|
||||||
|
|
||||||
|
S = let s = gens(G)
|
||||||
|
[s; inv.(s)]
|
||||||
|
end
|
||||||
|
|
||||||
|
@test all(
|
||||||
|
map(first(Groups.wlmetric_ball(S, radius=2))) do g
|
||||||
|
lm = Groups.LettersMap(g)
|
||||||
|
img = evaluate(g)
|
||||||
|
|
||||||
|
fimg = [F(lm[first(word(s))]) for s in gens(F)]
|
||||||
|
|
||||||
|
succeeded = all(img .== fimg)
|
||||||
|
@assert succeeded "forward evaluation of $(word(g)) failed: \n img=$img\n fimg=$(tuple(fimg...))"
|
||||||
|
succeeded
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
@testset "GroupsCore conformance" begin
|
@testset "GroupsCore conformance" begin
|
||||||
test_Group_interface(A)
|
test_Group_interface(A)
|
||||||
g = A(rand(1:length(alphabet(A)), 10))
|
g = A(rand(1:length(alphabet(A)), 10))
|
||||||
@ -153,37 +183,3 @@
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# using Random
|
|
||||||
# using GroupsCore
|
|
||||||
#
|
|
||||||
# A = New.SpecialAutomorphismGroup(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(word(New.normalform!(g*inv(g)))) length(word(New.normalform!(inv(g)*g)))
|
|
||||||
# a = commutator(g, h, g)
|
|
||||||
# b = conj(inv(g), h) * conj(conj(g, h), g)
|
|
||||||
#
|
|
||||||
# @info length(word(a))
|
|
||||||
# @info length(word(b))
|
|
||||||
#
|
|
||||||
# w = a*inv(b)
|
|
||||||
# @info length(word(w))
|
|
||||||
# New.normalform!(w)
|
|
||||||
# @info length(word(w))
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# #
|
|
||||||
# # @time ima = evaluate(a)
|
|
||||||
# # @time imb = evaluate(b)
|
|
||||||
# # @info "" a b ima imb
|
|
||||||
# # @time a == b
|
|
||||||
# end
|
|
||||||
|
Loading…
Reference in New Issue
Block a user