diff --git a/MCGn.jl b/MCGn.jl index 4b6cfe6..e60fe91 100644 --- a/MCGn.jl +++ b/MCGn.jl @@ -20,10 +20,6 @@ function parse_commandline() help = "Set number of cpus used by solver (default: auto)" arg_type = Int required = false - "-N" - help = "Consider mapping class group of surface of genus N" - arg_type = Int - default = 2 "--radius" help = "Radius of ball B_r(e,S) to find solution over" arg_type = Int @@ -31,58 +27,43 @@ function parse_commandline() "--warmstart" help = "Use warmstart.jl as the initial guess for SCS" action = :store_true + "-MCG" + help = "Compute for mapping class group of surface of genus N" + arg_type = Int + required = false + "--Higman" + help = "Compute for Higman Group" + action = :store_true + "--Caprace" + help = "Compute for Higman Group" + action = :store_true end return parse_args(args) end const PARSEDARGS = parse_commandline() -include("CPUselect.jl") -set_parallel_mthread(PARSEDARGS, workers=false) - -using Nemo -using SCS.SCSSolver +using AbstractAlgebra using PropertyT using Groups -include("FPGroups_GAP.jl") -include("groups/mappingclassgroup.jl") +include("CPUselect.jl") +set_parallel_mthread(PARSEDARGS, workers=false) -function main(GROUP, parsed_args) +include("main_gapgroup.jl") - radius = parsed_args["radius"] - tol = parsed_args["tol"] - iterations = parsed_args["iterations"] - upper_bound = parsed_args["upper-bound"] - warm = parsed_args["warmstart"] +if PARSEDARGS["Caprace"] + include("groups/caprace.jl") + main(CapraceGroup, PARSEDARGS) - name, N = GROUP.groupname(parsed_args) - isdir(name) || mkdir(name) +elseif PARSEDARGS["Higman"] + include("groups/higman.jl") + main(HigmanGroup, PARSEDARGS) - G, S = GROUP.generatingset(N) - relations = [k*inv(v) for (k,v) in G.rels] - prepare_pm_delta(name, GAP_groupcode(S, relations), radius) +elseif PARSEDARGS["N"] != nothing + include("groups/mappingclassgroup.jl") + main(MappingClassGroups, PARSEDARGS) - S = unique([S; inv.(S)]) - - Id = G() - - logger = PropertyT.setup_logging(joinpath(name, "$(upper_bound)")) - - info(logger, "Group: $name") - info(logger, "Iterations: $iterations") - info(logger, "Precision: $tol") - info(logger, "Upper bound: $upper_bound") - info(logger, "Radius: $radius") - info(logger, G) - info(logger, "Symmetric generating set of size $(length(S))") - info(logger, "Threads: $(Threads.nthreads())") - info(logger, "Workers: $(workers())") - - 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 +else + warn("You need to specify one of the --Higman, --Caprace, -MCG N") end - -main(MappingClassGroups, PARSEDARGS) diff --git a/groups/caprace.jl b/groups/caprace.jl new file mode 100644 index 0000000..48d6b31 --- /dev/null +++ b/groups/caprace.jl @@ -0,0 +1,62 @@ +module CapraceGroup + +using AbstractAlgebra +using Groups + +############################################################################### +# +# Generating set +# +############################################################################### + +Comm(x,y) = x*y*x^-1*y^-1 + +function generatingset() + + CapraceGroup = Groups.FPGroup(["x","y","z","t","r"]); + x,y,z,t,r = gens(CapraceGroup) + + relations = [ + x^7, + y^7, + t^2, + r^73, + t*r*t*r, + Comm(x,y)*z^-1, + Comm(x,z), + Comm(y,z), + Comm(x^2*y*z^-1, t), + Comm(x*y*z^3, t*r), + Comm(x^3*y*z^2, t*r^17), + Comm(x, t*r^-34), + Comm(y, t*r^-32), + Comm(z, t*r^-29), + Comm(x^-2*y*z, t*r^-25), + Comm(x^-1*y*z^-3, t*r^-19), + Comm(x^-3*y*z^-2, t*r^-11) + ]; + + relations = [relations; [inv(rel) for rel in relations]] + + Groups.add_rels!(CapraceGroup, Dict(rel => CapraceGroup() for rel in relations)) + + return CapraceGroup, gens(CapraceGroup) +end + +function generatingset(parsed_args) + return generatingset() +end + +############################################################################### +# +# Misc +# +############################################################################### + +function groupname(parsed_args) + return groupname(), 0 +end + +groupname() = "CapraceGroup" + +end # of module CapraceGroup diff --git a/groups/higman.jl b/groups/higman.jl new file mode 100644 index 0000000..041a015 --- /dev/null +++ b/groups/higman.jl @@ -0,0 +1,49 @@ +module HigmanGroup + +using AbstractAlgebra +using Groups + +############################################################################### +# +# Generating set +# +############################################################################### + +Comm(x,y) = x*y*x^-1*y^-1 + +function generatingset() + + HigmanGr = Groups.FPGroup(["a","b","c","d"]); + a,b,c,d = gens(HigmanGr) + + relations = [ + b^-1*Comm(b,a), + c^-1*Comm(c,b), + d^-1*Comm(d,c), + a^-1*Comm(a,d) + ]; + + relations = [relations; [inv(rel) for rel in relations]] + + Groups.add_rels!(HigmanGr, Dict(rel => HigmanGr() for rel in relations)) + + return HigmanGr, gens(HigmanGr) +end + +function generatingset(parsed_args) + return generatingset() +end + +############################################################################### +# +# Misc +# +############################################################################### + +function groupname(parsed_args) + return groupname(), 0 +end + +groupname() = "HigmanGroup" + +end # of module CapraceGroup diff --git a/groups/mappingclassgroup.jl b/groups/mappingclassgroup.jl index 1f2713d..ea44aff 100644 --- a/groups/mappingclassgroup.jl +++ b/groups/mappingclassgroup.jl @@ -12,9 +12,11 @@ using Groups Comm(x,y) = x*y*x^-1*y^-1 function generatingset(N::Int) - if N == 2 + if N < 2 + throw("Genus must be at least 2!") + elseif N == 2 MCGroup = Groups.FPGroup(["a1","a2","a3","a4","a5"]); - S = Nemo.gens(MCGroup) + S = gens(MCGroup) N = length(S) A = prod(reverse(S))*prod(S) @@ -31,12 +33,10 @@ function generatingset(N::Int) 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) + S = gens(MCGroup) a0 = S[1] A = S[2:end] diff --git a/main_gapgroup.jl b/main_gapgroup.jl new file mode 100644 index 0000000..80693e5 --- /dev/null +++ b/main_gapgroup.jl @@ -0,0 +1,40 @@ +using SCS.SCSSolver +# using Mosek +# using CSDP +# using SDPA + +include("FPGroups_GAP.jl") + +function main(GROUP, parsed_args) + + radius = parsed_args["radius"] + tol = parsed_args["tol"] + iterations = parsed_args["iterations"] + upper_bound = parsed_args["upper-bound"] + warm = parsed_args["warmstart"] + + name, N = GROUP.groupname(parsed_args) + G, S = GROUP.generatingset(N) + + isdir(name) || mkdir(name) + logger = PropertyT.setup_logging(joinpath(name, "$(upper_bound)"), :fulllog) + + relations = [k*inv(v) for (k,v) in G.rels] + prepare_pm_delta(name, GAP_groupcode(S, relations), radius) + + S = unique([S; inv.(S)]) + + info(logger, "Group: $name") + info(logger, "Iterations: $iterations") + info(logger, "Precision: $tol") + info(logger, "Upper bound: $upper_bound") + info(logger, "Radius: $radius") + info(logger, "Threads: $(Threads.nthreads())") + info(logger, "Workers: $(workers())") + info(logger, G) + info(logger, "Symmetric generating set of size $(length(S))") + + solver = SCSSolver(eps=tol, max_iters=iterations, linearsolver=SCS.Direct, alpha=1.95, acceleration_lookback=1) + + return PropertyT.check_property_T(name, S, G(), solver, upper_bound, tol, radius, warm) +end