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