mirror of
https://github.com/kalmarek/SmallHyperbolic
synced 2024-12-25 18:25:29 +01:00
add reworked FPGroups_GAP.jl
This commit is contained in:
parent
d36c949d36
commit
1a90b56820
178
src/FPGroups_GAP.jl
Normal file
178
src/FPGroups_GAP.jl
Normal file
@ -0,0 +1,178 @@
|
||||
using JLD
|
||||
using DelimitedFiles
|
||||
|
||||
abstract type WordReduction end
|
||||
struct KnuthBendix <: WordReduction end
|
||||
struct AutomaticStructure <: WordReduction end
|
||||
|
||||
const GAP_EXECUTABLE = get(ENV, "GAP_EXECUTABLE", "gap")
|
||||
|
||||
const PRODUCT_MATRIX_FUNCTIONS = """
|
||||
MetricBalls := function(rws, halfradius)
|
||||
local l, basis, sizes, i;
|
||||
l := EnumerateReducedWords(rws, 0, halfradius);;
|
||||
SortBy(l, Length);
|
||||
sizes := [1..halfradius];
|
||||
Apply(sizes, i -> Number(l, w -> Length(w) <= i));
|
||||
return [l, sizes];
|
||||
end;;
|
||||
|
||||
ProductMatrix := function(rws, basis, len)
|
||||
local result, dict, g, tmpList, t;
|
||||
result := [];
|
||||
dict := NewDictionary(basis[1], true);
|
||||
t := Runtime();
|
||||
for g in [1..Length(basis)] do;
|
||||
AddDictionary(dict, basis[g], g);
|
||||
od;
|
||||
Print("Creating dictionary: \t\t", StringTime(Runtime()-t), "\\n");
|
||||
for g in basis{[1..len]} do;
|
||||
tmpList := List(Inverse(g)*basis{[1..len]}, w->ReducedForm(rws, w));
|
||||
#t := Runtime();
|
||||
tmpList := List(tmpList, x -> LookupDictionary(dict, x));
|
||||
#Print(Runtime()-t, "\\n");
|
||||
Assert(1, ForAll(tmpList, x -> x <> fail));
|
||||
Add(result, tmpList);
|
||||
od;
|
||||
return result;
|
||||
end;;
|
||||
|
||||
SaveCSV := function(fname, pm)
|
||||
local file, i, j, k;
|
||||
file := OutputTextFile(fname, false);;
|
||||
for i in pm do;
|
||||
k := 1;
|
||||
for j in i do;
|
||||
if k < Length(i) then
|
||||
AppendTo(file, j, ", ");
|
||||
else
|
||||
AppendTo(file, j, "\\n");
|
||||
fi;
|
||||
k := k+1;
|
||||
od;
|
||||
od;
|
||||
CloseStream(file);
|
||||
end;;
|
||||
"""
|
||||
|
||||
function product_matrix_GAP_code(reduction::Type{<:WordReduction},
|
||||
G::FPGroup, dir, halfradius; maxeqns=100_000, infolevel=2)
|
||||
code = """
|
||||
LogTo("$(dir)/GAP.log");
|
||||
RequirePackage("kbmag");
|
||||
SetInfoLevel(InfoRWS, $infolevel);
|
||||
|
||||
$PRODUCT_MATRIX_FUNCTIONS
|
||||
$(GAP_code(G))
|
||||
|
||||
# G:= SimplifiedFpGroup(G);
|
||||
rws := KBMAGRewritingSystem(G);
|
||||
# ResetRewritingSystem(rws);
|
||||
O:=OptionsRecordOfKBMAGRewritingSystem(rws);;
|
||||
O.maxeqns := $maxeqns;
|
||||
O.maxstates := 1000*$maxeqns;
|
||||
#O.maxstoredlen := [100,100];
|
||||
|
||||
before := Runtimes();;
|
||||
$reduction(rws);
|
||||
after := Runtimes();;
|
||||
delta := after.user_time_children - before.user_time_children;;
|
||||
Print("$reduction time: \t", StringTime(delta), "\\n");
|
||||
|
||||
t := Runtime();
|
||||
res := MetricBalls(rws,$(2halfradius));;
|
||||
Print("Metric-Balls generation: \t", StringTime(Runtime()-t), "\\n");
|
||||
B := res[1];; sizes := res[2];;
|
||||
Print("Sizes of generated Balls: \t", sizes, "\\n");
|
||||
|
||||
t := Runtime();
|
||||
pm := ProductMatrix(rws, B, sizes[$halfradius]);;
|
||||
Print("Computing ProductMatrix: \t", StringTime(Runtime()-t), "\\n");
|
||||
|
||||
S := EnumerateReducedWords(rws, 1, 1);
|
||||
S := List(S, s -> Position(B,s));
|
||||
|
||||
SaveCSV("$(dir)/pm.csv", pm);
|
||||
SaveCSV("$(dir)/S.csv", [S]);
|
||||
SaveCSV("$(dir)/sizes.csv", [sizes]);
|
||||
SaveCSV("$(dir)/B_$(2halfradius).csv", [B]);
|
||||
|
||||
Print("DONE!\\n");
|
||||
|
||||
quit;""";
|
||||
return code
|
||||
end
|
||||
|
||||
function GAP_code(G::FPGroup)
|
||||
S = gens(G);
|
||||
rels = [k*inv(v) for (k,v) in G.rels]
|
||||
F = "FreeGroup("*join(["\"$v\"" for v in S], ", ") *");"
|
||||
m = match(r".*(\[.*\])$", string(rels))
|
||||
rels_gap = replace(m.captures[1], " "=>"\n")
|
||||
|
||||
gap_code = """
|
||||
F := $F;
|
||||
AssignGeneratorVariables(F);;
|
||||
relations := $rels_gap;;
|
||||
G := F/relations;
|
||||
"""
|
||||
return gap_code
|
||||
end
|
||||
|
||||
function GAP_execute(gap_code, dir)
|
||||
isdir(dir) || mkpath(dir)
|
||||
GAP_file = joinpath(dir, "GAP_code.g")
|
||||
@info "Writing GAP code to $GAP_file"
|
||||
|
||||
open(GAP_file, "w") do io
|
||||
write(io, gap_code)
|
||||
end
|
||||
run(pipeline(`cat $(GAP_file)`, `$GAP_EXECUTABLE -q`))
|
||||
end
|
||||
|
||||
function prepare_pm_delta_csv(reduction::Type{<:WordReduction},
|
||||
G::FPGroup, name::AbstractString, halfradius::Integer; kwargs...)
|
||||
|
||||
@info "Preparing multiplication table using GAP (via kbmag)"
|
||||
gap_code = product_matrix_GAP_code(reduction, G, name, halfradius; kwargs...)
|
||||
return GAP_execute(gap_code, name)
|
||||
end
|
||||
|
||||
function prepare_pm_delta(reduction::Type{<:WordReduction},
|
||||
G::FPGroup, name::AbstractString, halfradius::Integer; kwargs...)
|
||||
pm_fname = joinpath(name, "pm.csv")
|
||||
S_fname = joinpath(name, "S.csv")
|
||||
sizes_fname = joinpath(name, "sizes.csv")
|
||||
delta_fname = joinpath(name, "delta.jld")
|
||||
|
||||
csv_files_exist = isfile(pm_fname) && isfile(S_fname) && isfile(sizes_fname)
|
||||
|
||||
if !csv_files_exist
|
||||
@info "Creating csv files"
|
||||
prepare_pm_delta_csv(reduction, G, name, halfradius; kwargs...)
|
||||
elseif isfile(sizes_fname)
|
||||
sizes = readdlm(sizes_fname, ',')[1,:]
|
||||
if 2halfradius > length(sizes)
|
||||
prepare_pm_delta_csv(reduction, G, name, halfradius; kwargs...)
|
||||
end
|
||||
end
|
||||
|
||||
@assert isfile(pm_fname) && isfile(S_fname) && isfile(sizes_fname)
|
||||
|
||||
@info "Reading csv files"
|
||||
pm = Int.(readdlm(pm_fname, ','))
|
||||
S = Int.(readdlm(S_fname, ',')[1,:])
|
||||
sizes = Int.(readdlm(sizes_fname, ',')[1,:])
|
||||
|
||||
Δ = spzeros(Int, sizes[2halfradius])
|
||||
Δ[S] .= -1
|
||||
Δ[1] = length(S)
|
||||
|
||||
pm = pm[1:sizes[halfradius], 1:sizes[halfradius]]
|
||||
@info "Writing delta.jld for radius $(2halfradius)"
|
||||
save(joinpath(name, "delta.jld"), "coeffs", Δ, "pm", pm)
|
||||
end
|
||||
|
||||
function prepare_pm_delta(G::FPGroup, dir, halfradius; kwargs...)
|
||||
return prepare_pm_delta(KnuthBendix, G, dir, halfradius; kwargs... )
|
||||
end
|
Loading…
Reference in New Issue
Block a user