diff --git a/libsrc/conic.cc b/libsrc/conic.cc index ba0f39b..949970f 100644 --- a/libsrc/conic.cc +++ b/libsrc/conic.cc @@ -585,10 +585,9 @@ void testmodsqrt() cout << "Enter a modulus m: "; cin >> m; mm=m; vector plist=pdivs(mm); - int* flag = new int[m]; - for(i=0; i flag(m,0); for(i=0; i<=m/2; i++) flag[(i*i)%m]=1; - for(i=0; i ei = solve_nonsingular_cubic(b2,8*b4,16*b6); #ifdef DEBUG cout<<"ei = "< ellztopoint(const bigcomplex& z, const bigcomplex& a1, const bigcomplex& a2, const bigcomplex& a3); }; // end of class Cperiods def'n -bigcomplex* solve_nonsingular_cubic(const bigint& c1, const bigint& c2, const bigint& c3); //Returns an array -// Gets the 3 2-division points given the coefficients +vector solve_nonsingular_cubic(const bigint& c1, const bigint& c2, const bigint& c3); +// Gets the 3 2-division points given the coefficients void getei(const Curvedata& E, bigcomplex& e1, bigcomplex& e2, bigcomplex& e3); // Reorders 3 complex nos so real parts are decreasing void reorder1(bigcomplex& a, bigcomplex& b, bigcomplex& c); diff --git a/libsrc/eclib/htconst.h b/libsrc/eclib/htconst.h index 0bddb26..edb135b 100644 --- a/libsrc/eclib/htconst.h +++ b/libsrc/eclib/htconst.h @@ -39,7 +39,6 @@ inline double height_constant(const Curvedata& CD) } double egr_height_constant(const Curvedata& CD); -bigfloat lower_height_bound_alt(const Curvedata& CD); bigfloat lower_height_bound_search(const Curvedata& CD, const bigfloat& reg); bigfloat Gamma_n(long n); // Gamma(n) = (n-1)! bigfloat Gamma_n_plus_half(long n); // Gamma(n+1/2) = (2n)!sqrt(pi) / (4^n*n!) diff --git a/libsrc/eclib/mglobsol.h b/libsrc/eclib/mglobsol.h index 890f0cf..d73c01c 100644 --- a/libsrc/eclib/mglobsol.h +++ b/libsrc/eclib/mglobsol.h @@ -41,22 +41,19 @@ class quartic_sieve : public point_processor { int verbose, easy, use_stoll; long ulim; int num_aux; - long* auxs; - int** xgood_mod_aux; - int** squares; - long* umod; - long nwprimes; long* wprimes; long* uprimes; + vector auxs, umod, wprimes, uprimes; + vector> xgood_mod_aux, squares; + long nwprimes; long npoints, maxnpoints; int process(const bigint& x, const bigint& y, const bigint& z) - {pu=x; pv=y; pw=z; npoints++; - //cout<<"[x,y,z]=["<=maxnpoints); } // (x,y,z) as returned by ms's sieve; the point is (x/z,y/z^2) public: quartic_sieve(void) {;} quartic_sieve(quartic * gg, int moduli_option=2, int verb=0); - ~quartic_sieve(); long search(double h_lim, long maxnpts=1, int posxonly=0); long stoll_search(double h_lim, int posxonly=0); long search_range(int lower, bigfloat lower_bound, diff --git a/libsrc/eclib/mlocsol.h b/libsrc/eclib/mlocsol.h index 99b06d4..1f211e3 100644 --- a/libsrc/eclib/mlocsol.h +++ b/libsrc/eclib/mlocsol.h @@ -52,7 +52,7 @@ int locallysoluble(const bigint& a, const bigint& c, const bigint& e, /* Samir Siksek's Local Solubility Test for odd p */ -int local_sol(const bigint& p,bigint *c, int verbose=0); +int local_sol(const bigint& p, vector c, int verbose=0); // Checks for solublility in Qp int new_qpsoluble(const quartic& g, const bigint& p, int verbose=0); diff --git a/libsrc/eclib/quadratic.h b/libsrc/eclib/quadratic.h index 14c5492..9cb70dd 100644 --- a/libsrc/eclib/quadratic.h +++ b/libsrc/eclib/quadratic.h @@ -31,26 +31,16 @@ class quadratic { friend class unimod; -private: - bigint * coeffs; // will always have length 3 - // init just allocates memory - void init(); +private: + vector coeffs; public: - void set(long a, long b, long c) - {coeffs[0]=a; coeffs[1]=b; coeffs[2]=c;} - void set(const bigint& a, const bigint& b, const bigint& c) - {coeffs[0]=a; coeffs[1]=b; coeffs[2]=c;} - void set(const bigint* q) - {coeffs[0]=q[0]; coeffs[1]=q[1]; coeffs[2]=q[2];} - void set(const quadratic& q) - {coeffs[0]=q.coeffs[0]; coeffs[1]=q.coeffs[1]; coeffs[2]=q.coeffs[2];} - quadratic() {init(); set(0,0,0);} - ~quadratic(); - quadratic(const bigint& a, const bigint& b, const bigint& c) {init(); set(a,b,c);} - quadratic(long a, long b, long c) {init(); set(a,b,c);} - quadratic(const bigint* q) {init(); set(q);} - quadratic(const quadratic& q) {init(); set(q);} - void operator=(const quadratic& q) {set(q);} + void set(const bigint& a, const bigint& b, const bigint& c) {coeffs = {a, b, c};} + quadratic() { bigint zero(0); coeffs={zero,zero,zero};} + quadratic(const bigint& a, const bigint& b, const bigint& c) {coeffs = {a, b, c};} + quadratic(long a, long b, long c) {coeffs = {BIGINT(a), BIGINT(b), BIGINT(c)};} + quadratic(const bigint* q) {coeffs = {q[0], q[1], q[2]};} + quadratic(const quadratic& q) {coeffs = q.coeffs;} + void operator=(const quadratic& q) {coeffs = q.coeffs;} bigint eval(const bigint& x, const bigint& z) const {return coeffs[0]*sqr(x) + coeffs[1]*x*z + coeffs[2]*sqr(z);} bigint operator()(const bigint& x, const bigint& z) const @@ -59,10 +49,9 @@ class quadratic { {return coeffs[0]*sqr(x) + coeffs[1]*x + coeffs[2];} bigint operator()(const bigint& x) const {return coeffs[0]*sqr(x) + coeffs[1]*x + coeffs[2];} - bigint coeff(int i); - bigint operator[](int i) const; - void set_coeff(int i, const bigint& a) - {if((i>=0)&&(i<=2)) coeffs[i]=a;} + bigint coeff(int i) const {return coeffs[i];} + bigint operator[](int i) const {return coeffs[i];} + void set_coeff(int i, const bigint& a) {if((i>=0)&&(i<=2)) coeffs[i]=a;} friend bigint resultant(const quadratic& q1, const quadratic& q2); bigint disc() const {return sqr(coeffs[1])-4*coeffs[0]*coeffs[2];} void output(ostream& os=cout) const diff --git a/libsrc/htconst.cc b/libsrc/htconst.cc index 2a5ea63..4e7e442 100644 --- a/libsrc/htconst.cc +++ b/libsrc/htconst.cc @@ -68,14 +68,14 @@ double silverman_bound(const Curvedata& CD) double realjay; double hjay = hj(CD,realjay); -// NB the constant 1.922 = 2*0.961 below is from Bremner's correction +// NB the constant 1.922 = 2*0.961 below is from Bremner's correction // to Silverman's paper; Silverman has 0.973 givin 2*0.973 = 1.946. double mu = 1.922 + hjay/12 + log(fabs(I2double(delta)))/6 + logplus(realjay)/6 + logplus(I2double(b2)/12); - + if(b2!=0) mu += log2; return mu; @@ -168,9 +168,8 @@ bigfloat old_calc_dv_inf(const bigfloat& b2, const bigfloat& b4, const bigfloat& double cps_real(const bigfloat& b2, const bigfloat& b4, const bigfloat& b6, const bigfloat& b8) { - bigfloat htc=to_bigfloat(0); - bigfloat dv=to_bigfloat(0); - bigfloat dvd=to_bigfloat(0); + bigfloat zero=to_bigfloat(0); + bigfloat htc=zero, dv=zero, dvd=zero; long original_prec, prec; #ifdef MPFP prec = original_prec = bit_precision(); @@ -209,17 +208,6 @@ double cps_real(const bigfloat& b2, const bigfloat& b4, const bigfloat& b6, cons } #endif -#ifdef TEST_CPS - bigfloat del = -b2*b2*b8-8*b4*b4*b4-27*b6*b6+9*b2*b4*b6; - bigfloat dv2=old_calc_dv_inf(b2,b4,b6,b8,del); - bigfloat dvd2=old_calc_dvd_inf(b2,b4,b6,b8,del); - bigfloat diff = dv-dv2; - if(!is_zero(diff)) - cout<<"old_calc_dv gives "< crit_pts; // use a set, so we don't get any duplicates std::set F_roots; - crit_pts.insert(to_bigfloat(1)); - crit_pts.insert(to_bigfloat(-1)); - + crit_pts.insert(one); + crit_pts.insert(-one); + #ifdef DEBUG_CPS cout<<"crit_pts = "< crit_pts; // use a set, so we don't get any duplicates std::set f_roots; - crit_pts.insert(to_bigfloat(1)); - crit_pts.insert(to_bigfloat(-1)); + crit_pts.insert(to_bigfloat(one)); + crit_pts.insert(to_bigfloat(-one)); #ifdef DEBUG_CPS cout<<"crit_pts = "< rts, int debug=0); - -vector reals_in_interval ( vector& v, const vector rts); - -// Inserts from C in to S the elements which are real and between -1 -// and +1 -void include_real_11(std::set& S, const vector& C); - - -// test if rr lies in one of the first numint intervals out of [i1l.i1r],[i2l.i2r] - -int is_in_int(const bigfloat rr,const bigfloat i1l,const bigfloat i1r, - const bigfloat i2l,const bigfloat i2r,const long numint) -{ -if (numint>0) - { if (rr<=i1r && rr>=i1l) { return 1; } - if (numint==2 && rr<=i2r && rr>=i2l) { return 1; } - } -return 0; -} - -// test if rr lies in one of the numint intervals [intervals[i][0],intervals[i][1]] - -int is_in_int2(const bigfloat rr,bigfloat** intervals,const long numint) -{ - long i; - for (i=0; i=intervals[i][0]) && (rr<=intervals[i][1])) - { return 1; } - } - return 0; -} - -bigfloat old_calc_dv_inf(const bigfloat& b2, const bigfloat& b4, const bigfloat& b6, const bigfloat& b8, const bigfloat& del) -{ - bigfloat rr=to_bigfloat(0),rx,rn; - -#ifdef DEBUG_CPS - cout<<"\nIn old_calc_dv_inf"<0) - { te[0]=i1l; te[1]=i1u; - if (numint==2) - { te[2]=i2l; te[3]=i2u; } - } - - if (numint!=0) - { // Roots of g - rt=solvequartic(to_bigfloat(0),-b4,-2.0*b6,-b8); - for (i=0; i<4; i++) - { if (is_approx_zero(rt[i].imag())) - { rr=rt[i].real(); - if (is_in_int(rr,i1l,i1u,i2l,i2u,numint)) - { te[tec]=rr; tec=tec+1; } - } - } - - // Roots of f (again!) - rt=solvecubic(b2/4.0,b4/2.0,b6/4.0); - for (i=0; i<3; i++) - { if (is_approx_zero(rt[i].imag())) - { rr=rt[i].real(); - if (is_in_int(rr,i1l,i1u,i2l,i2u,numint)) - { te[tec]=rr; tec=tec+1; } - } - } - - // Roots of f+g - rt=solvequartic(to_bigfloat(4),b2-b4,2.0*(b4-b6),b6-b8); - for (i=0; i<4; i++) - { if (is_approx_zero(rt[i].imag())) - { rr=rt[i].real(); - if (is_in_int(rr,i1l,i1u,i2l,i2u,numint)) - { te[tec]=rr; tec=tec+1; } - } - } - - // Roots of g-f // Change from NPS - rt=solvequartic(to_bigfloat(-4),-(b2+b4),-2.0*(b4+b6),-(b6+b8)); - for (i=0; i<4; i++) - { if (is_approx_zero(rt[i].imag())) - { rr=rt[i].real(); - if (is_in_int(rr,i1l,i1u,i2l,i2u,numint)) - { te[tec]=rr; tec=tec+1; } - } - } - - // Roots of f' - if (-24.0*b4+b2*b2>=0.0) - { rn=sqrt(-24.0*b4+b2*b2); - rr=(-b2+rn)/12.0; - if (is_in_int(rr,i1l,i1u,i2l,i2u,numint)) - { te[tec]=rr; tec=tec+1; } - rr=(-b2-rn)/12.0; - if (is_in_int(rr,i1l,i1u,i2l,i2u,numint)) - { te[tec]=rr; tec=tec+1; } - } - - // Roots of g' - rt=solvecubic(to_bigfloat(0),-b4/2.0,-b6/2.0); - for (i=0; i<3; i++) - { if (is_approx_zero(rt[i].imag())) - { rr=rt[i].real(); - if (is_in_int(rr,i1l,i1u,i2l,i2u,numint)) - { te[tec]=rr; tec=tec+1; } - } - } - - } - - bigfloat dv=to_bigfloat(0); - // Evaluate |f|, |g| at each of the tec(>0) x-values in array te: - for (i=0; i=0) - { - d=sqrt(d); a1=1/(2*a); - x=a1*(-b+d); - if((x<=1)&&(x>=-1)) ans.push_back(x); - x=a1*(-b-d); - if((x<=1)&&(x>=-1)) ans.push_back(x); - } - return ans; -} - -vector reals_in ( vector& v) -{ - vector vr; - for (const auto& vi : v) - if(is_real(vi)) - vr.push_back(vi.real()); - return vr; -} - -vector reals_in_11 ( vector& v) -{ - vector vr; - for (const auto& vi : v) - if(is_real(vi)) - { - bigfloat x = vi.real(); - if((x<=1)&&(x>=-1)) - vr.push_back(x); - } - return vr; -} - -int interval_test(const bigfloat& x, const vector rts, int debug) -{ -// rts will have size 1 or 3, and be ordered - if(debug) cout<<"Interval test("<=rts[0]); - else - ans = ((x>=rts[0]) && (x<=rts[1])) || (x>=rts[2]); - if(debug) cout<<"\t returns "< reals_in_interval ( vector& v, const vector rts) -{ - vector vr; - bigfloat x; - for( const auto& vi : v) - if(is_real(vi)) - { - bigfloat x=vi.real(); - if(interval_test(x,rts,1)) - vr.push_back(x); - } - return vr; -} - -// Inserts from C in to S the elements which are real and between -1 -// and +1 -void include_real_11(std::set& S, const vector& C) -{ - bigfloat x; - for (const auto& Ci : C) - { - if(is_real(Ci)) - { - x = Ci.real(); - if((x<=1)&&(x>=-1)) S.insert(x); - } - } -} - -inline int in_fund_region(const bigcomplex& z) -{ - return (imag(z)>0)&&(abs(z)>0.999)&&(abs(2*real(z))<1.001); -} - //#define HTB_DEBUG - // returns lower bound for height of non-torsion points, following // Cremona & Siksek in ANTS7. If egr==1, return a lower bound for the // height of nontorsion pints with everywhere good reduction. @@ -1101,61 +552,6 @@ bigfloat lower_height_bound(const Curvedata& CD, int egr) return lambda; } -// This gives a lower bound on non-torsion points; experimental, not -// very good (and not always positive?!! - -bigfloat lower_height_bound_alt(const Curvedata& CD) -{ - static bigfloat log2 = log(to_bigfloat(2)); - bigcomplex w1, w2; - Cperiods pers(CD); - bigcomplex tau = gettau(pers); -#ifdef HTB_DEBUG - cout<<"\nAfter normalizing, periods are: "< CurveHeightConst::solveLEQ(long n, const bigfloat& B) -{ - vector ans; - if(B < e3) return ans; - vector xlist=solveEllNPower(n,B); - if(n%2) // n is odd - { - ans.push_back(Interval(e3,xlist[0])); - for(int i=1; i= B - -vector CurveHeightConst::solveGEQ(long n, const bigfloat& B) -{ - vector ans; - if(B <= e3) - { - ans.push_back(Interval(e3)); // i.e.[e3,infty] - return ans; - } - vector xlist=solveEllNPower(n,B); - int i; - if(n%2) // n is odd - { - for(i=1; i CurveHeightConst::solveEllNPower01(long n, const bigfloat& x1) -{ - vector ans; - if(x1 CurveHeightConst::solveEllNPower(long n, const bigfloat& x1) -{ - vector ans=solveEllNPower01(n,x1); - bigfloat om=real(get_real_period()); - for(int i=0; i1) + + if(verbose>1) { cout << "Finished constructing quartic_sieve, using "; switch(moduli_option) @@ -228,24 +198,6 @@ quartic_sieve::quartic_sieve(quartic * gg, int moduli_option, int verb) } } -quartic_sieve::~quartic_sieve() -{ - if(nwprimes) { delete[] wprimes; delete[] uprimes;} - - if(use_stoll) // using Stoll search so rest not needed. - return; - - delete[] auxs; - for(long i=0; i flag = xgood_mod_aux[index]; + vector sqs = squares[index]; + for (long x=0; x= aux) f -= aux; df += ddf; if(df >= aux) df -= aux; ddf += dddf; if(ddf >= aux) ddf -= aux; @@ -582,7 +533,7 @@ long quartic_sieve::search_range(int lower, bigfloat lower_bound, if(u_is_ok) { u_is_ok = xgood_mod_aux[i][umodi]; -// if(!u_is_ok) +// if(!u_is_ok) // cout<<"(u,w)=("<=w) umodw-=w; u_is_ok = wflag[umodw]; // true if gcd(u,w)=1 } - if(!u_is_ok) continue; + if(!u_is_ok) continue; // Check that u has no impossible prime factors: for(nwp=0; (nwp coeff = {a, b, c, d, e}; + return local_sol(p,coeff,verbose); } /* Samir's Local Solubility Test for odd p */ @@ -293,11 +290,11 @@ int new_zpsol(const bigint& a,const bigint& b,const bigint& c,const bigint& d,co #define Term pair_ZZ_pX_long #define Poly ZZ_pX -Factorization fact_c(bigint *c, int verbose=0) +Factorization fact_c(vector c, int verbose=0) { - Poly f; ZZ_p ci; - for (long i=0; i<5; i++) - { ci=to_ZZ_p(c[i]); SetCoeff(f,i,ci); } + Poly f; + for (long i=0; i<5; i++) + SetCoeff(f,i,to_ZZ_p(c[i])); if(verbose) cout<<"Factorizing "< c, int verbose) { ZZ_p::init(p); if (verbose) @@ -328,13 +325,11 @@ int local_sol(const bigint& p, bigint *c, int verbose) if (verbose) cout << "f is 0 mod p: Case II" << endl; zeromodp=1; for (i=0; (i<5) && zeromodp; i++) { zeromodp=div(p2,c[i]); } - bigint *dd=new bigint[5]; + vector dd(5); if (zeromodp) { for (i=0; i<5; i++) { dd[i]=c[i]/p2; } if (verbose) cout << "f is 0 mod p^2, recursing" << endl; - int res=local_sol(p,dd,verbose); - delete[] dd; - return res; + return local_sol(p,dd,verbose); } for (i=0; i<5; i++) { dd[i]=c[i]/p; } Factorization fact_f=fact_c(dd); @@ -342,13 +337,12 @@ int local_sol(const bigint& p, bigint *c, int verbose) if (verbose) cout << "Factorization of f/p = "< d(5); fl=0; for (i=0; i d(5); fl=0; for (i=0; i -quadratic::~quadratic() {delete [] coeffs;} - -void quadratic::init() -{ - coeffs = new bigint[3]; -} - -bigint quadratic::coeff(int i) - {if((i>=0)&&(i<=2)) return coeffs[i]; else {bigint ans; return ans;}} - -bigint quadratic::operator[](int i) const - {if((i>=0)&&(i<=2)) return coeffs[i]; else {bigint ans; return ans;}} - void quadratic::transform(const unimod& m) { bigint newq0 = eval(m.m11, m.m21); @@ -93,7 +80,10 @@ void quadratic::reduce(unimod& m) } bigint resultant(const quadratic& q1, const quadratic& q2) -{return sqr(q2.coeffs[0]*q1.coeffs[2]) + sqr(q1.coeffs[0]*q2.coeffs[2]) + - q2.coeffs[2]*q2.coeffs[0]*sqr(q1.coeffs[1]) - q2.coeffs[1]*q1.coeffs[1]*(q2.coeffs[0]*q1.coeffs[2] + q1.coeffs[0]*q2.coeffs[2]) + - (sqr(q2.coeffs[1])-2*q2.coeffs[0]*q2.coeffs[2])*q1.coeffs[0]*q1.coeffs[2]; +{ + const bigint& + a1=q1.coeffs[0], b1=q1.coeffs[1], c1=q1.coeffs[2], + a2=q2.coeffs[0], b2=q2.coeffs[1], c2=q2.coeffs[2]; + return + sqr(c2*a1) -a1*c2*b2*b1 + (-2*c2*a2 + sqr(b2))*c1*a1 + c2*a2*sqr(b1) - b2*a2*c1*b1 + sqr(a2*c1); }