Skip to content

Commit 428de65

Browse files
authored
Merge pull request #35 from JohnCremona/prec
reworked precision to use bit precision everywhere except for output
2 parents 5f48f3b + 708e451 commit 428de65

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+357
-433
lines changed

.travis.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ os:
66
osx_image: xcode6.4
77
dist: trusty
88

9-
matrix:
10-
include:
11-
- env: CONFIGURE_OPTS="--disable-mpfp"
12-
os: linux
9+
env:
10+
- CONFIGURE_OPTS=""
11+
- CONFIGURE_OPTS="--disable-mpfp"
1312

1413
install:
1514
- |

doc/mwrank/mwrank.options

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ List of command line options, their meaning and default values (set in options.h
4141
options (controlled by -v); for minimal useful
4242
output use "-q -v 0 -o"
4343

44-
-p n precision (#dp)
44+
-p n precision (#bits)
4545
Only relevant for the multiprecision
4646
floating point version. Range 1..large,
47-
default 15. This is decimal precision.
47+
default 50. This is bit precision.
4848
Stringly recommended to increase for curves
4949
with 2-torsion where a second descent is used
5050
since then the reduction applied to second

libsrc/compproc.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ bigcomplex normalize(bigcomplex& w1, bigcomplex& w2)
7474
w1=w1-w2*round(tau.real());
7575
tau=w1/w2;
7676
}
77+
if (tau.real()==-0.5)
78+
{
79+
w1+=w2; tau=w1/w2;
80+
}
81+
else
82+
if (abs(tau)==1 && tau.real()<0)
83+
{
84+
w3=-w1; w1=w2; w2=w3; tau=w1/w2;
85+
}
7786
return tau;
7887
}
7988

libsrc/eclib/interface.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,33 @@ inline CC &operator /=(CC &a, const CC &b)
230230

231231
#endif
232232

233+
// NB Internal precision is always bit-precision. We used to use
234+
// decimal precision in the user interface with a conversion factor of
235+
// 3.33 (approx log(10)/log(2)). NTL has a default internal bit
236+
// precision of 150 which can be changed using RR::SetPrecision(), and
237+
// RR:SetOutputPrecision(d) sets the output to d decimal places
238+
// (default 10). See www.shoup.net/ntl/doc/tour-ex6.html and
239+
// www.shoup.net/ntl/doc/RR.cpp.html.
240+
241+
// Set internal precision to n bits and output precision to (0.3*n)-1 decimal places
233242
inline void set_precision(long n)
234-
{RR::SetPrecision(long(n*3.33));RR::SetOutputPrecision(n);}
243+
{RR::SetPrecision(n); RR::SetOutputPrecision(long(0.3*n)-1);}
244+
245+
// Mostly for backward compatibility (used in saturate.cc) or for
246+
// temporarily changing internal precision when no output is relevant:
235247
inline void set_bit_precision(long n)
236248
{RR::SetPrecision(n);}
249+
250+
// Prompt user for precision
237251
inline void set_precision(const string prompt)
238252
{long n; cerr<<prompt<<": "; cin>>n; set_precision(n);}
253+
254+
// read current precision converted to decimal (approximately)
239255
inline long decimal_precision() {return long(RR::precision()*0.3);}
256+
257+
// read current bit precision
240258
inline long bit_precision() {return RR::precision();}
259+
241260
inline int is_approx_zero(const bigcomplex& z)
242261
{return is_approx_zero(z.real())&&is_approx_zero(z.imag());}
243262
inline RR to_bigfloat(const int& n) {return to_RR(n);}
@@ -265,9 +284,12 @@ inline CC pow(const CC& a, const RR& e) {return exp(e*log(a));}
265284
typedef double bigfloat;
266285

267286
inline long decimal_precision() {return 15;}
287+
inline long bit_precision() {return 53;}
268288
inline int is_zero(double x) {return fabs(x)<1e-15;}
269289
inline int is_approx_zero(double x) {return fabs(x)<1e-10;}
270-
inline void set_precision(long n) {cout.precision(n);}
290+
291+
// We cannot set internal bit precision in this mode, so we just set the output decimal precision
292+
inline void set_precision(long n) {cout.precision(min(15,long(0.3*n)));}
271293
inline void set_precision(const string prompt) {cout.precision(15);}
272294
#define Pi() 3.1415926535897932384626433832795028841
273295
#define Euler() (0.57721566490153286060651209008240243104)

libsrc/eclib/options.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ using namespace std;
3131

3232
#define DEFAULT_QUIET 0
3333
#define DEFAULT_VERBOSE 1
34-
#define DEFAULT_PRECISION 15
34+
#define DEFAULT_PRECISION 50
3535
#define DEFAULT_HLIMQ 10
3636
#define DEFAULT_NAUX 15
3737
#define DEFAULT_HLIMC 0
@@ -46,7 +46,7 @@ class mrank_options {
4646
private:
4747
int quiet; // 0/1, controls header output
4848
int verbose; // 0-3, controls output verbosity
49-
long precision; // 1-\infty, controls decimal precision
49+
long precision; // 1-\infty, controls floating point precision (in bits)
5050
long hlimq; // 1-20, height limit for quartic search
5151
long naux; // number of primes used in syzygy sieve
5252
long hlimc; // 1-15, height limit for curve search
@@ -125,7 +125,7 @@ class mrank_options {
125125
cerr << "-q\t""quiet""\t\tturns OFF banner display\n";
126126
cerr << "-v n\t""verbosity""\tsets verbosity to n (default="<<DEFAULT_VERBOSE<<")\n";
127127
cerr << "-o\t""PARI/GP output""\tturns ON extra PARI/GP short output (default is OFF)\n";
128-
cerr << "-p n\t""precision""\tsets precision to n decimals (default="<<DEFAULT_PRECISION<<")\n";
128+
cerr << "-p n\t""precision""\tsets real precision to n bits (default="<<DEFAULT_PRECISION<<")\n";
129129
cerr << "-b n\t""quartic bound""\tbound on quartic point search (default="<<DEFAULT_HLIMQ<<")\n";
130130
cerr << "-x n\t""n aux""\t\tnumber of aux primes used for sieving (default="<<DEFAULT_NAUX<<")\n";
131131
cerr << "-l\t""list""\t\tturns ON listing of points (default ON unless v=0)\n";
@@ -163,7 +163,7 @@ class mrank_options {
163163
if(quiet)cerr<<"ON"; else cerr<<"OFF"; cerr<<"\n";
164164
cerr << "PARI/GP output ";
165165
if(output_pari)cerr<<"ON"; else cerr<<"OFF"; cerr<<"\n";
166-
cerr << "Precision = " << precision << " decimal places (only relevant for multiprecision version)\n";
166+
cerr << "Precision = " << precision << " bits (only relevant for multiprecision version)\n";
167167
cerr << "Verbosity level = " << verbose << "\n";
168168
cerr << "Limit on height for point search on quartics: "<<hlimq<<"\n";
169169
cerr << "Number of auxiliary primes for syzygy sieving: "<<naux<<"\n";

libsrc/heights.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ bigfloat realheight(const bigfloat& x, const Curvedata* E)
156156
t=2*abs(b4); if(t>H) H=t;
157157
t=2*abs(b6); if(t>H) H=t;
158158
t=abs(b8); if(t>H) H=t;
159+
// NB We use decimal precision here since the formula for nlim (from
160+
// Silverman) is given in terms of decimal places required.
159161
long precision = decimal_precision();
160162
#ifdef DEBUG_HEIGHT
161163
cout<<"decimal precision = "<<precision<<endl;

libsrc/periods.cc

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -371,14 +371,14 @@ periods_via_lfchi::periods_via_lfchi (const level* iN, const newform* f)
371371
rootmod = sqrt(to_bigfloat(N));
372372
factor1 = exp(-(TWOPI)/ (to_bigfloat(chi1.modulus()) * rootmod));
373373
factor2 = exp(-(TWOPI)/ (to_bigfloat(chi2.modulus()) * rootmod));
374-
long dp = decimal_precision();
374+
long bp = bit_precision();
375375
// MUST keep brackets around TWOPI!:
376-
bigfloat rootlimit1=(dp*LOG10-log(1-factor1))*rootmod/(TWOPI) ;
377-
bigfloat rootlimit2=(dp*LOG10-log(1-factor1))*rootmod/(TWOPI) ;
376+
bigfloat rootlimit1=(bp-log(1-factor1))*rootmod/(TWOPI) ;
377+
bigfloat rootlimit2=(bp-log(1-factor1))*rootmod/(TWOPI) ;
378378
Iasb(limit1,rootlimit1);
379379
Iasb(limit2,rootlimit2);
380380
#ifdef TRACE_USE
381-
cout << "Decimal precision = "<<dp<<endl;
381+
cout << "Bit precision = "<<bp<<endl;
382382
cout << "Basic limits on n in sums = " << limit << endl;
383383
#endif
384384
limit1=chi1.modulus()*limit1;
@@ -390,7 +390,7 @@ periods_via_lfchi::periods_via_lfchi (const level* iN, const newform* f)
390390
#endif
391391
/*
392392
if(primelist[primelist.size()-1]<limit)
393-
cout<<"\nLARGEST PRIME "<<primelist[primelist.size()-1]<<" IS BELOW LIMIT "<< limit <<" required for decimal precision "<<dp<<endl;
393+
cout<<"\nLARGEST PRIME "<<primelist[primelist.size()-1]<<" IS BELOW LIMIT "<< limit <<" required for bit precision "<<bp<<endl;
394394
*/
395395
rootlimit=sqrt(to_bigfloat(limit));
396396
an_cache.resize(I2long(Ifloor(rootlimit+1)),0);
@@ -465,9 +465,9 @@ void periods_direct::compute(void)
465465
b = posmod(b,d);
466466
c = posmod(c,d);
467467
factor2 = factor1 * drecip;
468-
long dp = decimal_precision();
469-
Iasb(limit1,(-dp*LOG10-log((1-exp(factor1))/3))/(factor1)) ;
470-
Iasb(limit2,(-dp*LOG10-log((1-exp(factor2))/3))/(factor2)) ;
468+
long bp = bit_precision();
469+
Iasb(limit1,(-bp-log((1-exp(factor1))/3))/(factor1)) ;
470+
Iasb(limit2,(-bp-log((1-exp(factor2))/3))/(factor2)) ;
471471

472472
limit = limit2;
473473
rootlimit=sqrt(to_bigfloat(limit));
@@ -479,7 +479,7 @@ void periods_direct::compute(void)
479479
#endif
480480
/*
481481
if(primelist[primelist.size()-1]<limit)
482-
cout<<"\nLARGEST PRIME "<<primelist[primelist.size()-1]<<" IS BELOW LIMIT "<< limit <<" required for decimal precision "<<dp<<endl;
482+
cout<<"\nLARGEST PRIME "<<primelist[primelist.size()-1]<<" IS BELOW LIMIT "<< limit <<" required for bit precision "<<bp<<endl;
483483
*/
484484
#ifdef TRACE_CACHE
485485
cout << "Initial an_cache = "<<an_cache<<endl;
@@ -555,8 +555,8 @@ void part_period::compute(const bigcomplex& z0)
555555

556556
void part_period::compute()
557557
{
558-
long dp = decimal_precision();
559-
Iasb(limit,dp*LOG10/y0);
558+
long bp = bit_precision();
559+
Iasb(limit,bp/y0);
560560
limit1=limit2=limit;
561561
rootlimit=sqrt(to_bigfloat(limit));
562562
an_cache.resize(I2long(Ifloor(rootlimit+1)),0);
@@ -595,7 +595,7 @@ void ldash1::init(const level* iN, const vector<long>& f_aplist, long f_sfe, con
595595
rootmod=sqrt(to_bigfloat(N));
596596
factor1 = (TWOPI)/rootmod;
597597
long maxp = prime_number(nap);
598-
limit = I2long(Ifloor((15+decimal_precision())*log(10)/factor1));
598+
limit = I2long(Ifloor((30+bit_precision())/factor1));
599599
if(limit>maxp) limit=maxp;
600600
limit1 = limit;
601601
rootlimit=sqrt(to_bigfloat(limit));
@@ -636,8 +636,8 @@ lfchi::lfchi (const level* iN, const newform* f)
636636
{
637637
initaplist(iN, f->aplist);
638638
rootmod = sqrt(to_bigfloat(N));
639-
long dp = decimal_precision();
640-
Iasb(limit0,dp*LOG10*rootmod/(TWOPI)) ; // brackets essential
639+
long bp = bit_precision();
640+
Iasb(limit0,bp*rootmod/(TWOPI)) ; // brackets essential
641641
}
642642

643643
void lfchi::compute(long ell)
@@ -843,7 +843,7 @@ Curve newforms::getcurve(long i, int method, bigfloat& rperiod, int verbose)
843843
if((abs((wR-wRC)/wRC)>0.0001))
844844
{
845845
cout<<"Real period of constructed curve does not match that"
846-
<<" of the newform (using decimal precision "<<decimal_precision()<<")"<<endl;
846+
<<" of the newform (using bit precision "<<bit_precision()<<")"<<endl;
847847
cout<<"Real period of C: "<<real(wRC)<<endl;
848848
cout<<"Real period of f: "<<real(wR)<<endl;
849849
cout<<"Ratio = "<<real(wR)/real(wRC)<<endl;
@@ -852,7 +852,7 @@ Curve newforms::getcurve(long i, int method, bigfloat& rperiod, int verbose)
852852
if((abs((wRI-wRIC)/wRIC)>0.0001))
853853
{
854854
cout<<"Second period of constructed curve does not match that"
855-
<<" of the newform (using decimal precision "<<decimal_precision()<<")"<<endl;
855+
<<" of the newform (using bit precision "<< bit_precision()<<")"<<endl;
856856
cout<<"Imag part of second period of C: "<<real(wRIC)<<endl;
857857
cout<<"Imag part of second period of f: "<<real(wRI)<<endl;
858858
cout<<"Ratio of imaginary parts = "<<real(wRI)/real(wRIC)<<endl;
@@ -1034,7 +1034,8 @@ bigfloat G(int r, bigfloat x) // G_r(x)
10341034
#ifndef MPFP // Multi-Precision Floating Point
10351035
static const bigfloat x0 = to_bigfloat(14);
10361036
#else
1037-
static const bigfloat x0 = to_bigfloat(log(10)*decimal_precision());
1037+
// log(2) = 0.69314718
1038+
static const bigfloat x0 = to_bigfloat(0.69314718*bit_precision());
10381039
#endif
10391040
// cout<<"switch point = "<<x0<<endl;
10401041
// cout<<"x="<<x<<endl;
@@ -1058,7 +1059,7 @@ bigfloat ldash1::G(bigfloat x) // G_r(x)
10581059
}
10591060

10601061
#if(0) // myg2 and myg3 were inaccurate and now replaced by general
1061-
// G(r,x) -- whcih also works for r>3!
1062+
// G(r,x) -- which also works for r>3!
10621063
bigfloat myg2(bigfloat x)
10631064
{
10641065
static bigfloat zero=to_bigfloat(0);

libsrc/saturate.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ int saturator::enlarge()
220220
{
221221
cout<<"...but it isn't! (this may be due to insufficient precision:";
222222
#ifdef NTL_ALL
223-
cout << " decimal precision " <<prec<<" was used)"<<endl;
223+
cout << " bit precision " <<prec<<" was used)"<<endl;
224224
#else
225225
cout << " standard double precision was used)"<<endl;
226226
#endif

progs/h1bsd.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
int main(void)
3737
{
38-
set_precision(15);
38+
set_precision(50);
3939
int limit,n=1;
4040
#ifdef AUTOLOOP
4141
cout<<"Enter first and last N: ";cin>>n>>limit;

progs/h1bsdcurisog.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
int main(void)
6262
{
63-
set_precision(10);
63+
set_precision(35);
6464

6565
long limit, n=1, hlim1=10, hlim2=15;
6666
bigint nn;

0 commit comments

Comments
 (0)