From 8f295b8bc6aff2a3ba2621757d2868896eeb8368 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Sat, 12 Feb 2022 15:17:30 +0100 Subject: [PATCH 1/5] move script creating json to a separate folder --- {data => scripts/create_json}/Manifest.toml | 0 {data => scripts/create_json}/Project.toml | 0 {data => scripts/create_json}/create_json.jl | 0 {data => scripts/create_json}/parse_presentations.jl | 0 {data => scripts/create_json}/smallhyperbolicgrp.jl | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename {data => scripts/create_json}/Manifest.toml (100%) rename {data => scripts/create_json}/Project.toml (100%) rename {data => scripts/create_json}/create_json.jl (100%) rename {data => scripts/create_json}/parse_presentations.jl (100%) rename {data => scripts/create_json}/smallhyperbolicgrp.jl (100%) diff --git a/data/Manifest.toml b/scripts/create_json/Manifest.toml similarity index 100% rename from data/Manifest.toml rename to scripts/create_json/Manifest.toml diff --git a/data/Project.toml b/scripts/create_json/Project.toml similarity index 100% rename from data/Project.toml rename to scripts/create_json/Project.toml diff --git a/data/create_json.jl b/scripts/create_json/create_json.jl similarity index 100% rename from data/create_json.jl rename to scripts/create_json/create_json.jl diff --git a/data/parse_presentations.jl b/scripts/create_json/parse_presentations.jl similarity index 100% rename from data/parse_presentations.jl rename to scripts/create_json/parse_presentations.jl diff --git a/data/smallhyperbolicgrp.jl b/scripts/create_json/smallhyperbolicgrp.jl similarity index 100% rename from data/smallhyperbolicgrp.jl rename to scripts/create_json/smallhyperbolicgrp.jl From 8555393004bed51c37db07fd14c222ef147c4cb3 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Sat, 12 Feb 2022 15:18:39 +0100 Subject: [PATCH 2/5] rm http_server.py --- docs/http_server.py | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 docs/http_server.py diff --git a/docs/http_server.py b/docs/http_server.py deleted file mode 100644 index 2c5da5e..0000000 --- a/docs/http_server.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python3 -# encoding: utf-8 -"""Use instead of `python3 -m http.server` when you need CORS""" - -from http.server import HTTPServer, SimpleHTTPRequestHandler - -class CORSRequestHandler(SimpleHTTPRequestHandler): - def end_headers(self): - self.send_header('Access-Control-Allow-Origin', '*') - self.send_header('Access-Control-Allow-Methods', 'GET') - self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate') - return super(CORSRequestHandler, self).end_headers() - - -httpd = HTTPServer(('localhost', 8003), CORSRequestHandler) -httpd.serve_forever() From 080032356b4f08cbfaede9a07b63242d15f39df1 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Sat, 12 Feb 2022 15:29:18 +0100 Subject: [PATCH 3/5] fix paths in create_json scripts --- scripts/create_json/create_json.jl | 25 ++++++++++++---------- scripts/create_json/parse_presentations.jl | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/scripts/create_json/create_json.jl b/scripts/create_json/create_json.jl index 110ac32..19f0e13 100644 --- a/scripts/create_json/create_json.jl +++ b/scripts/create_json/create_json.jl @@ -6,19 +6,22 @@ using JSON include(joinpath(@__DIR__, "parse_presentations.jl")) include(joinpath(@__DIR__, "smallhyperbolicgrp.jl")) +const DATA_DIR = joinpath(@__DIR__, "..", "..", "data") + +function _files_with_extension(dir::AbstractString, ext::AbstractString) + return [ + joinpath(dir, f) for f in readdir(dir) if + isfile(joinpath(dir, f)) && endswith(f, '.'*ext) + ] +end + all_grps_presentations = - let tables = [ - joinpath(@__DIR__, f) for f in readdir(@__DIR__) if - isfile(joinpath(@__DIR__, f)) && endswith(f, ".txt") - ] + let tables = _files_with_extension(DATA_DIR, "txt") mapreduce(parse_grouppresentations_abstract, union, tables) |> Dict end -tr_grps = - let csvs = [ - joinpath(@__DIR__, f) for f in readdir(@__DIR__) if - isfile(joinpath(@__DIR__, f)) && endswith(f, ".csv") - ] +grps = + let csvs = _files_with_extension(DATA_DIR, "csv") trGrps = mapreduce(union, csvs) do file m = match(r".*_(\d)_(\d)_(\d).csv", basename(file)) @@ -37,9 +40,9 @@ tr_grps = end end -open(joinpath(@__DIR__, "triangle_groups.json"), "w") do io +open(joinpath(DATA_DIR, "triangle_groups.json"), "w") do io f(args...) = show_json(args...; indent = 4) - s = sprint(f, TriangleGrpSerialization(), tr_grps) + s = sprint(f, TriangleGrpSerialization(), grps) # JSON.print(io, , 4) print(io, s) end diff --git a/scripts/create_json/parse_presentations.jl b/scripts/create_json/parse_presentations.jl index 139ce1f..8842396 100644 --- a/scripts/create_json/parse_presentations.jl +++ b/scripts/create_json/parse_presentations.jl @@ -1,4 +1,4 @@ -include("../src/groupparse.jl") +include(joinpath(@__DIR__, "..", "..", "src", "groupparse.jl")) function parse_grouppresentations_abstract(filename::AbstractString) lines = strip.(readlines(filename)) From 7e540e849349a1feb2595a756666f1722ee4dbf0 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Sun, 13 Feb 2022 11:33:21 +0100 Subject: [PATCH 4/5] add introduction to readme --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d7218ae..1680275 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,18 @@ The repository contains code for running experiments for [Marek Kaluba](https://kalmar.faculty.wmi.amu.edu.pl/) and [Stefan Witzel](https://www.math.uni-bielefeld.de/~switzel/). -There are three disjoint computations covered in this repository. +# Introduction +If you arrived here after reading the article looking for groups and + 1. you don't understand any of this, you probably want to visit [this page](https://kalmarek.github.io/SmallHyperbolic/) instead; + 2. you want just the machine-readable data, then the `json` file is available [here](https://github.com/kalmarek/SmallHyperbolic/blob/master/data/triangle_groups.json) (the file was generated by calling `julia ./scripts/create_json/create_json.jl`); + 3. you want to re-run some of the computations that lead to the results, then continue reading. + +# Computations + +There are three disjoint computations covered in this repository: + 1. certified eigenvalue computations for _PSL₂(p)_, + 2. sum of squares computations in an attempt to prove property (T) by estimating spectral gap of the group Laplacian, + 3. generation of magma files used to compute e.g. witnesses for non-hyperbolicity, rank of abelianization, etc. ## Eigenvalues computations for _PSL₂(p)_ From 91fb10742e43bd76968b2051b9fcd401ee92f6e0 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Sun, 13 Feb 2022 11:38:31 +0100 Subject: [PATCH 5/5] formatting --- adj_psl2_eigvals.jl | 62 +++++++++++++++--------------- scripts/create_json/create_json.jl | 40 +++++++++---------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/adj_psl2_eigvals.jl b/adj_psl2_eigvals.jl index 4c933b2..2c889bd 100644 --- a/adj_psl2_eigvals.jl +++ b/adj_psl2_eigvals.jl @@ -57,40 +57,41 @@ function SL2p_gens(p::Integer) end end - return a,b + return a, b end -function adjacency(ϱ, a, b; prec=256) - order_a = findfirst(i-> isone(a^i), 1:100) - order_b = findfirst(i-> isone(b^i), 1:100) +function adjacency(ϱ, a, b; prec = 256) + order_a = findfirst(i -> isone(a^i), 1:100) + order_b = findfirst(i -> isone(b^i), 1:100) @assert !isnothing(order_a) && order_a > 1 @assert !isnothing(order_b) && order_b > 1 - k = order_a-1 + order_b-1 + k = order_a - 1 + order_b - 1 - A = AcbMatrix(ϱ(a), prec=prec) - B = AcbMatrix(ϱ(b), prec=prec) + A = AcbMatrix(ϱ(a), prec = prec) + B = AcbMatrix(ϱ(b), prec = prec) res = sum(A^i for i = 1:order_a-1) + sum(B^i for i = 1:order_b-1) - return Arblib.scalar_div!(res, res, k) + #return Arblib.scalar_div!(res, res, k) + return res end function parse_our_args() s = ArgParseSettings() @add_arg_table! s begin "-p" - help = "the prime p for which to use PSL(2,p)" - arg_type = Int - required = true + help = "the prime p for which to use PSL(2,p)" + arg_type = Int + required = true "-a" - help = "generator a (optional)" + help = "generator a (optional)" "-b" - help = "generator b (optional)" + help = "generator b (optional)" "--ab" - help = "array of generators a and b (optional)" + help = "array of generators a and b (optional)" "--precision" - help = "set the precision of computations" - arg_type = Int - default = 128 + help = "set the precision of computations" + arg_type = Int + default = 128 end result = parse_args(s) @@ -113,7 +114,8 @@ end parsed_args = parse_our_args() const p = let p = parsed_args["p"] - isprime(p) || @error "You need to provide a prime, ex: `julia adj_psl2_eigvals.jl -p 31`" + isprime(p) || + @error "You need to provide a prime, ex: `julia adj_psl2_eigvals.jl -p 31`" p end @@ -124,14 +126,14 @@ open(LOGFILE, "w") do io @info "Logging into $LOGFILE" with_logger(SimpleLogger(io)) do - @info "Arguments:" args=parsed_args + @info "Arguments:" args = parsed_args - a,b = SL2p_gens(p) + a, b = SL2p_gens(p) a = SL₂{p}(get(parsed_args, "a", a)) b = SL₂{p}(get(parsed_args, "b", b)) @info "Generators" a b - Borel_cosets = let p = p, (a,b) = (a,b) + Borel_cosets = let p = p, (a, b) = (a, b) SL2p, sizes = RamanujanGraphs.generate_balls([a, b, inv(a), inv(b)], radius = 21) @assert sizes[end] == RamanujanGraphs.order(SL₂{p}) @@ -143,11 +145,11 @@ open(LOGFILE, "w") do io for j = 0:(p-1)÷4 h = PrincipalRepr( - α => unit_root((p - 1) ÷ 2, j, prec=PRECISION), + α => unit_root((p - 1) ÷ 2, j, prec = PRECISION), Borel_cosets, ) - @time adj = adjacency(h, a, b, prec=PRECISION) + @time adj = adjacency(h, a, b, prec = PRECISION) try @time evs = let evs = safe_eigvals(adj) @@ -168,20 +170,20 @@ open(LOGFILE, "w") do io if p % 4 == 1 ub = (p - 1) ÷ 4 - ζ = unit_root((p + 1) ÷ 2, 1, prec=PRECISION) + ζ = unit_root((p + 1) ÷ 2, 1, prec = PRECISION) else # p % 4 == 3 ub = (p + 1) ÷ 4 - ζ = unit_root((p + 1), 1, prec=PRECISION) + ζ = unit_root((p + 1), 1, prec = PRECISION) end for k = 1:ub h = DiscreteRepr( - RamanujanGraphs.GF{p}(1) => unit_root(p, prec=PRECISION), + RamanujanGraphs.GF{p}(1) => unit_root(p, prec = PRECISION), β => ζ^k, ) - @time adj = adjacency(h, a, b, prec=PRECISION) + @time adj = adjacency(h, a, b, prec = PRECISION) try @time evs = let evs = safe_eigvals(adj) @@ -196,11 +198,11 @@ open(LOGFILE, "w") do io end end end - all_large_evs = sort(all_large_evs, rev=true) + all_large_evs = sort(all_large_evs, rev = true) λ = all_large_evs[2] - ε = (λ - 3)/5 + ε = (λ - 3) / 5 α = acos(ε) - α_deg = (α/pi)*180 + α_deg = (α / pi) * 180 @info "Certified values:" λ ε α α_deg end # with_logger end # open(logfile) diff --git a/scripts/create_json/create_json.jl b/scripts/create_json/create_json.jl index 19f0e13..f288767 100644 --- a/scripts/create_json/create_json.jl +++ b/scripts/create_json/create_json.jl @@ -10,35 +10,33 @@ const DATA_DIR = joinpath(@__DIR__, "..", "..", "data") function _files_with_extension(dir::AbstractString, ext::AbstractString) return [ - joinpath(dir, f) for f in readdir(dir) if - isfile(joinpath(dir, f)) && endswith(f, '.'*ext) + joinpath(dir, f) for + f in readdir(dir) if isfile(joinpath(dir, f)) && endswith(f, '.' * ext) ] end -all_grps_presentations = - let tables = _files_with_extension(DATA_DIR, "txt") - mapreduce(parse_grouppresentations_abstract, union, tables) |> Dict - end +all_grps_presentations = let tables = _files_with_extension(DATA_DIR, "txt") + mapreduce(parse_grouppresentations_abstract, union, tables) |> Dict +end -grps = - let csvs = _files_with_extension(DATA_DIR, "csv") +grps = let csvs = _files_with_extension(DATA_DIR, "csv") - trGrps = mapreduce(union, csvs) do file - m = match(r".*_(\d)_(\d)_(\d).csv", basename(file)) - @assert !isnothing(m) - type = parse.(Int, tuple(m[1], m[2], m[3])) + trGrps = mapreduce(union, csvs) do file + m = match(r".*_(\d)_(\d)_(\d).csv", basename(file)) + @assert !isnothing(m) + type = parse.(Int, tuple(m[1], m[2], m[3])) - data = readdlm(file, '&') - labels = Symbol.(replace.(strip.(data[1, :]), ' ' => '_', '-' => '_')) - groups = data[2:end, :] - grps = map(enumerate(eachrow(groups))) do (i, props) - nt = (; (Symbol(l) => v for (l, v) in zip(labels, props))...) - @debug i, grp_name(nt) - P = all_grps_presentations[grp_name(nt)] - grp = TriangleGrp(type, P.generators, P.relations, nt) - end + data = readdlm(file, '&') + labels = Symbol.(replace.(strip.(data[1, :]), ' ' => '_', '-' => '_')) + groups = data[2:end, :] + grps = map(enumerate(eachrow(groups))) do (i, props) + nt = (; (Symbol(l) => v for (l, v) in zip(labels, props))...) + # @debug i, grp_name(nt) + P = all_grps_presentations[grp_name(nt)] + grp = TriangleGrp(type, P.generators, P.relations, nt) end end +end open(joinpath(DATA_DIR, "triangle_groups.json"), "w") do io f(args...) = show_json(args...; indent = 4)