Merge branch 'master' into enh/julia-v0.6

This commit is contained in:
kalmarek 2017-11-15 20:34:30 +01:00
commit c18e2156b5
4 changed files with 99 additions and 92 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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)