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