CoCalc Public Fileswww / cgi-bin / mfd / magma.m
Author: William A. Stein
Compute Environment: Ubuntu 18.04 (Deprecated)
1// freeze;
2
3function aplist_to_powerbasis(aplist, prec)
4   assert Type(aplist) eq Tup;
5   assert Type(prec) eq RngIntElt;
6   if Degree(aplist[1]) eq 1 then
7      return [ap[1] : ap in aplist[2]];
8   end if;
9   R<x> := PolynomialRing(RationalField());
10   K<a> := NumberField(aplist[1]);
11   phi := hom<R -> K | K.1>;
12   embed := [phi(b) : b in aplist[3]];
13   n := #[p : p in [2..prec] | IsPrime(p)];
14   n := Min(#aplist[2], n);
15   return [DotProd(aplist[2][i],embed) : i in [1..n]];
16end function;
17
18
19function DirChar(N,eps, eps_data, K)
20   assert Type(N) eq RngIntElt;
21
22   if Type(K) ne FldRat then
23      rootof1, order := Explode(eps_data);
24      if Type(Parent(rootof1)) in { RngInt, FldRat} then
25         phi := hom<Parent(rootof1) -> K|>;
26      else
27         phi := hom<Parent(rootof1) -> K | K.1>;
28      end if;
29      rootof1 := phi(rootof1);
30      G := DirichletGroup(N,K,rootof1,Integers()!order);
31   else
32      G := DirichletGroup(N,K);
33   end if;
34   return G!eps;
35end function;
36
37intrinsic aplist_to_qexpansion(aplist::Tup, N::RngIntElt, k::RngIntElt,
38                               eps::., prec::RngIntElt) -> RngSerPowElt
39{}
40   if prec eq 0 then
41      p := 1;
42      for i in [1..#aplist[2]] do
43         p := NextPrime(p);
44      end for;
45      prec := NextPrime(p)-1;
46   end if;
47
48   if #aplist eq 3 then
49      eps_data := <-1,2>;
50   else
51      eps_data := aplist[4]; // a pair <root of unity, order of root>.
52   end if;
53
54   aplist := aplist_to_powerbasis(aplist, Max(prec,2) );
55   K := Parent(aplist[1]);
56   if Type(K) eq RngInt then
57      K := RationalField();
58   end if;
59   e := DirChar(N,eps,eps_data,K);
60
61   R<q> := PowerSeriesRing(K);
62   f := q;
63   p := 2;
64   for i in [1..#aplist] do
65      f := f + aplist[i]*q^p;
66      p := NextPrime(p);
67   end for;
68   prec := Min(p,prec);
69   for n in [m : m in [4..prec-1] | not IsPrime(m)] do
70      fac := Factorization(n);
71      if #fac eq 1 then
72         // a_{p^r} := a_p * a_{p^{r-1}} - eps(p)p^{k-1} a_{p^{r-2}}.
73         p  := fac[1][1];
74         r  := fac[1][2];
75         an := Coefficient(f,p) * Coefficient(f,p^(r-1))
76                     - Evaluate(e,p)*p^(k-1)*Coefficient(f,p^(r-2));
77      else  // a_s*a_r := a_{sr} and we know all a_i for i<n.
78         s  := fac[1][1]^fac[1][2];
79         an := Coefficient(f,s)*Coefficient(f,n div s);
80      end if;
81      f := f + an*q^n;
82   end for;
83   return f + O(q^prec);
84end intrinsic;
85
86intrinsic aplist_to_q_integral_basis(aplist::Tup, N::RngIntElt, k::RngIntElt, eps::., prec::RngIntElt) -> RngSerPowElt
87{}
88   f := aplist_to_qexpansion(aplist, N, k, eps, prec);
89   prec := AbsolutePrecision(f);
90   K := Parent(Coefficient(f,0));
91   if Type(K) eq FldRat then
92      return [f];
93   end if;
94
95   q := PowerSeriesRing(Rationals()).1;
96   S := [&+[q^n*Eltseq(Coefficient(f,n))[i] : n in [0..prec-1]] : i in [1..Degree(K)]];
97   SS := SaturateSequence(S, prec);
98   SS := [f + O(q^prec) : f in SS];
99   ans := "";
100   for f in SS do
101      ans := ans * Sprintf("%o|",f);
102   end for;
103   return ans;
104end intrinsic;
105
106
107intrinsic inner_twists_data(N::RngIntElt, f::RngUPolElt, embedding::SeqEnum, aplist::SeqEnum) -> MonStgElt
108{}
109   // The intrinsic below is defined in inner_twists.m
110   end_alg, G, T, F, has_CM := InnerTwistsData(N, f, embedding, aplist);
111
112   num_twists := #T+1;
113   if #G gt 0 then
114      _, order_of_root := DistinguishedRoot(Parent(G[1]));
115   else
116      order_of_root := 2;
117   end if;
118   generators := [Eltseq(eps) : eps in G];
119   if not has_CM then
120      fixed_field := DefiningPolynomial(F);
121      fixed_degree := Degree(fixed_field);
122   else
123      fixed_field := "NULL";
124      fixed_degree := "NULL";
125   end if;
126   hilb_sym := "NULL";
127   if Type(F) eq FldNum and Degree(F) gt 1 then
128      AssignNames(~F,["x"]);
129   end if;
130
131   return Sprintf("%o|%o|%o|%o|%o|%o|%o|%o",order_of_root, num_twists, generators,
132                  fixed_field, fixed_degree, hilb_sym, end_alg, has_CM);
133
134end intrinsic;
135
136intrinsic torsion_upper_bound(aplist::Tup, N::RngIntElt, prec::RngIntElt) -> RngIntElt
137{}
138   function cp(alpha)
139      if Type(Parent(alpha)) eq FldRat then
140         return PolynomialRing(RationalField()).1-alpha;
141      end if;
142      return CharacteristicPolynomial(alpha);
143   end function;
144   p := 2;
145   bound := 0;
146   for ap in aplist_to_powerbasis(aplist, prec+1) do
147      if p gt 2 and N mod p ne 0 then
148         bound := GCD(bound,Integers()!Evaluate(cp(ap),p+1));
149      end if;
150      p := NextPrime(p);
151   end for;
152   return bound;
153end intrinsic;
154
155
156