From f4b0f4aa1d7bef0ae2c022fb43a4e753c73e417d Mon Sep 17 00:00:00 2001 From: kalmarek Date: Mon, 6 Nov 2017 01:58:50 +0100 Subject: [PATCH] Move groptheoretic stuff to SLN.jl --- SLNs.jl | 117 +++++++++++++++++++++++++++++++++ SL_orbit.jl | 181 ++++++++-------------------------------------------- 2 files changed, 143 insertions(+), 155 deletions(-) create mode 100644 SLNs.jl diff --git a/SLNs.jl b/SLNs.jl new file mode 100644 index 0000000..cd40348 --- /dev/null +++ b/SLNs.jl @@ -0,0 +1,117 @@ +module SLNs + +using Nemo +using Groups + +############################################################################### +# +# Generating set +# +############################################################################### + +function E(i::Int, j::Int, M::MatSpace, val=one(M.base_ring)) + @assert i≠j + m = one(M) + m[i,j] = val + return m +end + +function SLsize(n,p) + result = BigInt(1) + for k in 0:n-1 + result *= p^n - p^k + end + return div(result, p-1) +end + +function generatingset(n::Int, X::Bool=false) + indexing = [(i,j) for i in 1:n for j in 1:n if i≠j] + G = MatrixSpace(ZZ, n, n) + if X + S = [E(i,j,G,v) for (i,j) in indexing for v in [1, 100]] + else + S = [E(i,j,G,v) for (i,j) in indexing for v in [1]] + end + S = vcat(S, [inv(x) for x in S]) + return G, unique(S) +end + +function generatingset(n::Int, p::Int, X::Bool=false) + (p > 1 && n > 1) || throw("Both n and p should be positive integers!") + info("Size(SL($n,$p)) = $(SLsize(n,p))") + F = ResidueRing(ZZ, p) + G = MatrixSpace(F, n, n) + indexing = [(i,j) for i in 1:n for j in 1:n if i≠j] + S = [E(i, j, G) for (i,j) in indexing] + S = vcat(S, [inv(x) for x in S]) + return G, unique(S) +end + +function generatingset(parsed_args) + N = parsed_args["N"] + p = parsed_args["p"] + X = parsed_args["X"] + + if p == 0 + return generatingset(N, X) + else + return generatingset(N, p, X) + end +end + +############################################################################### +# +# Action of WreathProductElems on Nemo.MatElem +# +############################################################################### + +function matrix_emb(MM::MatSpace, g::WreathProductElem) + parent(g).P.n == MM.cols == MM.rows || throw("No natural embedding of $(parent(g)) in ") + powers = [(elt == parent(elt)() ? 0: 1) for elt in g.n.elts] + elt = diagm([(-1)^(elt == parent(elt)() ? 0: 1) for elt in g.n.elts]) + return MM(elt)*MM(Nemo.matrix_repr(g.p)') +end + +function (g::WreathProductElem)(A::MatElem) + G = matrix_emb(parent(A), g) + inv_G = matrix_emb(parent(A), inv(g)) + return G*A*inv_G +end + +function (p::perm)(A::MatElem) + length(p.d) == A.r == A.c || throw("Can't act via $p on matrix of size ($(A.r), $(A.c))") + R = parent(A) + return p*A*inv(p) +end + +function autS(parsed_args) + N = parsed_args["N"] + return WreathProduct(PermutationGroup(2), PermutationGroup(N)) + # return WreathProduct(FiniteField(2,1, "a")[1], PermutationGroup(N)) +end + +############################################################################### +# +# Misc +# +############################################################################### + +function groupname(parsed_args) + N = parsed_args["N"] + p = parsed_args["p"] + X = parsed_args["X"] + + if p == 0 + if X + name = "oSL$(N)Z⟨X⟩" + else + name = "oSL$(N)Z" + end + else + name = "oSL$(N)_$p" + end + + return name, N +end + +end # of module SLNs diff --git a/SL_orbit.jl b/SL_orbit.jl index fe1b829..2f80de1 100644 --- a/SL_orbit.jl +++ b/SL_orbit.jl @@ -1,86 +1,4 @@ using ArgParse -using SCS.SCSSolver -# using Mosek - -using Nemo -if VERSION >= v"0.6.0" - import Nemo.Generic.perm -end - -addprocs(4) -using PropertyT - -using Groups - -############################################################################### -# -# Action of WreathProductElems on Nemo.MatElem -# -############################################################################### - -function matrix_emb(MM::MatSpace, g::WreathProductElem) - parent(g).P.n == MM.cols == MM.rows || throw("No natural embedding of $(parent(g)) in ") - powers = [(elt == parent(elt)() ? 0: 1) for elt in g.n.elts] - elt = diagm([(-1)^(elt == parent(elt)() ? 0: 1) for elt in g.n.elts]) - return MM(elt)*MM(Nemo.matrix_repr(g.p)') -end - -function (g::WreathProductElem)(A::MatElem) - G = matrix_emb(parent(A), g) - inv_G = matrix_emb(parent(A), inv(g)) - return G*A*inv_G -end - -function (p::perm)(A::MatElem) - length(p.d) == A.r == A.c || throw("Can't act via $p on matrix of size ($(A.r), $(A.c))") - R = parent(A) - return p*A*inv(p) -end - -############################################################################### -# -# Generating set -# -############################################################################### - -function E(i::Int, j::Int, M::MatSpace, val=one(M.base_ring)) - @assert i≠j - m = one(M) - m[i,j] = val - return m -end - -function SLsize(n,p) - result = BigInt(1) - for k in 0:n-1 - result *= p^n - p^k - end - return div(result, p-1) -end - -function SL_generatingset(n::Int, X::Bool=false) - indexing = [(i,j) for i in 1:n for j in 1:n if i≠j] - G = MatrixSpace(ZZ, n, n) - if X - S = [E(i,j,G,v) for (i,j) in indexing for v in [1, 100]] - else - S = [E(i,j,G,v) for (i,j) in indexing for v in [1]] - end - S = vcat(S, [inv(x) for x in S]) - return G, unique(S) -end - -function SL_generatingset(n::Int, p::Int, X::Bool=false) - p == 0 && return SL_generatingset(n, X) - (p > 1 && n > 1) || throw("Both n and p should be positive integers!") - info("Size(SL($n,$p)) = $(SLsize(n,p))") - F = ResidueRing(ZZ, p) - G = MatrixSpace(F, n, n) - indexing = [(i,j) for i in 1:n for j in 1:n if i≠j] - S = [E(i, j, G) for (i,j) in indexing] - S = vcat(S, [inv(x) for x in S]) - return G, unique(S) -end ############################################################################### # @@ -88,17 +6,6 @@ end # ############################################################################### -function cpuinfo_physicalcores() - maxcore = -1 - for line in eachline("/proc/cpuinfo") - if startswith(line, "core id") - maxcore = max(maxcore, parse(Int, split(line, ':')[2])) - end - end - maxcore < 0 && error("failure to read core ids from /proc/cpuinfo") - return maxcore + 1 -end - function parse_commandline() settings = ArgParseSettings() @@ -139,68 +46,32 @@ function parse_commandline() return parse_args(settings) end -############################################################################### -# -# main -# -############################################################################### +parsed_args = parse_commandline() -function main() - parsed_args = parse_commandline() - - if parsed_args["cpus"] ≠ nothing - if parsed_args["cpus"] > cpuinfo_physicalcores() - warn("Number of specified cores exceeds the physical core cound. Performance will suffer.") - end - BLAS.set_num_threads(parsed_args["cpus"]) - end - - N = parsed_args["N"] - p = parsed_args["p"] - - if p == 0 - if parsed_args["X"] - dirname = "oSL$(N)Z⟨X⟩" - else - dirname = "oSL$(N)Z" - end - else - dirname = "oSL$(N)_$p" - end - - radius = parsed_args["radius"] - tol = parsed_args["tol"] - iterations = parsed_args["iterations"] - upper_bound = parsed_args["upper-bound"] - - dirname = "$(dirname)_r$radius" - isdir(dirname) || mkdir(dirname) - - logger = PropertyT.setup_logging(joinpath(dirname, "$(upper_bound)")) - - info(logger, "Group: $dirname") - info(logger, "Iterations: $iterations") - info(logger, "Precision: $tol") - info(logger, "Upper bound: $upper_bound") - info(logger, "Threads: $(Threads.nthreads())") - info(logger, "Workers: $(workers())") - - G, S = SL_generatingset(N, p, parsed_args["X"]) - info(logger, G) - info(logger, "Symmetric generating set of size $(length(S))") - # info(logger, S) - AutS = WreathProduct(FiniteField(2,1, "a")[1], PermutationGroup(N)) - # AutS = PermutationGroup(N) - - solver = SCSSolver(eps=tol, max_iters=iterations, linearsolver=SCS.Direct) - # solver = Mosek.MosekSolver( - # MSK_DPAR_INTPNT_CO_TOL_REL_GAP=tol, - # MSK_IPAR_INTPNT_MAX_ITERATIONS=iterations, - # QUIET=false) - - sett = Settings(dirname, N, G, S, AutS, radius, solver, upper_bound, tol) - - PropertyT.check_property_T(sett) +function cpuinfo_physicalcores() + maxcore = -1 + for line in eachline("/proc/cpuinfo") + if startswith(line, "core id") + maxcore = max(maxcore, parse(Int, split(line, ':')[2])) + end + end + maxcore < 0 && error("failure to read core ids from /proc/cpuinfo") + return maxcore + 1 end -main() +if parsed_args["cpus"] == nothing + N = cpuinfo_physicalcores() + parsed_args["cpus"] = N + info("Setting --cpus to $N") +elseif parsed_args["cpus"] > cpuinfo_physicalcores() + warn("Number of specified cores exceeds the physical core count. Performance will suffer.") + end +end + +addprocs(parsed_args["cpus"]) +BLAS.set_num_threads(parsed_args["cpus"]) + +include("SLNs.jl") + +include("Orbit.jl") +main(SLNs, parsed_args)