// freeze; function aplist_to_powerbasis(aplist, prec) assert Type(aplist) eq Tup; assert Type(prec) eq RngIntElt; if Degree(aplist[1]) eq 1 then return [ap[1] : ap in aplist[2]]; end if; R := PolynomialRing(RationalField()); K := NumberField(aplist[1]); phi := hom K | K.1>; embed := [phi(b) : b in aplist[3]]; n := #[p : p in [2..prec] | IsPrime(p)]; n := Min(#aplist[2], n); return [DotProd(aplist[2][i],embed) : i in [1..n]]; end function; function DirChar(N,eps, eps_data, K) assert Type(N) eq RngIntElt; if Type(K) ne FldRat then rootof1, order := Explode(eps_data); if Type(Parent(rootof1)) in { RngInt, FldRat} then phi := hom K|>; else phi := hom K | K.1>; end if; rootof1 := phi(rootof1); G := DirichletGroup(N,K,rootof1,Integers()!order); else G := DirichletGroup(N,K); end if; return G!eps; end function; intrinsic aplist_to_qexpansion(aplist::Tup, N::RngIntElt, k::RngIntElt, eps::., prec::RngIntElt) -> RngSerPowElt {} if prec eq 0 then p := 1; for i in [1..#aplist[2]] do p := NextPrime(p); end for; prec := NextPrime(p)-1; end if; if #aplist eq 3 then eps_data := <-1,2>; else eps_data := aplist[4]; // a pair . end if; aplist := aplist_to_powerbasis(aplist, Max(prec,2) ); K := Parent(aplist[1]); if Type(K) eq RngInt then K := RationalField(); end if; e := DirChar(N,eps,eps_data,K); R := PowerSeriesRing(K); f := q; p := 2; for i in [1..#aplist] do f := f + aplist[i]*q^p; p := NextPrime(p); end for; prec := Min(p,prec); for n in [m : m in [4..prec-1] | not IsPrime(m)] do fac := Factorization(n); if #fac eq 1 then // a_{p^r} := a_p * a_{p^{r-1}} - eps(p)p^{k-1} a_{p^{r-2}}. p := fac[1][1]; r := fac[1][2]; an := Coefficient(f,p) * Coefficient(f,p^(r-1)) - Evaluate(e,p)*p^(k-1)*Coefficient(f,p^(r-2)); else // a_s*a_r := a_{sr} and we know all a_i for i RngSerPowElt {} f := aplist_to_qexpansion(aplist, N, k, eps, prec); prec := AbsolutePrecision(f); K := Parent(Coefficient(f,0)); if Type(K) eq FldRat then return [f]; end if; q := PowerSeriesRing(Rationals()).1; S := [&+[q^n*Eltseq(Coefficient(f,n))[i] : n in [0..prec-1]] : i in [1..Degree(K)]]; SS := SaturateSequence(S, prec); SS := [f + O(q^prec) : f in SS]; ans := ""; for f in SS do ans := ans * Sprintf("%o|",f); end for; return ans; end intrinsic; intrinsic inner_twists_data(N::RngIntElt, f::RngUPolElt, embedding::SeqEnum, aplist::SeqEnum) -> MonStgElt {} // The intrinsic below is defined in inner_twists.m end_alg, G, T, F, has_CM := InnerTwistsData(N, f, embedding, aplist); num_twists := #T+1; if #G gt 0 then _, order_of_root := DistinguishedRoot(Parent(G[1])); else order_of_root := 2; end if; generators := [Eltseq(eps) : eps in G]; if not has_CM then fixed_field := DefiningPolynomial(F); fixed_degree := Degree(fixed_field); else fixed_field := "NULL"; fixed_degree := "NULL"; end if; hilb_sym := "NULL"; if Type(F) eq FldNum and Degree(F) gt 1 then AssignNames(~F,["x"]); end if; return Sprintf("%o|%o|%o|%o|%o|%o|%o|%o",order_of_root, num_twists, generators, fixed_field, fixed_degree, hilb_sym, end_alg, has_CM); end intrinsic; intrinsic torsion_upper_bound(aplist::Tup, N::RngIntElt, prec::RngIntElt) -> RngIntElt {} function cp(alpha) if Type(Parent(alpha)) eq FldRat then return PolynomialRing(RationalField()).1-alpha; end if; return CharacteristicPolynomial(alpha); end function; p := 2; bound := 0; for ap in aplist_to_powerbasis(aplist, prec+1) do if p gt 2 and N mod p ne 0 then bound := GCD(bound,Integers()!Evaluate(cp(ap),p+1)); end if; p := NextPrime(p); end for; return bound; end intrinsic;