diff --git a/src/autgroups.jl b/src/autgroups.jl index 53db353..7c30686 100644 --- a/src/autgroups.jl +++ b/src/autgroups.jl @@ -173,3 +173,64 @@ function evaluate!(res::AbstractWord, w::AbstractWord, lm::LettersMap) end return res end + +# compile automorphisms + +compiled(a) = eval(generated_evaluate(a)) + +function generated_evaluate(a::FPGroupElement{<:AutomorphismGroup}) + lm = Groups.LettersMap(a) + d = Groups.domain(a) + @assert all(length.(word.(d)) .== 1) + A = alphabet(first(d)) + first_ltrs = first.(word.(d)) + + args = [Expr(:call, :*) for _ in first_ltrs] + + for (idx, letter) in enumerate(first_ltrs) + for l in lm[letter] + k = findfirst(==(l), first_ltrs) + if k !== nothing + push!(args[idx].args, :(d[$k])) + continue + end + k = findfirst(==(inv(A, l)), first_ltrs) + if k !== nothing + push!(args[idx].args, :(inv(d[$k]))) + continue + end + throw("Letter $l doesn't seem to be mapped anywhere!") + end + end + locals = Dict{Expr, Symbol}() + locals_counter = 0 + for (i,v) in enumerate(args) + @assert length(v.args) >= 2 + if length(v.args) > 2 + for (j, a) in pairs(v.args) + if a isa Expr && a.head == :call "$a" + @assert a.args[1] == :inv + if !(a in keys(locals)) + locals[a] = Symbol("var_#$locals_counter") + locals_counter += 1 + end + v.args[j] = locals[a] + end + end + else + args[i] = v.args[2] + end + end + + q = quote + $([:(local $v = $k) for (k,v) in locals]...) + end + + # return args, locals + + return :(d -> begin + @boundscheck @assert length(d) == $(length(d)) + $q + @inbounds tuple($(args...)) + end) +end diff --git a/src/groups/symplectic_twists.jl b/src/groups/symplectic_twists.jl index bef6f3e..d9f5929 100644 --- a/src/groups/symplectic_twists.jl +++ b/src/groups/symplectic_twists.jl @@ -161,7 +161,8 @@ function SymplecticMappingClass( g = genus(Σ) perm = [2g:-2:1; (2g-1):-2:1] - f(t) = evaluate!(t, a) + f = compiled(a) + # f = t -> evaluate!(t, a) res = SymplecticMappingClass(id, UInt(i), UInt(j), minus, inverse, a, perm, f) @@ -180,7 +181,8 @@ end function Base.inv(m::SymplecticMappingClass) inv_w = inv(m.autFn_word) - f(t) = evaluate!(t, inv_w) + # f(t) = evaluate!(t, inv_w) + f = compiled(inv_w) return SymplecticMappingClass(m.id, m.i, m.j, m.minus, !m.inv, inv_w, m.perm, f) end @@ -192,8 +194,6 @@ function evaluate!( ) where {N,T} t = smc.f(t[smc.perm])[invperm(smc.perm)] - # t = evaluate!(t[smc.perm], smc.autFn_word, tmp) - # t = t[invperm(smc.perm)] return t end