1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
// FILE PCURVE.CC
//////////////////////////////////////////////////////////////////////////
//
// Copyright 1990-2012 John Cremona
//
// This file is part of the eclib package.
//
// eclib is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// eclib is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with eclib; if not, write to the Free Software Foundation,
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
//
//////////////////////////////////////////////////////////////////////////
//
// computes a possible equation from periods for newforms
// ONLY needs eigs data, not full intdata
// BUT only finds curves "up to isogeny" as it does not
// determine the full Gamma_0(N) period lattice.
#include <iostream>
#include <eclib/marith.h>
#include <eclib/moddata.h>
#include <eclib/symb.h>
#include <eclib/oldforms.h>
#include <eclib/homspace.h>
#include <eclib/cperiods.h> //from qcurves, for computing conductors
#include <eclib/newforms.h>
#include <eclib/periods.h>
#include <eclib/pcprocs.h>
//#define SINGLE
#ifndef SINGLE
#define AUTOLOOP
#endif
#define DMAX 50 // Upper bound for d = (2,2) matrix entry used
#define LMAX 200 // Upper bound twisting prime l-
int main(void)
{
initprimes("PRIMES",0);
set_precision(20);
long limit,n=1;
int dump=1, detail;
long maxn, dmax=DMAX;
//#ifdef SINGLE
detail=2;
//#else
cout << "See details? "; cin>>detail;
//#endif
cout << "Enter max d: "; cin>>dmax;
cout << "Enter max scaling factor for periods: "; cin>>maxn;
#ifdef AUTOLOOP
cout<<"Enter first and last N: ";cin>>n>>limit;
n--; cout<<"\n";
while (n<limit) { n++;
#else
while (n>0) { cout<<"Enter level: "; cin>>n;
#endif
if (n>0)
{
cout << "N = " << n << endl;
newforms nf(n,detail);
int noldap=25;
nf.createfromdata(1,noldap);
int squarelevel=nf.squarelevel;
long fac=nf.sqfac;
long nnf = nf.n1ds;
long inf = 1;
#ifdef SINGLE
cout << "Enter form number: "; cin>>inf;
nnf=inf;
#endif
primevar pr; long p0; // First "good" prime
while (p0=(long)pr, ::divides(p0,n)) pr++;
int anyfound=0;
for(long i=inf-1; i<nnf; i++)
{
if(detail) cout<<"\n"<<"Form number "<<i+1<<"\n";
else cout<<(i+1)<<" ";
newform* nfi = &((nf.nflist)[i]);
if(detail>1) {cout<<"\n Newform details:\n";nfi->display();cout<<endl;}
bigfloat x0=to_bigfloat(10), y0=to_bigfloat(10), ratio;
// flags to say that we have real/imag period
// and that we have a cycle giving both together
int rp_known=0, have_both=0;
long lplus=nfi->lplus, mplus=nfi->mplus;
long s = nfi->sfe;
//nfi->dotplus=1;
nfi->dotminus=1; // In case wrong values were on the file!
// STEP 1: find the real period using L(f,1) is L/P nonzero,
// or via L(f,chi,1)
// Now done within get_matrix_periods()
// STEP 2: compute periods of lots of matriced in Gamma_0(N) over all
// symbols {0,b/d} for d<dmax. We are looking for (i) a symbol whose
// imaginary part is nonzero; (ii) a symbol whose real and imaginary
// parts are both non-zero, which we store.
have_both = nf.find_matrix( i, dmax, rp_known, x0, y0);
if(!have_both)
cout<<"Problem! find_matrix() returns 0!"<<endl;
if(detail)
{
cout << "Minimal periods found: x0 = "<<x0<<", y0 = "<<y0<<"\n";
cout << "Matrix ("<<nfi->a<<","<<nfi->b<<";"<<n*nfi->c<<","<<nfi->d<<"):\t";
cout << "dotplus = "<< nfi->dotplus << ", dotminus = "<< nfi->dotminus<< "\n";
cout << "Searching for scaling factors.\n";
}
// STEP 3: Now we have nonzero integer multiples of real and imag
// periods, we search for a sub-multiple of both which gives a genuine
// curve.
long nx, ny; int type;
long maxnx=maxn;
if(rp_known) maxnx=1;
int found = get_curve(n, fac, maxnx, maxn, x0, y0, nx, ny, type, detail);
if(found)
{
anyfound=1;
// cout<<"before rescaling, dotplus="<<nfi->dotplus<<", dotminus="<<nfi->dotminus<<endl;
// cout<<"rescaling by nx = "<<nx<<", ny="<<ny<<endl;
nfi->dotplus *= nx;
nfi->dotminus *= ny;
nfi->type=type;
cout << "[(" <<nfi->a<<","<<nfi->b<<";"<<nfi->c
<<","<<nfi->d<<"),"<<nfi->dotplus<<","<<nfi->dotminus
<<";"<<nfi->type<<"]"<<endl;
// STEP 4: We find a suitable twisting prime for the imaginary period
if(!squarelevel)
{
bigfloat y1 = y0/to_bigfloat(ny);
int ok = nf.find_lminus(i, 0, y1);
if(!ok)
{
cout<<"No suitable twisting prime "
<<" found for imaginary period!"<<endl;
}
}
if(detail)
{
cout<<"Updated newform data:\n"; nfi->display();
cout<<"test reconstruction of curve from updated data:"<<endl;
}
// test reconstruction of the curve
bigfloat rperiod;
Curve C = nf.getcurve(i, -1, rperiod, detail);
Curvedata CD(C,1); // The 1 causes minimalization
cout << "Curve = \t";
cout << (Curve)CD << "\t";
CurveRed CR(CD);
bigint nc = getconductor(CR);
cout << "N = " << getconductor(CR) << endl;
}
else cout<<"No curve found\n";
// dump complete data file into NF_DIR/x$N.
} // end of forms loop
if (anyfound)
{
cout<<"Store newform data? "; cin>>dump;
if(dump)
{
nf.output_to_file();
}
}
} // end of if(n)
} // end of while()
} // end of main()
|