1/***********************************************************
2 j0n_invariants.m -- compute invariants of factors of J_0(N)
3
4    For each level N, compute lots of information about
5    the simple factors of J_0(N).
6
7    William Stein, 28 January 2001.
8
9 ***********************************************************/
10
11forward OddPart,
12        PrimeSeq;
13
14J0N := recformat<
15   levels,
16   new_dimensions,
17   dimensions,
18   intersection_graph,
19   ap_traces,
20   hecke_fields,
21   atkin_lehners,
22   component_group_orders,
23   tamagawa_numbers,
24   torsion_upper_bounds,
25   torsion_lower_bounds,
26   l_ratios,
27   analytic_sha_upper_bounds,
28   analytic_sha_lower_bounds,
29   eigenvalues,
30   q_expansions
31>;
32
33
34intrinsic J0(N::RngIntElt : Sign := +1, bound := 38) -> Rec
35{Lots of data about the factors of J_0(N).}
36   M := ModularSymbols(N,2,Sign);
37   S := CuspidalSubspace(M);
38   D := NewformDecomposition(S : Proof := false);
39   D := SortDecomposition(D);
40   R<x> := PolynomialRing(Rationals());
41
42   intersection_graph :=
43                      [OddPart(#IntersectionGroup(A,B) cmpeq Infinity()
44                            select 0 else #IntersectionGroup(A,B), Sign) :
45                                                            A in D, B in D];
46
47   ap_traces := [[Trace(DualHeckeOperator(A,p)) : p in PrimeSeq(2,bound)]
48   		   : A in D | IsNew(A)];
49
50   atkin_lehners := [[AtkinLehner(A,p[1])[1,1] : p in Factorization(N)]
51     		        : A in D | IsNew(A)];
52
53   q_expansions := [* *];
54   eigenvalues := [* *];
55   for A in D do
56      if IsNew(A) then
57         f := qEigenform(A,bound);
58         Append(~q_expansions, f) ;
59         Append(~eigenvalues, [Coefficient(f,p) : p in PrimeSeq(2,bound)]);
60      end if;
61   end for;
62   hecke_fields := [];
63   for f in q_expansions do
64      if BaseRing(Parent(f)) cmpeq RationalField() then
65         Append(~hecke_fields, x-1);
66      else
67         Append(~hecke_fields, R!Modulus(BaseRing(Parent(f))));
68      end if;
69   end for;
70
71   square_free := [p[1] : p in Factorization(N) | p[2] eq 1];
72   component_group_orders := [[OddPart(ComponentGroupOrder(A,p), Sign) : p in square_free]
73                                 : A in D | IsNew(A)];
74   tamagawa_numbers := [[OddPart(TamagawaNumber(A,p), Sign) : p in square_free]
75                                 : A in D | IsNew(A)];
76   torsion_upper_bounds := [OddPart(TorsionBound(A,bound), Sign) : A in D |IsNew(A)];
77   e := M!<1,[Cusps()|0,Infinity()]>;
78   torsion_lower_bounds := [OddPart(#SubgroupOfTorus(A,e), Sign) : A in D |IsNew(A)];
79
80   l_ratios := [OddPart(LRatio(A,1), Sign) : A in D | IsNew(A)];
81
82   analytic_sha_lower_bounds :=
83          [(l_ratios[i]*torsion_lower_bounds[i]^2)/&*tamagawa_numbers[i] :
84              i in [1..#l_ratios]];
85   analytic_sha_upper_bounds :=
86          [(l_ratios[i]*torsion_upper_bounds[i]^2)/&*tamagawa_numbers[i] :
87              i in [1..#l_ratios]];
88
89   ans := rec<J0N |
90      levels := [Level(AssociatedNewSpace(A)) : A in D],
91      dimensions := [Dimension(A) : A in D],
92      new_dimensions := [Dimension(AssociatedNewSpace(A)) : A in D],
93      intersection_graph := intersection_graph,
94      ap_traces := ap_traces,
95      hecke_fields := hecke_fields,
96      atkin_lehners := atkin_lehners,
97      component_group_orders := component_group_orders,
98      tamagawa_numbers := tamagawa_numbers,
99      torsion_lower_bounds := torsion_lower_bounds,
100      torsion_upper_bounds := torsion_upper_bounds,
101      l_ratios := l_ratios,
102      analytic_sha_upper_bounds := analytic_sha_upper_bounds,
103      analytic_sha_lower_bounds := analytic_sha_lower_bounds,
104      q_expansions := q_expansions,
105      eigenvalues := eigenvalues
106   >;
107
108   DisownChildren(M);
109
110   return ans;
111end intrinsic;
112
113
114function OddPart(n, sign)
115   if sign eq 0 then
116      return n;
117   end if;
118   return n eq 0 select 0 else Parent(n)!(n / 2^Valuation(n,2));
119end function;
120
121function PrimeSeq(n,m)
122   return [p : p in [n..m] |IsPrime(p)];
123end function;
124
125
126function Go(N, file)
127   return Sprintf("echo \"SetVerbose(\\\\\"ModularForms\\\\\",2); Attach(\\\\\"j0n_invariants.m\\\\\"); t := Cputime(); a := J0(%o); fprintf Open(\\\\\"%o\\\\\", \\\\\"a\\\\\"), \\\\\"\\\\n\\\\nJ[\\%o] := \\%o ;  // time = \\%o seconds\\\\n\\\\n\\\\n\\\\\", %o, a, Cputime(t); quit;\" | magma\n", N, file, N);
128end function;
129
130intrinsic MakeGoFile(Nstart, Nstop)
131{}
132   fname := "go_" cat IntegerToString(Nstart) cat "-" cat IntegerToString(Nstop);
133   out   := "j0_" cat IntegerToString(Nstart) cat "-" cat IntegerToString(Nstop) cat ".out";
134   file := Open(fname, "w");
135   for n in [m : m in [Nstart..Nstop] |IsSquareFree(m)] do
136      fprintf file, "%o\n", Go(n,out);
137   end for;
138end intrinsic;
139
140intrinsic IsSquareFree(N) -> BoolElt
141{}
142   return &*[Integers()|p[2] : p in Factorization(N)] eq 1;
143end intrinsic;
144
145// for n in [m : m in [1..500] |IsSquareFree(m)] do Go(n,"1-500.out"); end for;
146