mirror of
https://github.com/kalmarek/Groups.jl.git
synced 2025-01-03 20:15:28 +01:00
Merge branch 'master' into enh/julia-v0.6
This commit is contained in:
commit
c18e2156b5
@ -26,7 +26,7 @@ matrix:
|
||||
|
||||
## uncomment the following lines to override the default test script
|
||||
script:
|
||||
- julia -e 'Pkg.clone("https://github.com/Nemocas/Nemo.jl"); Pkg.build("Nemo")'
|
||||
# - julia -e 'Pkg.clone("https://github.com/Nemocas/Nemo.jl"); Pkg.build("Nemo")'
|
||||
- julia -e 'Pkg.clone(pwd()); Pkg.build("Groups"); Pkg.test("Groups"; coverage=true)'
|
||||
|
||||
after_success:
|
||||
|
134
src/AutGroup.jl
134
src/AutGroup.jl
@ -7,8 +7,7 @@
|
||||
struct AutSymbol <: GSymbol
|
||||
str::String
|
||||
pow::Int
|
||||
ex::Expr
|
||||
func::Function
|
||||
typ::Union{RTransvect, LTransvect, FlipAut, PermAut, Identity}
|
||||
end
|
||||
|
||||
AutGroupElem = GWord{AutSymbol}
|
||||
@ -36,21 +35,23 @@ parent_type(::AutGroupElem) = AutGroup
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
function ϱ(i,j, pow=1)
|
||||
# @assert i ≠ j
|
||||
return v -> [(k==i ? v[i]*v[j]^pow : v[k]) for k in eachindex(v)]
|
||||
function (ϱ::RTransvect)(v, pow=1::Int)
|
||||
return [(k==ϱ.i ? v[ϱ.i]*v[ϱ.j]^pow : v[k]) for k in eachindex(v)]
|
||||
end
|
||||
|
||||
function λ(i,j, pow=1)
|
||||
# @assert i ≠ j
|
||||
return v -> [(k==i ? v[j]^pow*v[i] : v[k]) for k in eachindex(v)]
|
||||
function (λ::LTransvect)(v, pow=1::Int)
|
||||
return [(k==λ.i ? v[λ.j]^pow*v[λ.i] : v[k]) for k in eachindex(v)]
|
||||
end
|
||||
|
||||
function σ(p::Generic.perm, pow=1)
|
||||
return v -> [v[(p^pow)[k]] for k in eachindex(v)]
|
||||
function (σ::PermAut)(v, pow=1::Int)
|
||||
return v[(σ.p^pow).d]
|
||||
end
|
||||
|
||||
ɛ(i, pow=1) = v -> [(k==i ? v[k]^(-1*(2+pow%2)%2) : v[k]) for k in eachindex(v)]
|
||||
function (ɛ::FlipAut)(v, pow=1::Int)
|
||||
return [(k==ɛ.i ? v[k]^(-1^pow) : v[k]) for k in eachindex(v)]
|
||||
end
|
||||
|
||||
(::Identity)(v, pow=1::Int) = v
|
||||
|
||||
# taken from ValidatedNumerics, under under the MIT "Expat" License:
|
||||
# https://github.com/JuliaIntervals/ValidatedNumerics.jl/blob/master/LICENSE.md
|
||||
@ -60,32 +61,36 @@ function subscriptify(n::Int)
|
||||
end
|
||||
|
||||
function id_autsymbol()
|
||||
return AutSymbol("(id)", 0, :(id()), identity)
|
||||
return AutSymbol("(id)", 0, Identity())
|
||||
end
|
||||
|
||||
function rmul_autsymbol(i, j; pow::Int=1)
|
||||
str = "ϱ"*subscriptify(i)*subscriptify(j)
|
||||
return AutSymbol(str, pow, :(ϱ($i, $j, $pow)), ϱ(i, j, pow))
|
||||
return AutSymbol(str, pow, RTransvect(i, j))
|
||||
end
|
||||
|
||||
function lmul_autsymbol(i, j; pow::Int=1)
|
||||
str = "λ"*subscriptify(i)*subscriptify(j)
|
||||
return AutSymbol(str, pow, :(λ($i, $j, $pow)), λ(i, j, pow))
|
||||
return AutSymbol(str, pow, LTransvect(i, j))
|
||||
end
|
||||
|
||||
function flip_autsymbol(i; pow::Int=1)
|
||||
str = "ɛ"*subscriptify(i)
|
||||
pow = (2+pow%2)%2
|
||||
return AutSymbol(str, pow, :(ɛ($i, $pow)), ɛ(i, pow))
|
||||
if pow == 0
|
||||
return id_autsymbol()
|
||||
else
|
||||
str = "ɛ"*subscriptify(i)
|
||||
return AutSymbol(str, pow, FlipAut(i))
|
||||
end
|
||||
end
|
||||
|
||||
function perm_autsymbol(p::Generic.perm; pow::Int=1)
|
||||
p = p^pow
|
||||
if p == parent(p)()
|
||||
return id_autsymbol()
|
||||
return id_autsymbol()
|
||||
else
|
||||
p = p^pow
|
||||
str = "σ"*join([subscriptify(i) for i in p.d])
|
||||
return AutSymbol(str, 1, :(σ($(p.d), 1)), σ(p, 1))
|
||||
str = "σ"*join([subscriptify(i) for i in p.d])
|
||||
return AutSymbol(str, 1, PermAut(p))
|
||||
end
|
||||
end
|
||||
|
||||
@ -94,38 +99,30 @@ function perm_autsymbol(a::Vector{Int})
|
||||
return perm_autsymbol(G(a))
|
||||
end
|
||||
|
||||
function getperm(s::AutSymbol)
|
||||
if s.ex.args[1] == :σ
|
||||
p = s.ex.args[2]
|
||||
return PermutationGroup(length(p))(p)
|
||||
else
|
||||
throw(ArgumentError("$s is not a permutation automorphism!"))
|
||||
end
|
||||
end
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# AutGroup / AutGroupElem constructors
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
function AutGroup(G::FreeGroup; outer=false, special=false)
|
||||
function AutGroup(G::FreeGroup; special=false)
|
||||
n = length(G.gens)
|
||||
n == 0 && return AutGroup(G, AutSymbol[])
|
||||
S = AutSymbol[]
|
||||
|
||||
indexing = [[i,j] for i in 1:n for j in 1:n if i≠j]
|
||||
|
||||
rmuls = [rmul_autsymbol(i,j) for (i,j) in indexing]
|
||||
append!(S, rmuls)
|
||||
lmuls = [lmul_autsymbol(i,j) for (i,j) in indexing]
|
||||
append!(S, lmuls)
|
||||
|
||||
append!(S, [rmuls; lmuls])
|
||||
|
||||
if !special
|
||||
flips = [flip_autsymbol(i) for i in 1:n]
|
||||
append!(S, flips)
|
||||
end
|
||||
if !outer
|
||||
perms = collect(elements(PermutationGroup(n)))
|
||||
perms = [perm_autsymbol(p) for p in perms[2:end]] # leave the identity
|
||||
append!(S, perms)
|
||||
syms = [perm_autsymbol(p) for p in elements(PermutationGroup(n))][2:end]
|
||||
|
||||
append!(S, [flips; syms])
|
||||
|
||||
end
|
||||
return AutGroup(G, S)
|
||||
end
|
||||
@ -160,10 +157,12 @@ end
|
||||
###############################################################################
|
||||
|
||||
function (f::AutSymbol){T}(v::Vector{GWord{T}})
|
||||
if f.pow == 0
|
||||
return v
|
||||
end
|
||||
return f.func(v)
|
||||
if f.pow == 0
|
||||
nothing
|
||||
else
|
||||
v = f.typ(v, f.pow)
|
||||
end
|
||||
return v
|
||||
end
|
||||
|
||||
function (F::AutGroupElem)(v::Vector)
|
||||
@ -182,30 +181,31 @@ end
|
||||
hash(s::AutSymbol, h::UInt) = hash(s.str, hash(s.pow, hash(:AutSymbol, h)))
|
||||
|
||||
function hash(g::AutGroupElem, h::UInt)
|
||||
gs = gens(parent(g).objectGroup)
|
||||
return hash(g(gs), hash(typeof(g), hash(parent(g), h)))
|
||||
if g.modified
|
||||
g.savedhash = hash(g(gens(parent(g).objectGroup)), hash(typeof(g), hash(parent(g), h)))
|
||||
g.modified = false
|
||||
end
|
||||
return g.savedhash
|
||||
end
|
||||
|
||||
function change_pow(s::AutSymbol, n::Int)
|
||||
if n == 0
|
||||
return id_autsymbol()
|
||||
end
|
||||
symbol = s.ex.args[1]
|
||||
if symbol == :ɛ
|
||||
return flip_autsymbol(s.ex.args[2], pow=n)
|
||||
elseif symbol == :σ
|
||||
G = PermutationGroup(length(s.ex.args[2]))
|
||||
return perm_autsymbol(G(s.ex.args[2]), pow=n)
|
||||
elseif symbol == :ϱ
|
||||
s.ex.args[2:end-1]
|
||||
return rmul_autsymbol(s.ex.args[2:end-1]..., pow=n)
|
||||
elseif symbol == :λ
|
||||
return lmul_autsymbol(s.ex.args[2:end-1]..., pow=n)
|
||||
elseif symbol == :id
|
||||
symbol = s.typ
|
||||
if isa(symbol, FlipAut)
|
||||
return flip_autsymbol(symbol.i, pow=n)
|
||||
elseif isa(symbol, PermAut)
|
||||
return perm_autsymbol(symbol.p, pow=n)
|
||||
elseif isa(symbol, RTransvect)
|
||||
return rmul_autsymbol(symbol.i, symbol.j, pow=n)
|
||||
elseif isa(symbol, LTransvect)
|
||||
return lmul_autsymbol(symbol.i, symbol.j, pow=n)
|
||||
elseif isa(symbol, Identity)
|
||||
return s
|
||||
else
|
||||
warn("Changing power of an unknown type of symbol! $s")
|
||||
return AutSymbol(s.str, n, s.ex, s.func)
|
||||
return AutSymbol(s.str, n, s.typ)
|
||||
end
|
||||
end
|
||||
|
||||
@ -257,18 +257,22 @@ inv(f::AutSymbol) = change_pow(f, -f.pow)
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
ispermauto(s::AutSymbol) = s.ex.args[1] == :σ
|
||||
function getperm(s::AutSymbol)
|
||||
isa(s.typ, PermAut) || throw("$s is not a permutation automorphism")
|
||||
return s.typ.p
|
||||
end
|
||||
|
||||
function simplify_perms!(W::AutGroupElem)
|
||||
reduced = true
|
||||
for i in 1:length(W.symbols) - 1
|
||||
current = W.symbols[i]
|
||||
if ispermauto(current)
|
||||
if current.pow != 1
|
||||
current = perm_autsymbol(perm(current), pow=current.pow)
|
||||
end
|
||||
if isa(current.typ, PermAut)
|
||||
next_s = W.symbols[i+1]
|
||||
if ispermauto(next_s)
|
||||
if isa(next_s.typ, PermAut)
|
||||
if current.pow != 1
|
||||
current = perm_autsymbol(perm(current), pow=current.pow)
|
||||
end
|
||||
|
||||
reduced = false
|
||||
if next_s.pow != 1
|
||||
next_s = perm_autsymbol(perm(next_s), pow=next_s.pow)
|
||||
@ -295,7 +299,7 @@ function reduce!(W::AutGroupElem)
|
||||
end
|
||||
end
|
||||
|
||||
W.modified = false
|
||||
W.savedhash = hash(W.symbols,hash(typeof(W)))
|
||||
W.modified = true
|
||||
|
||||
return W
|
||||
end
|
||||
|
@ -1,3 +1,4 @@
|
||||
__precompile__()
|
||||
module Groups
|
||||
|
||||
using Nemo
|
||||
@ -376,30 +377,23 @@ end
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
function products(X::AbstractVector{T}, Y::AbstractVector{T}, op=*) where {T<:GroupElem}
|
||||
|
||||
result = Vector{T}()
|
||||
seen = Set{T}()
|
||||
for x in X
|
||||
for y in Y
|
||||
z = op(x,y)
|
||||
if !in(z, seen)
|
||||
push!(seen, z)
|
||||
push!(result, z)
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function generate_balls(S::Vector{T}, Id::T; radius=2, op=*) where {T<:GroupElem}
|
||||
|
||||
sizes = Vector{Int}()
|
||||
S = deepcopy(S)
|
||||
S = unshift!(S, Id)
|
||||
function generate_balls{T<:GroupElem}(S::Vector{T}, Id::T=parent(first(S))(); radius=2, op=*)
|
||||
sizes = Int[]
|
||||
B = [Id]
|
||||
for i in 1:radius
|
||||
B = products(B, S, op);
|
||||
BB = [op(i,j) for (i,j) in Base.product(B,S)]
|
||||
B = unique([B; vec(BB)])
|
||||
push!(sizes, length(B))
|
||||
end
|
||||
return B, sizes
|
||||
end
|
||||
|
||||
function generate_balls{T<:RingElem}(S::Vector{T}, Id::T=one(parent(first(S))); radius=2, op=*)
|
||||
sizes = Int[]
|
||||
B = [Id]
|
||||
for i in 1:radius
|
||||
BB = [op(i,j) for (i,j) in Base.product(B,S)]
|
||||
B = unique([B; vec(BB)])
|
||||
push!(sizes, length(B))
|
||||
end
|
||||
return B, sizes
|
||||
|
@ -5,7 +5,7 @@
|
||||
@testset "AutSymbol" begin
|
||||
@test_throws MethodError Groups.AutSymbol("a")
|
||||
@test_throws MethodError Groups.AutSymbol("a", 1)
|
||||
f = Groups.AutSymbol("a", 1, :(a()), v -> v)
|
||||
f = Groups.AutSymbol("a", 1, Groups.FlipAut(2))
|
||||
@test isa(f, Groups.GSymbol)
|
||||
@test isa(f, Groups.AutSymbol)
|
||||
@test isa(Groups.perm_autsymbol(G([1,2,3,4])), Groups.AutSymbol)
|
||||
@ -83,7 +83,7 @@
|
||||
end
|
||||
|
||||
@testset "AutGroup/AutGroupElem constructors" begin
|
||||
f = Groups.AutSymbol("a", 1, :(a()), v -> v)
|
||||
f = Groups.AutSymbol("a", 1, Groups.FlipAut(1))
|
||||
@test isa(AutGroupElem(f), Groups.GWord)
|
||||
@test isa(AutGroupElem(f), AutGroupElem)
|
||||
@test isa(AutGroup(FreeGroup(3)), Nemo.Group)
|
||||
@ -129,7 +129,6 @@
|
||||
@test (Groups.change_pow(f, -2)).pow == 1
|
||||
@test (inv(f)).pow == 1
|
||||
|
||||
|
||||
f = Groups.perm_autsymbol(G([2,1,4,3]))
|
||||
@test isa(inv(f), Groups.AutSymbol)
|
||||
|
||||
@ -150,6 +149,16 @@
|
||||
b = Groups.flip_autsymbol(2)*A(inv(Groups.rmul_autsymbol(1,2)))
|
||||
@test a*b == b*a
|
||||
@test a^3 * b^3 == A()
|
||||
g,h = Nemo.gens(A)[[1,8]]
|
||||
domain = Nemo.gens(A.objectGroup)
|
||||
@test (g*h)(domain) == (h*g)(domain)
|
||||
@test (g*h).savedhash != (h*g).savedhash
|
||||
a = g*h
|
||||
b = h*g
|
||||
@test hash(a) == hash(b)
|
||||
@test a.savedhash == b.savedhash
|
||||
@test length(unique([a,b])) == 1
|
||||
@test length(unique([g*h, h*g])) == 1
|
||||
end
|
||||
|
||||
@testset "specific Aut(F4) tests" begin
|
||||
@ -164,7 +173,7 @@
|
||||
S_inv = [S..., [inv(s) for s in S]...]
|
||||
@test length(unique(S_inv)) == 75
|
||||
|
||||
G = AutGroup(FreeGroup(N), special=true, outer=true)
|
||||
G = AutGroup(FreeGroup(N), special=true)
|
||||
S = Nemo.gens(G)
|
||||
S_inv = [G(), S..., [inv(s) for s in S]...]
|
||||
S_inv = unique(S_inv)
|
||||
|
Loading…
Reference in New Issue
Block a user