mirror of
https://github.com/kalmarek/Groups.jl.git
synced 2025-01-07 13:10:28 +01:00
format aut_groups
This commit is contained in:
parent
29af9659d9
commit
3cdef72977
@ -1,4 +1,4 @@
|
||||
function gersten_alphabet(n::Integer; commutative::Bool=true)
|
||||
function gersten_alphabet(n::Integer; commutative::Bool = true)
|
||||
indexing = [(i, j) for i in 1:n for j in 1:n if i ≠ j]
|
||||
S = [ϱ(i, j) for (i, j) in indexing]
|
||||
|
||||
@ -40,12 +40,17 @@ function _hexagonal_rule(
|
||||
return W(T[A[x], A[inv(y)], A[z]]) => W(T[A[z], A[w^-1], A[x]])
|
||||
end
|
||||
|
||||
gersten_relations(n::Integer; commutative) =
|
||||
gersten_relations(Word{UInt8}, n, commutative=commutative)
|
||||
function gersten_relations(n::Integer; commutative)
|
||||
return gersten_relations(Word{UInt8}, n; commutative = commutative)
|
||||
end
|
||||
|
||||
function gersten_relations(::Type{W}, n::Integer; commutative) where {W<:AbstractWord}
|
||||
function gersten_relations(
|
||||
::Type{W},
|
||||
n::Integer;
|
||||
commutative,
|
||||
) where {W<:AbstractWord}
|
||||
@assert n > 1 "Gersten relations are defined only for n>1, got n=$n"
|
||||
A = gersten_alphabet(n, commutative=commutative)
|
||||
A = gersten_alphabet(n; commutative = commutative)
|
||||
@assert length(A) <= typemax(eltype(W)) "Type $W can not represent words over alphabet with $(length(A)) letters."
|
||||
|
||||
rels = Pair{W,W}[]
|
||||
@ -74,7 +79,10 @@ function gersten_relations(::Type{W}, n::Integer; commutative) where {W<:Abstrac
|
||||
|
||||
for (i, j, k) in Iterators.product(1:n, 1:n, 1:n)
|
||||
if (i ≠ j && k ≠ i && k ≠ j)
|
||||
push!(rels, _pentagonal_rule(W, A, ϱ(i, j)^-1, ϱ(j, k)^-1, ϱ(i, k)^-1))
|
||||
push!(
|
||||
rels,
|
||||
_pentagonal_rule(W, A, ϱ(i, j)^-1, ϱ(j, k)^-1, ϱ(i, k)^-1),
|
||||
)
|
||||
push!(rels, _pentagonal_rule(W, A, ϱ(i, j)^-1, ϱ(j, k), ϱ(i, k)))
|
||||
|
||||
commutative && continue
|
||||
@ -83,7 +91,10 @@ function gersten_relations(::Type{W}, n::Integer; commutative) where {W<:Abstrac
|
||||
push!(rels, _pentagonal_rule(W, A, ϱ(i, j), λ(j, k)^-1, ϱ(i, k)))
|
||||
|
||||
# the same as above, but with ϱ ↔ λ:
|
||||
push!(rels, _pentagonal_rule(W, A, λ(i, j)^-1, λ(j, k)^-1, λ(i, k)^-1))
|
||||
push!(
|
||||
rels,
|
||||
_pentagonal_rule(W, A, λ(i, j)^-1, λ(j, k)^-1, λ(i, k)^-1),
|
||||
)
|
||||
push!(rels, _pentagonal_rule(W, A, λ(i, j)^-1, λ(j, k), λ(i, k)))
|
||||
|
||||
push!(rels, _pentagonal_rule(W, A, λ(i, j), ϱ(j, k), λ(i, k)^-1))
|
||||
@ -94,7 +105,10 @@ function gersten_relations(::Type{W}, n::Integer; commutative) where {W<:Abstrac
|
||||
if !commutative
|
||||
for (i, j) in Iterators.product(1:n, 1:n)
|
||||
if i ≠ j
|
||||
push!(rels, _hexagonal_rule(W, A, ϱ(i, j), ϱ(j, i), λ(i, j), λ(j, i)))
|
||||
push!(
|
||||
rels,
|
||||
_hexagonal_rule(W, A, ϱ(i, j), ϱ(j, i), λ(i, j), λ(j, i)),
|
||||
)
|
||||
w = W([A[ϱ(i, j)], A[ϱ(j, i)^-1], A[λ(i, j)]])
|
||||
push!(rels, w^2 => inv(w, A)^2)
|
||||
end
|
||||
|
@ -17,7 +17,7 @@ function Base.show(io::IO, S::SurfaceGroup)
|
||||
end
|
||||
end
|
||||
|
||||
function SurfaceGroup(genus::Integer, boundaries::Integer, W=Word{Int16})
|
||||
function SurfaceGroup(genus::Integer, boundaries::Integer, W = Word{Int16})
|
||||
@assert genus > 1
|
||||
|
||||
# The (confluent) rewriting systems comes from
|
||||
@ -31,7 +31,15 @@ function SurfaceGroup(genus::Integer, boundaries::Integer, W=Word{Int16})
|
||||
ltrs = String[]
|
||||
for i in 1:genus
|
||||
subscript = join('₀' + d for d in reverse(digits(i)))
|
||||
append!(ltrs, ["A" * subscript, "a" * subscript, "B" * subscript, "b" * subscript])
|
||||
append!(
|
||||
ltrs,
|
||||
[
|
||||
"A" * subscript,
|
||||
"a" * subscript,
|
||||
"B" * subscript,
|
||||
"b" * subscript,
|
||||
],
|
||||
)
|
||||
end
|
||||
Al = Alphabet(reverse!(ltrs))
|
||||
|
||||
@ -51,9 +59,13 @@ function SurfaceGroup(genus::Integer, boundaries::Integer, W=Word{Int16})
|
||||
comms = W(word)
|
||||
word_rels = [comms => one(comms)]
|
||||
|
||||
rws = let R = KnuthBendix.RewritingSystem(word_rels, KnuthBendix.Recursive(Al))
|
||||
KnuthBendix.IndexAutomaton(KnuthBendix.knuthbendix(R))
|
||||
end
|
||||
rws =
|
||||
let R = KnuthBendix.RewritingSystem(
|
||||
word_rels,
|
||||
KnuthBendix.Recursive(Al),
|
||||
)
|
||||
KnuthBendix.IndexAutomaton(KnuthBendix.knuthbendix(R))
|
||||
end
|
||||
elseif boundaries == 1
|
||||
word_rels = Pair{W,W}[]
|
||||
rws = let R = RewritingSystem(word_rels, KnuthBendix.LenLex(Al))
|
||||
@ -66,7 +78,13 @@ function SurfaceGroup(genus::Integer, boundaries::Integer, W=Word{Int16})
|
||||
F = FreeGroup(Al)
|
||||
rels = [F(lhs) => F(rhs) for (lhs, rhs) in word_rels]
|
||||
|
||||
return SurfaceGroup(genus, boundaries, [Al[i] for i in 2:2:length(Al)], rels, rws)
|
||||
return SurfaceGroup(
|
||||
genus,
|
||||
boundaries,
|
||||
[Al[i] for i in 2:2:length(Al)],
|
||||
rels,
|
||||
rws,
|
||||
)
|
||||
end
|
||||
|
||||
rewriting(S::SurfaceGroup) = S.rw
|
||||
@ -75,17 +93,26 @@ relations(S::SurfaceGroup) = S.relations
|
||||
function symplectic_twists(π₁Σ::SurfaceGroup)
|
||||
g = genus(π₁Σ)
|
||||
|
||||
saut = SpecialAutomorphismGroup(FreeGroup(2g), max_rules=1000)
|
||||
saut = SpecialAutomorphismGroup(FreeGroup(2g); max_rules = 1000)
|
||||
|
||||
Aij = [SymplecticMappingClass(saut, :A, i, j) for i in 1:g for j in 1:g if i ≠ j]
|
||||
Aij = [
|
||||
SymplecticMappingClass(saut, :A, i, j) for i in 1:g for
|
||||
j in 1:g if i ≠ j
|
||||
]
|
||||
|
||||
Bij = [SymplecticMappingClass(saut, :B, i, j) for i in 1:g for j in 1:g if i ≠ j]
|
||||
Bij = [
|
||||
SymplecticMappingClass(saut, :B, i, j) for i in 1:g for
|
||||
j in 1:g if i ≠ j
|
||||
]
|
||||
|
||||
mBij = [SymplecticMappingClass(saut, :B, i, j, minus=true) for i in 1:g for j in 1:g if i ≠ j]
|
||||
mBij = [
|
||||
SymplecticMappingClass(saut, :B, i, j; minus = true) for i in 1:g
|
||||
for j in 1:g if i ≠ j
|
||||
]
|
||||
|
||||
Bii = [SymplecticMappingClass(saut, :B, i, i) for i in 1:g]
|
||||
|
||||
mBii = [SymplecticMappingClass(saut, :B, i, i, minus=true) for i in 1:g]
|
||||
mBii = [SymplecticMappingClass(saut, :B, i, i; minus = true) for i in 1:g]
|
||||
|
||||
return [Aij; Bij; mBij; Bii; mBii]
|
||||
end
|
||||
|
@ -1,10 +1,13 @@
|
||||
include("transvections.jl")
|
||||
include("gersten_relations.jl")
|
||||
|
||||
function SpecialAutomorphismGroup(F::FreeGroup; ordering=KnuthBendix.LenLex, kwargs...)
|
||||
|
||||
function SpecialAutomorphismGroup(
|
||||
F::FreeGroup;
|
||||
ordering = KnuthBendix.LenLex,
|
||||
kwargs...,
|
||||
)
|
||||
n = length(alphabet(F)) ÷ 2
|
||||
A, rels = gersten_relations(n, commutative=false)
|
||||
A, rels = gersten_relations(n; commutative = false)
|
||||
S = [A[i] for i in 1:2:length(A)]
|
||||
|
||||
max_rules = 1000 * n
|
||||
@ -12,7 +15,10 @@ function SpecialAutomorphismGroup(F::FreeGroup; ordering=KnuthBendix.LenLex, kwa
|
||||
rws = Logging.with_logger(Logging.NullLogger()) do
|
||||
rws = KnuthBendix.RewritingSystem(rels, ordering(A))
|
||||
# the rws is not confluent, let's suppress warning about it
|
||||
KnuthBendix.knuthbendix(rws, KnuthBendix.Settings(; max_rules=max_rules, kwargs...))
|
||||
return KnuthBendix.knuthbendix(
|
||||
rws,
|
||||
KnuthBendix.Settings(; max_rules = max_rules, kwargs...),
|
||||
)
|
||||
end
|
||||
|
||||
idxA = KnuthBendix.IndexAutomaton(rws)
|
||||
@ -21,5 +27,5 @@ end
|
||||
|
||||
function relations(G::AutomorphismGroup{<:FreeGroup})
|
||||
n = length(alphabet(object(G))) ÷ 2
|
||||
return last(gersten_relations(n, commutative=false))
|
||||
return last(gersten_relations(n; commutative = false))
|
||||
end
|
||||
|
@ -47,7 +47,15 @@ function Te_diagonal(λ::Groups.ΡΛ, ϱ::Groups.ΡΛ, i::Integer)
|
||||
return g
|
||||
end
|
||||
|
||||
function Te_lantern(A::Alphabet, b₀::T, a₁::T, a₂::T, a₃::T, a₄::T, a₅::T) where {T}
|
||||
function Te_lantern(
|
||||
A::Alphabet,
|
||||
b₀::T,
|
||||
a₁::T,
|
||||
a₂::T,
|
||||
a₃::T,
|
||||
a₄::T,
|
||||
a₅::T,
|
||||
) where {T}
|
||||
a₀ = (a₁ * a₂ * a₃)^4 * inv(b₀, A)
|
||||
X = a₄ * a₅ * a₃ * a₄ # from Primer
|
||||
b₁ = inv(X, A) * a₀ * X # from Primer
|
||||
@ -85,7 +93,8 @@ function Te(λ::ΡΛ, ϱ::ΡΛ, i, j)
|
||||
if mod(j - (i + 1), genus) == 0
|
||||
return Te_diagonal(λ, ϱ, i)
|
||||
else
|
||||
return inv(Te_lantern(
|
||||
return inv(
|
||||
Te_lantern(
|
||||
A,
|
||||
# Our notation: # Primer notation:
|
||||
inv(Ta(λ, i + 1), A), # b₀
|
||||
@ -94,7 +103,9 @@ function Te(λ::ΡΛ, ϱ::ΡΛ, i, j)
|
||||
inv(Te_diagonal(λ, ϱ, i), A), # a₃
|
||||
inv(Tα(λ, i + 1), A), # a₄
|
||||
inv(Te(λ, ϱ, i + 1, j), A), # a₅
|
||||
), A)
|
||||
),
|
||||
A,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@ -105,7 +116,6 @@ Return the element of `G` which corresponds to shifting generators of the free g
|
||||
In the corresponding mapping class group this element acts by rotation of the surface anti-clockwise.
|
||||
"""
|
||||
function rotation_element(G::AutomorphismGroup{<:FreeGroup})
|
||||
|
||||
A = alphabet(G)
|
||||
@assert iseven(ngens(object(G)))
|
||||
genus = ngens(object(G)) ÷ 2
|
||||
@ -140,7 +150,10 @@ function rotation_element(λ::ΡΛ, ϱ::ΡΛ)
|
||||
Ta(λ, i) *
|
||||
inv(Te_diagonal(λ, ϱ, i), A)
|
||||
|
||||
Ta(λ, i) * inv(Ta(λ, j) * Tα(λ, j), A)^6 * (Ta(λ, j) * Tα(λ, j) * z)^4 * c
|
||||
return Ta(λ, i) *
|
||||
inv(Ta(λ, j) * Tα(λ, j), A)^6 *
|
||||
(Ta(λ, j) * Tα(λ, j) * z)^4 *
|
||||
c
|
||||
end
|
||||
|
||||
τ = (Ta(λ, 1) * Tα(λ, 1))^6 * prod(halftwists)
|
||||
@ -148,7 +161,6 @@ function rotation_element(λ::ΡΛ, ϱ::ΡΛ)
|
||||
end
|
||||
|
||||
function mcg_twists(G::AutomorphismGroup{<:FreeGroup})
|
||||
|
||||
@assert iseven(ngens(object(G)))
|
||||
genus = ngens(object(G)) ÷ 2
|
||||
|
||||
@ -178,7 +190,9 @@ struct SymplecticMappingClass{T,F} <: GSymbol
|
||||
f::F
|
||||
end
|
||||
|
||||
Base.:(==)(a::SymplecticMappingClass, b::SymplecticMappingClass) = a.autFn_word == b.autFn_word
|
||||
function Base.:(==)(a::SymplecticMappingClass, b::SymplecticMappingClass)
|
||||
return a.autFn_word == b.autFn_word
|
||||
end
|
||||
|
||||
Base.hash(a::SymplecticMappingClass, h::UInt) = hash(a.autFn_word, h)
|
||||
|
||||
@ -187,8 +201,8 @@ function SymplecticMappingClass(
|
||||
id::Symbol,
|
||||
i::Integer,
|
||||
j::Integer;
|
||||
minus=false,
|
||||
inverse=false
|
||||
minus = false,
|
||||
inverse = false,
|
||||
)
|
||||
@assert i > 0 && j > 0
|
||||
id === :A && @assert i ≠ j
|
||||
@ -246,7 +260,7 @@ function Base.show(io::IO, smc::SymplecticMappingClass)
|
||||
else
|
||||
print(io, smc.id, subscriptify(smc.i), ".", subscriptify(smc.j))
|
||||
end
|
||||
smc.inv && print(io, "^-1")
|
||||
return smc.inv && print(io, "^-1")
|
||||
end
|
||||
|
||||
function Base.inv(m::SymplecticMappingClass)
|
||||
@ -259,7 +273,7 @@ end
|
||||
function evaluate!(
|
||||
t::NTuple{N,T},
|
||||
smc::SymplecticMappingClass,
|
||||
tmp=nothing,
|
||||
tmp = nothing,
|
||||
) where {N,T}
|
||||
t = smc.f(t)
|
||||
for i in 1:N
|
||||
|
@ -4,7 +4,7 @@ struct Transvection <: GSymbol
|
||||
j::UInt16
|
||||
inv::Bool
|
||||
|
||||
function Transvection(id::Symbol, i::Integer, j::Integer, inv=false)
|
||||
function Transvection(id::Symbol, i::Integer, j::Integer, inv = false)
|
||||
@assert id in (:ϱ, :λ)
|
||||
return new(id, i, j, inv)
|
||||
end
|
||||
@ -20,20 +20,23 @@ function Base.show(io::IO, t::Transvection)
|
||||
'λ'
|
||||
end
|
||||
print(io, id, subscriptify(t.i), '.', subscriptify(t.j))
|
||||
t.inv && print(io, "^-1")
|
||||
return t.inv && print(io, "^-1")
|
||||
end
|
||||
|
||||
Base.inv(t::Transvection) = Transvection(t.id, t.i, t.j, !t.inv)
|
||||
|
||||
Base.:(==)(t::Transvection, s::Transvection) =
|
||||
t.id === s.id && t.i == s.i && t.j == s.j && t.inv == s.inv
|
||||
function Base.:(==)(t::Transvection, s::Transvection)
|
||||
return t.id === s.id && t.i == s.i && t.j == s.j && t.inv == s.inv
|
||||
end
|
||||
|
||||
Base.hash(t::Transvection, h::UInt) = hash(hash(t.id, hash(t.i)), hash(t.j, hash(t.inv, h)))
|
||||
function Base.hash(t::Transvection, h::UInt)
|
||||
return hash(hash(t.id, hash(t.i)), hash(t.j, hash(t.inv, h)))
|
||||
end
|
||||
|
||||
Base.@propagate_inbounds @inline function evaluate!(
|
||||
v::NTuple{T,N},
|
||||
t::Transvection,
|
||||
tmp=one(first(v)),
|
||||
tmp = one(first(v)),
|
||||
) where {T,N}
|
||||
i, j = t.i, t.j
|
||||
@assert 1 ≤ i ≤ length(v) && 1 ≤ j ≤ length(v)
|
||||
@ -84,7 +87,7 @@ end
|
||||
|
||||
function Base.show(io::IO, p::PermRightAut)
|
||||
print(io, 'σ')
|
||||
join(io, (subscriptify(Int(i)) for i in p.perm))
|
||||
return join(io, (subscriptify(Int(i)) for i in p.perm))
|
||||
end
|
||||
|
||||
Base.inv(p::PermRightAut) = PermRightAut(invperm(p.perm))
|
||||
@ -92,4 +95,6 @@ Base.inv(p::PermRightAut) = PermRightAut(invperm(p.perm))
|
||||
Base.:(==)(p::PermRightAut, q::PermRightAut) = p.perm == q.perm
|
||||
Base.hash(p::PermRightAut, h::UInt) = hash(p.perm, hash(PermRightAut, h))
|
||||
|
||||
evaluate!(v::NTuple{T,N}, p::PermRightAut, tmp=nothing) where {T,N} = v[p.perm]
|
||||
function evaluate!(v::NTuple{T,N}, p::PermRightAut, tmp = nothing) where {T,N}
|
||||
return v[p.perm]
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user