diff --git a/MCG.jl b/MCG.jl index f2fbe1c..4b6cfe6 100644 --- a/MCG.jl +++ b/MCG.jl @@ -27,7 +27,7 @@ function parse_commandline() "--radius" help = "Radius of ball B_r(e,S) to find solution over" arg_type = Int - default = 4 + default = 2 "--warmstart" help = "Use warmstart.jl as the initial guess for SCS" action = :store_true @@ -38,113 +38,15 @@ end const PARSEDARGS = parse_commandline() include("CPUselect.jl") -# set_parallel_mthread(PARSEDARGS, workers=true) +set_parallel_mthread(PARSEDARGS, workers=false) -include("FPGroups_GAP.jl") - -module MCGrps - -using Groups using Nemo - -Comm(x,y) = x*y*x^-1*y^-1 - -function Group(N::Int) - if N == 2 - MCGroup = Groups.FPGroup(["a1","a2","a3","a4","a5"]); - S = Nemo.gens(MCGroup) - - N = length(S) - A = prod(reverse(S))*prod(S) - - relations = [ - [Comm(S[i], S[j]) for i in 1:N for j in 1:N if abs(i-j) > 1]..., - [S[i]*S[i+1]*S[i]*inv(S[i+1]*S[i]*S[i+1]) for i in 1:N-1]..., - (S[1]*S[2]*S[3])^4*inv(S[5])^2, - Comm(A, S[1]), - A^2 - ] - - relations = [relations; [inv(rel) for rel in relations]] - Groups.add_rels!(MCGroup, Dict(rel => MCGroup() for rel in relations)) - return MCGroup - - elseif N < 2 - throw("Genus must be at least 2!") - end - - MCGroup = Groups.FPGroup(["a$i" for i in 0:2N]) - S = Nemo.gens(MCGroup) - - a0 = S[1] - A = S[2:end] - k = length(A) - - relations = [ - [Comm(A[i], A[j]) for i in 1:k for j in 1:k if abs(i-j) > 1]..., - [Comm(a0, A[i]) for i in 1:k if i != 4]..., - [A[i]*A[(i+1)]*A[i]*inv(A[i+1]*A[i]*A[i+1]) for i in 1:k-1]..., - A[4]*a0*A[4]*inv(a0*A[4]*a0) - ] - - # 3-chain relation - c = prod(reverse(A[1:4]))*prod(A[1:4]) - b0 = c*a0*inv(c) - push!(relations, (A[1]*A[2]*A[3])^4*inv(a0*b0)) - - # Lantern relation - b1 = inv(A[4]*A[5]*A[3]*A[4])*a0*(A[4]*A[5]*A[3]*A[4]) - b2 = inv(A[2]*A[3]*A[1]*A[2])*b1*(A[2]*A[3]*A[1]*A[2]) - u = inv(A[6]*A[5])*b1*(A[6]*A[5]) - x = prod(reverse(A[2:6]))*u*prod(inv.(A[1:4])) - b3 = x*a0*inv(x) - push!(relations, a0*b2*b1*inv(A[1]*A[3]*A[5]*b3)) - - # Hyperelliptic relation - X = prod(reverse(A))*prod(A) - - function n(i::Int, b=b0) - if i == 1 - return A[1] - elseif i == 2 - return b - else - return w(i-2)*n(i-2)*w(i-2) - end - end - - function w(i::Int) - (A[2i+4]*A[2i+3]*A[2i+2]* n(i+1))*(A[2i+1]*A[2i] *A[2i+2]*A[2i+1])* - (A[2i+3]*A[2i+2]*A[2i+4]*A[2i+3])*( n(i+1)*A[2i+2]*A[2i+1]*A[2i] ) - end - - push!(relations, X*n(N)*inv(n(N)*X)) - - relations = [relations; [inv(rel) for rel in relations]] - Groups.add_rels!(MCGroup, Dict(rel => MCGroup() for rel in relations)) - @show MCGroup - return MCGroup -end - -############################################################################### -# -# Misc -# -############################################################################### - -function groupname(parsed_args) - N = parsed_args["N"] - return groupname(N), N -end - -groupname(N::Int) = "MCG$(N)" - -end #of module MCGrps - - - using SCS.SCSSolver using PropertyT +using Groups + +include("FPGroups_GAP.jl") +include("groups/mappingclassgroup.jl") function main(GROUP, parsed_args) @@ -157,12 +59,11 @@ function main(GROUP, parsed_args) name, N = GROUP.groupname(parsed_args) isdir(name) || mkdir(name) - G = GROUP.Group(N) - S = Nemo.gens(G) + G, S = GROUP.generatingset(N) relations = [k*inv(v) for (k,v) in G.rels] prepare_pm_delta(name, GAP_groupcode(S, relations), radius) - S = unique([S; [inv(s) for s in S]]) + S = unique([S; inv.(S)]) Id = G() @@ -178,10 +79,10 @@ function main(GROUP, parsed_args) info(logger, "Threads: $(Threads.nthreads())") info(logger, "Workers: $(workers())") - solver = SCSSolver(eps=tol, max_iters=iterations, linearsolver=SCS.Direct, alpha=1.9, acceleration_lookback=1) + solver = SCSSolver(eps=tol, max_iters=iterations, linearsolver=SCS.Direct, alpha=1.95, acceleration_lookback=1) PropertyT.check_property_T(name, S, Id, solver, upper_bound, tol, radius, warm) return 0 end -main(MCGrps, PARSEDARGS) +main(MappingClassGroups, PARSEDARGS) diff --git a/groups/mappingclassgroup.jl b/groups/mappingclassgroup.jl new file mode 100644 index 0000000..50388ad --- /dev/null +++ b/groups/mappingclassgroup.jl @@ -0,0 +1,109 @@ +module MappingClassGroups + +using Nemo +using Groups + +############################################################################### +# +# Generating set +# +############################################################################### + +Comm(x,y) = x*y*x^-1*y^-1 + +function generatingset(N::Int) + if N == 2 + MCGroup = Groups.FPGroup(["a1","a2","a3","a4","a5"]); + S = Nemo.gens(MCGroup) + + N = length(S) + A = prod(reverse(S))*prod(S) + + relations = [ + [Comm(S[i], S[j]) for i in 1:N for j in 1:N if abs(i-j) > 1]..., + [S[i]*S[i+1]*S[i]*inv(S[i+1]*S[i]*S[i+1]) for i in 1:N-1]..., + (S[1]*S[2]*S[3])^4*inv(S[5])^2, + Comm(A, S[1]), + A^2 + ] + + relations = [relations; [inv(rel) for rel in relations]] + Groups.add_rels!(MCGroup, Dict(rel => MCGroup() for rel in relations)) + return MCGroup + + elseif N < 2 + throw("Genus must be at least 2!") + end + + MCGroup = Groups.FPGroup(["a$i" for i in 0:2N]) + S = Nemo.gens(MCGroup) + + a0 = S[1] + A = S[2:end] + k = length(A) + + relations = [ + [Comm(A[i], A[j]) for i in 1:k for j in 1:k if abs(i-j) > 1]..., + [Comm(a0, A[i]) for i in 1:k if i != 4]..., + [A[i]*A[(i+1)]*A[i]*inv(A[i+1]*A[i]*A[i+1]) for i in 1:k-1]..., + A[4]*a0*A[4]*inv(a0*A[4]*a0) + ] + + # 3-chain relation + c = prod(reverse(A[1:4]))*prod(A[1:4]) + b0 = c*a0*inv(c) + push!(relations, (A[1]*A[2]*A[3])^4*inv(a0*b0)) + + # Lantern relation + b1 = inv(A[4]*A[5]*A[3]*A[4])*a0*(A[4]*A[5]*A[3]*A[4]) + b2 = inv(A[2]*A[3]*A[1]*A[2])*b1*(A[2]*A[3]*A[1]*A[2]) + u = inv(A[6]*A[5])*b1*(A[6]*A[5]) + x = prod(reverse(A[2:6]))*u*prod(inv.(A[1:4])) + b3 = x*a0*inv(x) + push!(relations, a0*b2*b1*inv(A[1]*A[3]*A[5]*b3)) + + # Hyperelliptic relation + X = prod(reverse(A))*prod(A) + + function n(i::Int, b=b0) + if i == 1 + return A[1] + elseif i == 2 + return b + else + return w(i-2)*n(i-2)*w(i-2) + end + end + + function w(i::Int) + (A[2i+4]*A[2i+3]*A[2i+2]* n(i+1))*(A[2i+1]*A[2i] *A[2i+2]*A[2i+1])* + (A[2i+3]*A[2i+2]*A[2i+4]*A[2i+3])*( n(i+1)*A[2i+2]*A[2i+1]*A[2i] ) + end + + push!(relations, X*n(N)*inv(n(N)*X)) + + relations = [relations; [inv(rel) for rel in relations]] + Groups.add_rels!(MCGroup, Dict(rel => MCGroup() for rel in relations)) + + return MCGroup, gens(MCGroup) +end + +function generatingset(parsed_args) + N = parsed_args["N"] + return generatingset(N) +end + +############################################################################### +# +# Misc +# +############################################################################### + +function groupname(parsed_args) + N = parsed_args["N"] + return groupname(N), N +end + +groupname(N::Int) = "MCG$(N)" + +end #of module MappingClassGroups