1 // FILE H1CURVE.CC: Program to list curves
2 //////////////////////////////////////////////////////////////////////////
3 //
4 // Copyright 1990-2012 John Cremona
5 //
6 // This file is part of the eclib package.
7 //
8 // eclib is free software; you can redistribute it and/or modify it
9 // under the terms of the GNU General Public License as published by the
10 // Free Software Foundation; either version 2 of the License, or (at your
11 // option) any later version.
12 //
13 // eclib is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 // for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with eclib; if not, write to the Free Software Foundation,
20 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 //
22 //////////////////////////////////////////////////////////////////////////
23 //
24 #include <fstream>
25 #include <eclib/compproc.h>
26 #include <eclib/moddata.h>
27 #include <eclib/symb.h>
28 #include <eclib/cusp.h>
29 #include <eclib/homspace.h>
30 #include <eclib/oldforms.h>
31 #include <eclib/curve.h> //from qcurves
32 #include <eclib/cperiods.h> //from qcurves, for computing conductors
33 #include <eclib/newforms.h>
34 #include <eclib/periods.h>
35
36 #ifndef SINGLE // so Makefile can override
37 #define AUTOLOOP
38 #endif
39
40 #define LMFDB_ORDER // if defined, sorts newforms into LMFDB order before output
41
42 // If this is defined, the fisc6 output is placed in subdirectory
43 // fixc6 in file fixc6/fixc6.N (one per level); otherwise it is all
44 // put in ./fixc6.extra
45 //#define FIXC6_OUTPUT_TO_SUBDIR
46
47 #define BOOKORDER // if defined, sorts newforms/curves into order
48 // in the Book (relevant up to 500 only)
49 #include <eclib/curvesort.h>
50
51 vector<pair<int,int> > bad_ones; // holds bad (n,i) list
52
53 int checkap(const level* iN, const newform& nf, CurveRed& CR, long pmax=100);
54
main(void)55 int main(void)
56 {
57 int prec0 = 100;
58 int maxprec = 500;
59 int prec = prec0;
60 int delta_prec = 50;
61 set_precision(prec);
62 int verb=0;
63 #ifdef SINGLE
64 verb=1;
65 #else
66 cout<<"See detail? "; cin>>verb;
67 #endif
68 int limit,n=1;
69 #ifdef AUTOLOOP
70 cout<<"Enter first and last N: ";cin>>n>>limit;
71 n--; cout<<endl;
72 cout<<endl<<"Table of curves computed from newforms via periods"<<endl;
73 #ifdef BOOKORDER
74 cout<<"(reordered to agree with Book for levels up to 1000)"<<endl;
75 #endif
76 #ifdef LMFDB_ORDER
77 cout<<"(reordered to agree with LMFDB for levels over 1000)"<<endl;
78 #endif
79 if(!verb)
80 {
81 cout << "\nN \t# \t";
82 cout<<"[a1,a2,a3,a4,a6]";
83 cout<<"\t\tConductor\n";
84 }
85 while (n<limit) { n++;
86 #else
87 while (n>0) { cout<<"Enter level: "; cin>>n;
88 #endif
89 if (n>0)
90 {
91 newforms nf(n,verb);
92 int noldap=25;
93 nf.createfromdata(1,noldap,0); // do not create from scratch if data absent
94 #ifdef LMFDB_ORDER
95 nf.sort();
96 #endif
97 int nnf = nf.n1ds;
98 int inf = 1;
99 #ifndef SINGLE
100 if(verb>1) nf.display();
101 #else
102 // if(nnf>1)
103 {
104 cout << "Enter form number (between 1 and "<<nnf<<"): "; cin>>inf;
105 if((inf<1)||(inf>nnf))
106 {
107 cout << "Not in range!\n"; inf=1; nnf=0;
108 }
109 else nnf=inf;
110 }
111 #endif
112
113 for(int xi=inf-1; xi<nnf; xi++)
114 { int i = xi;
115 #ifdef BOOKORDER
116 i=booknumber0(n,i);
117 #endif
118 if(verb) cout << "\nForm number " << i+1 << ": " << endl;
119 else cout << n << "\t" << codeletter(xi) << "\t";
120 //#ifdef SINGLE
121 if(verb) nf.nflist[i].display();
122 //#endif
123
124 bigfloat rperiod;
125 Curve C;
126 Curvedata CD;
127 CurveRed CR;
128 bigint nc;
129 prec = prec0-delta_prec;
130 set_precision(prec);
131 C = Curve();
132 while (C.isnull() && (prec<maxprec))
133 {
134 prec += delta_prec;
135 set_precision(prec);
136 C = nf.getcurve(i, -1, rperiod, verb);
137 if (!C.isnull())
138 {
139 CD = Curvedata(C,1); // The 1 causes minimalization
140 CR = CurveRed(CD);
141 nc = getconductor(CR);
142 if(n!=nc) C = Curve(); // wrong conductor; reset to null curve
143 }
144 }
145 if(C.isnull())
146 {
147 cout << "bad curve, even after trying precision up to "<<maxprec<<endl;
148 bad_ones.push_back(pair<int,int>(n,i+1));
149 }
150 else
151 {
152 if(getdiscr(Curvedata(C,0))!=getdiscr(CD))
153 {
154 cout << "Non-minimal curve = \t" << C << ", minimal curve = \t";
155 }
156 else if(verb) cout << "Curve = \t";
157 cout << (Curve)CD << "\t";
158 cout << "N = " << nc;
159 if(n!=nc)
160 {
161 cout<<" ------WRONG CONDUCTOR!";
162 }
163 else
164 {
165 if(!checkap(&nf, nf.nflist[i], CR))
166 cout<<" ----- a_p do not agree!";
167 // else
168 // cout<<" ----- a_p agree for p<100";
169 }
170 cout<<endl;
171 }
172 #ifdef SINGLE
173 bigint c6=getc6(CD), c4=getc4(CD);
174 char* f = new char[20];
175 #ifdef FIXC6_OUTPUT_TO_SUBDIR
176 sprintf(f,"fixc6/fixc6.%ld",n);
177 #else
178 sprintf(f,"fixc6.extra");
179 #endif
180 ofstream xout(f,ios::app);
181 delete[] f;
182 xout<<" "<<n<<" "<<(i+1)<<" "<<c6<<endl;
183 xout.close();
184 cout<<"c4: "<<n<<" "<<(i+1)<<" "<<c4<<endl;
185 cout<<"c6: "<<n<<" "<<(i+1)<<" "<<c6<<endl;
186 #endif
187 if(verb) cout<<endl;
188 }
189 } // end of if(n)
190 } // end of while()
191
192 if (bad_ones.size()>0)
193 {
194 cout<<"\nNumber of bad curves: "<<bad_ones.size()<<endl;
195 cout<<"List of bad curves\n";
196 for(unsigned int i=0; i<bad_ones.size(); i++)
197 cout<<bad_ones[i].first<<" "<<bad_ones[i].second<<"\n";
198 cout<<endl;
199 }
200 } // end of main()
201
202 int checkap(const level* iN, const newform& nf, CurveRed& CR, long pmax)
203 {
204 vector<long> aplist = nf.aplist;
205 vector<long> primelist = primes(aplist.size());
206 unsigned int i;
207 bigint ap, p=BIGINT(0);
208 int ok=1, ok1;
209 for(i=0; (i<aplist.size())&&(p<=pmax); i++)
210 {
211 p=primelist[i];
212 ap=Trace_Frob(CR,p);
213 ok1 = (ap==BIGINT(aplist[i]));
214 if(!ok1) cout<<"p="<<p<<": ap(E)="<<ap<<" but ap(f)="<<aplist[i]<<endl;
215 ok = ok && ok1;
216 }
217 return ok;
218 }
219