-
Notifications
You must be signed in to change notification settings - Fork 2
/
GaloisGroup_ARM.mag
135 lines (129 loc) · 5.29 KB
/
GaloisGroup_ARM.mag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import "Utils.mag": not_implemented, Z;
declare type PGGAlg_GaloisGroup_ARM: PGGAlg_GaloisGroup;
declare attributes PGGAlg_GaloisGroup_ARM: groups_alg, resolvent_alg, use_easy_resolvents, upto;
intrinsic PGGAlg_GaloisGroup_ARM_Make( : GroupsAlg:=false, ResolventAlg:=false, UseEasyResolvents:=false, UpTo:=false) -> PGGAlg_GaloisGroup_ARM
{The resolvent method algorithm for computing Galois groups.}
alg := New(PGGAlg_GaloisGroup_ARM);
alg`groups_alg := GroupsAlg cmpne false select GroupsAlg else PGGAlg_ResGroups_All_Make();
alg`resolvent_alg := ResolventAlg cmpne false select ResolventAlg else PGGAlg_ResEval_Global_Make();
alg`use_easy_resolvents := UseEasyResolvents;
alg`upto := UpTo cmpne false select UpTo else PGGAlg_GaloisGroup_ARM_UpTo_ResolventEmbedding_Make(:CheckInjective);
return alg;
end intrinsic;
intrinsic Print(alg :: PGGAlg_GaloisGroup_ARM)
{Print.}
print "resolvent method";
IndentPush();
print "groups =", alg`groups_alg;
print "resolvents =", alg`resolvent_alg;
print "up to =", alg`upto;
printf "use easy resolvents = %o", alg`use_easy_resolvents;
IndentPop();
end intrinsic;
procedure getraminfo(~r, f);
// // UNCOMMENT THIS WHEN EXACTPADICS PACKAGE IS LOADED TO KEEP TRACK OF WHAT RAMIFICATION WE HAVE SEEN SO FAR
// if Type(f) eq PGGPolExact then
// // initial value
// if not assigned r then
// r := rec<recformat<min_resdeg, min_tamedeg, vs, min_wilddeg, min_ramdeg, min_deg> | min_resdeg:=1, min_tamedeg:=1, vs:={**}, min_wilddeg:=1, min_ramdeg:=1, min_deg:=1>;
// end if;
// K := Actual(BaseRing(f));
// p := Prime(K);
// _, _, certs := Factorization(Actual(f) : Extensions);
// for cert in certs do
// L := cert`Extension;
// r`min_resdeg := LCM(r`min_resdeg, cert`F);
// if cert`E gt 1 then
// uvs := Vertices(TransitionFunction(L, K));
// assert #uvs ge 2;
// us := [uv[1] : uv in uvs];
// vs := [uv[2] : uv in uvs];
// assert vs[1] eq 0;
// dudvs := [Z| (us[i]-us[i-1])/(vs[i]-vs[i-1]) : i in [2..#us]] cat [cert`E];
// idxs := [Z| dudvs[i] / dudvs[i-1] : i in [2..#dudvs]];
// print "vs =", vs;
// print "idxs =", idxs;
// if IsPowerOf(cert`E, p) then
// assert vs[2] gt 1;
// i0 := 1;
// else
// assert not IsDivisibleBy(idxs[1], p);
// assert vs[2] eq 1;
// r`min_tamedeg := LCM(r`min_tamedeg, idxs[1]);
// i0 := 2;
// end if;
// r`vs := r`vs join ({*vs[i+1]^^w where ok,w:=IsPowerOf(idxs[i],p) : i in [i0..#idxs]*} diff r`vs);
// end if;
// end for;
// r`min_wilddeg := p^#r`vs;
// r`min_ramdeg := r`min_tamedeg * r`min_wilddeg;
// r`min_deg := r`min_resdeg * r`min_ramdeg;
// print "raminfo =", r;
// end if;
end procedure;
intrinsic TryGaloisGroup(Alg :: PGGAlg_GaloisGroup_ARM, f :: PGGPol) -> BoolElt, GrpPerm
{The Galois group of f.}
PGG_GlobalTimer_Push("start resolvent");
rst := Start(Alg`resolvent_alg, f);
emb := OvergroupEmbedding(rst);
vprint PGG_GaloisGroup: "conjugacy group =", Domain(emb);
vprint PGG_GaloisGroup: "resolvent overgroup =", Codomain(emb);
vprint PGG_GaloisGroup: "overgroup embedding =", emb;
W := Group(Codomain(emb));
PGG_GlobalTimer_Swap("start groups");
gst := Start(Alg`groups_alg, emb, Alg`upto);
// if Alg`use_easy_resolvents then
// vprint PGG_GaloisGroup: "easy resolvents...";
// PGG_GlobalTimer_Swap("easy resolvents");
// RUs := EasyResolvents(conj);
// for RU in RUs do
// if IsDone(gst) then
// break;
// end if;
// R, U := Explode(RU);
// PGG_GlobalTimer_Swap("process resolvent");
// ProcessResolvent(gst, R, U);
// end for;
// end if;
getraminfo(~raminfo, f);
PGG_GlobalTimer_Swap("check done");
if not IsDone(gst) then
vprint PGG_GaloisGroup: "main loop...";
repeat
PGG_GlobalTimer_Swap("subgroup");
ok, U := HasSubgroup(gst);
if not ok then
return false, "ran out of subgroups";
end if;
if ISA(Type(U), SeqEnum) then
I := [];
R := [];
for i in [1..#U] do
vprint PGG_GaloisGroup: "subgroup", i, "index =", Index(W, U[i]);
PGG_GlobalTimer_Swap("invariant");
Append(~I, RelativeInvariant(W, U[i]));
vprint PGG_GaloisGroup: "invariant", i, "=", I[i];
PGG_GlobalTimer_Swap("resolvent");
Append(~R, Resolvent(rst, I[i], U[i]));
getraminfo(~raminfo, R[i]);
vprint PGG_GaloisGroup: "resolvent", i, "=", R[i];
end for;
else
vprint PGG_GaloisGroup: "subgroup index =", Index(W, U);
PGG_GlobalTimer_Swap("invariant");
I := RelativeInvariant(W, U);
vprint PGG_GaloisGroup: "invariant =", I;
PGG_GlobalTimer_Swap("resolvent");
R := Resolvent(rst, I, U);
getraminfo(~raminfo, R);
vprint PGG_GaloisGroup: "resolvent =", R;
end if;
PGG_GlobalTimer_Swap("process resolvent");
ProcessResolvent(gst, R, U);
PGG_GlobalTimer_Swap("check done");
until IsDone(gst);
end if;
vprint PGG_GaloisGroup: "success";
PGG_GlobalTimer_Pop();
return true, TheGroup(gst);
end intrinsic;