2017-12-29 17:45:09 +01:00
|
|
|
using JLD
|
|
|
|
|
|
|
|
function GAP_code(group_code, dir, R; maxeqns=10_000, infolevel=2)
|
|
|
|
code = """
|
2018-01-04 10:46:40 +01:00
|
|
|
LogTo("$(dir)/GAP.log");
|
2017-12-29 17:45:09 +01:00
|
|
|
RequirePackage("kbmag");
|
|
|
|
SetInfoLevel(InfoRWS, $infolevel);
|
|
|
|
|
2018-01-04 10:46:40 +01:00
|
|
|
|
2017-12-29 17:45:09 +01:00
|
|
|
MetricBalls := function(rws, R)
|
|
|
|
local l, basis, sizes, i;
|
|
|
|
l := EnumerateReducedWords(rws, 0, R);;
|
|
|
|
SortBy(l, Length);
|
|
|
|
sizes := [1..R];
|
|
|
|
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;;
|
|
|
|
|
|
|
|
$group_code
|
|
|
|
|
2018-01-04 10:46:40 +01:00
|
|
|
# G:= SimplifiedFpGroup(G);
|
2017-12-29 17:45:09 +01:00
|
|
|
RWS := KBMAGRewritingSystem(G);
|
|
|
|
# ResetRewritingSystem(RWS);
|
|
|
|
O:=OptionsRecordOfKBMAGRewritingSystem(RWS);;
|
|
|
|
O.maxeqns := $maxeqns;
|
|
|
|
#O.maxstoredlen := [100,100];
|
|
|
|
|
|
|
|
before := Runtimes();;
|
|
|
|
KnuthBendix(RWS);
|
|
|
|
after := Runtimes();;
|
|
|
|
delta := after.user_time_children - before.user_time_children;;
|
|
|
|
Print("Knuth-Bendix completion: \t", StringTime(delta), "\\n");
|
|
|
|
|
|
|
|
t := Runtime();
|
|
|
|
res := MetricBalls(RWS,$(2*R));;
|
|
|
|
Print("Metric-Balls generation: \t", StringTime(Runtime()-t), "\\n");
|
|
|
|
B := res[1];; sizes := res[2];;
|
2018-01-04 10:46:40 +01:00
|
|
|
Print("Sizes of generated Balls: \t", sizes, "\\n");
|
2017-12-29 17:45:09 +01:00
|
|
|
|
|
|
|
t := Runtime();
|
|
|
|
pm := ProductMatrix(RWS, B, sizes[$R]);;
|
|
|
|
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]);
|
|
|
|
|
|
|
|
Print("DONE!\\n");
|
|
|
|
|
|
|
|
quit;""";
|
|
|
|
return code
|
|
|
|
end
|
|
|
|
|
|
|
|
function GAP_groupcode(S, rels)
|
|
|
|
F = "FreeGroup("*join(["\"$v\""for v in S], ", ") *");"
|
|
|
|
m = match(r".*(\[.*\])$", string(rels))
|
|
|
|
rels = replace(m.captures[1], " ", "\n")
|
|
|
|
code = """
|
|
|
|
F := $F;
|
|
|
|
AssignGeneratorVariables(F);;
|
2018-01-04 10:46:40 +01:00
|
|
|
relations := $rels;;
|
2017-12-29 17:45:09 +01:00
|
|
|
G := F/relations;
|
|
|
|
"""
|
|
|
|
return code
|
|
|
|
end
|
|
|
|
|
|
|
|
function GAP_execute(gap_code, dir)
|
|
|
|
isdir(dir) || mkdir(dir)
|
|
|
|
GAP_file = joinpath(dir, "GAP_code.g")
|
|
|
|
@show dir
|
|
|
|
@show GAP_file;
|
|
|
|
|
|
|
|
open(GAP_file, "w") do io
|
|
|
|
write(io, gap_code)
|
|
|
|
end
|
2018-01-04 10:46:40 +01:00
|
|
|
run(pipeline(`cat $(GAP_file)`, `gap -q`))
|
2017-12-29 17:45:09 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
function prepare_pm_delta_csv(name, group_code, R; maxeqns=10_000, infolevel=2)
|
|
|
|
info("Preparing multiplication table using GAP (via kbmag)")
|
|
|
|
gap_code = GAP_code(group_code, name, R, maxeqns=maxeqns, infolevel=infolevel)
|
2018-01-04 10:46:40 +01:00
|
|
|
GAP_execute(gap_code, name)
|
2017-12-29 17:45:09 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
function prepare_pm_delta(name, group_code, R; maxeqns=100_000, infolevel=2)
|
|
|
|
|
|
|
|
pm_fname = joinpath(name, "pm.csv")
|
|
|
|
S_fname = joinpath(name, "S.csv")
|
|
|
|
sizes_fname = joinpath(name, "sizes.csv")
|
|
|
|
delta_fname = joinpath(name, "delta.jld")
|
|
|
|
|
|
|
|
if !isfile(pm_fname) || !isfile(S_fname) || !isfile(sizes_fname)
|
|
|
|
prepare_pm_delta_csv(name, group_code, R, maxeqns=maxeqns, infolevel=infolevel)
|
|
|
|
end
|
|
|
|
|
|
|
|
if isfile(sizes_fname)
|
|
|
|
sizes = readcsv(sizes_fname, Int)[1,:]
|
|
|
|
if 2R > length(sizes)
|
|
|
|
prepare_pm_delta_csv(name, group_code, R, maxeqns=maxeqns, infolevel=infolevel)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
pm = readcsv(pm_fname, Int)
|
|
|
|
S = readcsv(S_fname, Int)[1,:]
|
|
|
|
sizes = readcsv(sizes_fname, Int)[1,:]
|
|
|
|
|
|
|
|
Δ = spzeros(sizes[2R])
|
|
|
|
Δ[S] .= -1
|
|
|
|
Δ[1] = length(S)
|
|
|
|
|
|
|
|
pm = pm[1:sizes[R], 1:sizes[R]]
|
|
|
|
|
|
|
|
save(joinpath(name, "pm.jld"), "pm", pm)
|
|
|
|
save(joinpath(name, "delta.jld"), "Δ", Δ)
|
|
|
|
|
|
|
|
end
|