From d209a2df9d0dce6c50e91d90d1ebf448d12a75cf Mon Sep 17 00:00:00 2001 From: John Cremona Date: Mon, 22 Apr 2024 16:31:35 +0100 Subject: [PATCH] improve precision handling for special L-value computations --- libsrc/eclib/interface.h | 3 +- libsrc/eclib/periods.h | 15 +- libsrc/interface.cc | 4 +- libsrc/periods.cc | 295 ++++++++++++------------------ progs/out_no_ntl/h1bsd.out | 6 +- progs/out_no_ntl/h1bsdcurisog.out | 6 +- progs/out_ntl/h1bsd.out | 4 +- progs/out_ntl/h1bsdcurisog.out | 4 +- 8 files changed, 135 insertions(+), 202 deletions(-) diff --git a/libsrc/eclib/interface.h b/libsrc/eclib/interface.h index 148c6b01..28e8e92a 100644 --- a/libsrc/eclib/interface.h +++ b/libsrc/eclib/interface.h @@ -152,7 +152,6 @@ inline RR sinh(const RR& x) {return (exp(x)-exp(-x))/2;} inline RR tan(const RR& x) {return sin(x)/cos(x);} RR atan2(const RR&, const RR&); inline int is_approx_zero(const RR& x) -// {return abs(x) -#define PI Pi() -const bigfloat eps = to_bigfloat(1.0e-16); // ?? mindouble; -#define EULERGAMMA Euler() - -bigfloat myg0(bigfloat x); -bigfloat myg1(bigfloat x); -bigfloat myg2(bigfloat x); -bigfloat myg3(bigfloat x); - class character { private: long modul; @@ -123,8 +114,6 @@ class part_period :public summer { bigcomplex getperiod() {return bigcomplex(rp,ip);} }; -bigfloat G(int r, bigfloat x); // G_r(x) - class ldash1 : public summer { private: long r; @@ -133,8 +122,7 @@ class ldash1 : public summer { bigfloat G(bigfloat x); // G_r(x) void init(const level* N, const vector& f_aplist, long f_sfe, const rational& f_loverp); void use(long n, long an) override {use1(n,an);} - bigfloat func1(long n) override - { return -G(factor1*to_bigfloat(n)); } + bigfloat func1(long n) override; public: ldash1 (const level* iN, const newform* f); ldash1 (const newforms* nf, long i); // the i'th newform @@ -167,5 +155,6 @@ vector resort_aplist(const level* iN, const vector& primelist, const vector& apl); +bigfloat myg1(bigfloat x); #endif diff --git a/libsrc/interface.cc b/libsrc/interface.cc index 92fc1fc3..573c0354 100644 --- a/libsrc/interface.cc +++ b/libsrc/interface.cc @@ -102,6 +102,7 @@ void Compute_Euler(RR& y) bigfloat u, v, a, b, c; l = RR::precision(); + RR::SetPrecision(l+20); x = 1 + static_cast((0.25 * (l - 3)) * (NTL_BITS_PER_LONG * LOG2)); n = 1 + static_cast(3.591 * x); @@ -111,7 +112,7 @@ void Compute_Euler(RR& y) if (sign(u) > 0) u=-u; a=u; v=b=to_bigfloat(1); - + for (k = 1; k <= n; k++) { mul(b, b, x); mul(b, b, x); @@ -125,6 +126,7 @@ void Compute_Euler(RR& y) add(v, v, b); } div(y, u, v); + RR::SetPrecision(l); } long prec() {return RR::precision();} diff --git a/libsrc/periods.cc b/libsrc/periods.cc index b9d44f47..193acc00 100644 --- a/libsrc/periods.cc +++ b/libsrc/periods.cc @@ -618,6 +618,18 @@ void ldash1::compute(void) } } +bigfloat ldash1::func1(long n) +{ +#ifdef MPFP + long l = bit_precision(); + set_precision(l+20); +#endif + bigfloat ans = -G(factor1*to_bigfloat(n)); +#ifdef MPFP + set_precision(l); +#endif + return ans; +} ///////////////////////////////// // functions for lfchi class // @@ -861,102 +873,26 @@ Curve newforms::getcurve(long i, int method, bigfloat& rperiod, int verbose) return C; } -// avoid underflow: log(MINDOUBLE)=-708.396 - -bigfloat myg0(bigfloat x) -{ -#ifndef MPFP // Multi-Precision Floating Point - if(x>708) return to_bigfloat(0); -#endif - return exp(-x); -} - -//#define TRACEG1 - -bigfloat myg1(bigfloat x) -{ -#ifndef MPFP // Multi-Precision Floating Point - if(x>708) return to_bigfloat(0); -#endif - if(x<2) - { - bigfloat ans = -log(x) - Euler(); - bigfloat p = to_bigfloat(-1); -#ifdef TRACEG1 - cout<<"Computing myg1 for x = "< Av(r+1); // indexed from 0 to r - int j; bigfloat n=one; - for(j=0;j<=r;j++) Av[j]=one; + bigfloat n=one, emx=exp(-x), ans=x, term=x, y; + vector Av(r+1, one); // indexed from 0 to r while(!is_approx_zero(emx*term*Av[r])) - //while(!is_approx_zero(term*Av[r])) { n++; // update A-vector, term and sum - for(j=1;j<=r;j++) Av[j]+=(Av[j-1]/n); - term*=(x/n); - ans+=(Av[r]*term); + for(int j=1;j<=r;j++) + Av[j]+=(Av[j-1]/n); + term*=x; + term/=n; + y = Av[r]*term; + ans+=y; + // cout<<"\n"< Cv(r+1); // indexed from 0 to r - int j; bigfloat n=zero; + bigfloat emx2=2*exp(-x), ans=zero, mxinv=-one/x; + bigfloat y, term = mxinv, n=zero; + if (is_approx_zero(abs(emx2*term))) + return zero; + // cout<<"Glarge("< Cv(r+1, zero); // indexed from 0 to r Cv[0]=one; - for(j=1;j<=r;j++) Cv[j]=zero; - //cout<<"In Glarge with r="<20) return zero; - bigfloat ans = -log(x) - Euler(); -//cout<<"Computing myg3 for x = "<