1 // interface.h: used to provide common interface
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 //  The macro NO_MPFP can optionally be set.  It controls whether most
25 //   real and complex floating point functions are implemented using
26 //   doubles and complex doubles (if set) or using NTL bigfloats
27 //   (RR) and bigcomplexes (CC) (if not set, the default)
28 
29 #ifndef _ECLIB_INTERFACE_H_
30 #define _ECLIB_INTERFACE_H_
31 
32 #ifndef NO_MPFP // the default is for this *not* to be set
33 #define MPFP
34 #endif
35 
36 #include <limits>
37 #include <iostream>
38 #include <sstream>
39 #include <fstream>
40 #include <set>
41 #include <vector>
42 #include <map>
43 #include <algorithm>
44 #ifdef _LIBCPP_VERSION
45 #include <numeric>
46 #else
47 #include <ext/numeric>
48 #endif
49 #include <iterator>
50 
51 #include <eclib/templates.h>
52 #include <stdint.h>
53 
54 #ifndef MININT
55 #define MININT numeric_limits<int>::min()
56 #endif
57 #ifndef MINLONG
58 #define MINLONG numeric_limits<long>::min()
59 #endif
60 #ifndef MAXINT
61 #define MAXINT numeric_limits<int>::max()
62 #endif
63 #ifndef MAXLONG
64 #define MAXLONG numeric_limits<long>::max()
65 #endif
66 
67 // integers and rationals
68 
69 // Some of the following were defined for compatibility with LiDIA, which is no longer supported
70 
71 #include <NTL/ZZ.h>
72 #include <NTL/ZZXFactoring.h>
73 using namespace NTL;
74 
75 typedef ZZ bigint;
76 
77 #define BIGINT(val) to_ZZ(val)
atoI(const char * s)78 inline bigint atoI(const char* s) {return to_ZZ(s);}
79 
odd(const int & a)80 inline int odd(const int& a) {return a&1;}
even(const int & a)81 inline int even(const int& a) {return !(a&1);}
odd(const long & a)82 inline int odd(const long& a) {return a&1;}
even(const long & a)83 inline int even(const long& a) {return !(a&1);}
84 
is_zero(const bigint & x)85 inline int is_zero(const bigint& x) {return IsZero(x);}
is_positive(const bigint & x)86 inline int is_positive(const bigint& x) {return sign(x)>0;}
is_negative(const bigint & x)87 inline int is_negative(const bigint& x) {return sign(x)<0;}
is_one(const bigint & x)88 inline int is_one(const bigint& x) {return IsOne(x);}
odd(const bigint & a)89 inline int odd(const bigint& a) {return IsOdd(a);}
even(const bigint & a)90 inline int even(const bigint& a) {return !IsOdd(a);}
rshift(const bigint & a,long i,bigint & c)91 inline void rshift(const bigint& a, long i, bigint& c) {RightShift(c,a,i);}
lshift(const bigint & a,long i,bigint & c)92 inline void lshift(const bigint& a, long i, bigint& c) {LeftShift(c,a,i);}
93 #ifdef setbit
94 #undef setbit
95 #endif
setbit(bigint & a,int e)96 inline void setbit(bigint& a, int e) {SetBit(a,e);}
lg(const bigint & x)97 inline long lg(const bigint& x) {return NumBits(x)-1;}
is_long(const bigint & a)98 inline int is_long(const bigint& a) {return (a<=MAXLONG)&&(a>=MINLONG);}
is_int(const bigint & a)99 inline int is_int(const bigint& a) {return (a<=MAXINT)&&(a>=MININT);}
100 
101 // The following are not in NTL & need defining
102 int I2int(const bigint& x);    // too long to inline
103 long I2long(const bigint& x);  // too long to inline
I2double(const bigint & x)104 inline double I2double(const bigint& x) {return to_double(x);}
longasI(long & a,const bigint & x)105 inline void longasI(long& a, const bigint& x) {a = I2long(x);}
negate(bigint & a)106 inline void negate(bigint& a) {a=-a;}
sqrt(bigint & a,const bigint & b)107 inline void sqrt(bigint& a, const bigint& b) {SqrRoot(a,b);}
sqrt(const bigint & a)108 inline bigint sqrt(const bigint& a) {bigint b; sqrt(b,a); return b;}
square(bigint & a,const bigint & b)109 inline void square(bigint& a, const bigint& b) {sqr(a,b);}
gcd(const bigint & a,const bigint & b)110 inline bigint gcd(const bigint& a, const bigint& b) {return GCD(a,b);}
lcm(const bigint & a,const bigint & b)111 inline bigint lcm(const bigint& a, const bigint& b)
112  {if (IsZero(a) && IsZero(b)) return ZZ::zero(); else return a*(b/GCD(a,b));}
113 
114 // In NTL add, sub, mul, div are defined with result in first place
addx(const bigint & a,const bigint & b,bigint & c)115 inline void addx(const bigint& a, const bigint& b, bigint& c)  {add(c,a,b);}
subx(const bigint & a,const bigint & b,bigint & c)116 inline void subx(const bigint& a, const bigint& b, bigint& c)  {sub(c,a,b);}
divx(const bigint & a,const bigint & b,bigint & c)117 inline void divx(const bigint& a, const bigint& b, bigint& c)  {div(c,a,b);}
mulx(const bigint & a,const bigint & b,bigint & c)118 inline void mulx(const bigint& a, const bigint& b, bigint& c)  {mul(c,a,b);}
pow(const bigint & a,long e)119 inline bigint pow(const bigint& a, long e)  {return power(a,e);}
120 
121 //N.B. no power to bigint exponent in NTL
jacobi(const bigint & a,const bigint & p)122 inline long jacobi(const bigint& a, const bigint& p)  {return Jacobi(a,p);}
sqrt_mod_p(bigint & x,const bigint & a,const bigint & p)123 inline void sqrt_mod_p(bigint & x, const bigint & a, const bigint & p)
124   {SqrRootMod(x,a,p); if(x>(p-x)) x= p-x;}
power_mod(bigint & ans,const bigint & base,const bigint & expo,const bigint & m)125 inline void power_mod(bigint& ans, const bigint& base, const bigint& expo, const bigint& m)
126  {PowerMod(ans,base,expo,m);}
nearest(bigint & c,const bigint & a,const bigint & b)127 inline void nearest(bigint& c, const bigint& a, const bigint& b)
128  {bigint a0=(a%b);  c = (a-a0)/b; if(2*a0>b) c+=1;}
roundover(const bigint & a,const bigint & b)129 inline bigint roundover(const bigint& a, const bigint& b)
130  {bigint a0=(a%b); bigint c = (a-a0)/b; if(2*a0>b) c+=1; return c;}
131 
132 #define bigint_mod_long(a,m) (a%m)
133 
134 
135 // Reals and Complexes
136 
137 #ifdef MPFP
138 
139 #include <NTL/RR.h>
140 typedef RR bigfloat;
141 RR Pi();
142 RR Euler();
143 RR atan(const RR&);
144 RR asin(const RR&);
pow(const RR & a,int e)145 inline RR pow(const RR& a, int e)  {return power(a,e);}
pow(const RR & a,long e)146 inline RR pow(const RR& a, long e)  {return power(a,e);}
147 namespace NTL {
cosh(const RR & x)148 inline RR cosh(const RR& x) {return (exp(x)+exp(-x))/2;}
sinh(const RR & x)149 inline RR sinh(const RR& x) {return (exp(x)-exp(-x))/2;}
tan(const RR & x)150 inline RR tan(const RR& x) {return sin(x)/cos(x);}
151 RR atan2(const RR&, const RR&);
is_approx_zero(const RR & x)152 inline int is_approx_zero(const RR& x)
153 //  {return abs(x)<power2_RR(2-RR::precision());}
154 {
155   if (IsZero(x)) return 1;
156   long n = x.exponent()+RR::precision()-1;
157   if (n>=0) return 0;
158   // cout<<"x="<<x<<", exponent="<<x.exponent()<<", mantissa="<<x.mantissa()<<", precision="<<RR::precision()<<endl;
159   // cout<<"is_approx_zero() returns "<<(x.mantissa()<power2_ZZ(-n))<<endl;
160   return abs(x.mantissa())<power2_ZZ(-n);
161 }
162 } // namespace NTL
163 #ifdef _LIBCPP_VERSION
164 namespace NTL {
isinf(const RR & z)165 inline bool isinf(const RR& z) {
166   return false;
167 }
isnan(const RR & z)168 inline bool isnan(const RR& z) {
169   return false;
170 }
copysign(const RR & x,const RR & y)171 inline RR copysign(const RR& x, const RR& y) {
172   if (sign(x) != sign(y)) {
173     return -y;
174   }
175   return y;
176 }
signbit(const RR & x)177 inline bool signbit(const RR& x) {
178   return sign(x) < 0;
179 }
fmax(const RR & x,const RR & y)180 inline RR fmax(const RR& x, const RR& y)
181 {
182   return x < y ? y : x;
183 }
184 } // namespace NTL
185 #endif
186 
187 #include <complex>
188 typedef complex<RR> CC;
189 typedef CC bigcomplex;
190 
191 #ifdef _LIBCPP_VERSION
abs(const CC & z)192 template <> inline RR std::abs(const CC &z)
193 {
194   RR re = z.real();
195   RR im = z.imag();
196   return sqrt(re*re + im*im);
197 }
exp(const CC & z)198 template <> inline CC std::exp(const CC &z)
199 {
200   RR im = z.imag();
201   RR e = exp(z.real());
202   return CC(e * cos(im), e * sin(im));
203 }
204 inline CC operator/(const CC &a, const CC &b)
205 {
206   RR are = a.real();
207   RR aim = a.imag();
208   RR bre = b.real();
209   RR bim = b.imag();
210   if (abs(bre) <= abs(bim)) {
211     RR r = bre / bim;
212     RR den = bim + r*bre;
213     return CC((are*r + aim)/den, (aim*r - are)/den);
214   } else {
215     RR r = bim / bre;
216     RR den = bre + r*bim;
217     return CC((are + aim*r)/den, (aim - are*r)/den);
218   }
219 }
220 inline CC operator /(const RR &a, const CC &b)
221 {
222   CC r(a);
223   return r/b;
224 }
225 inline CC &operator /=(CC &a, const CC &b)
226 {
227   a = a/b;
228   return a;
229 }
230 
231 #endif
232 
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
set_precision(long n)242 inline void set_precision(long 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:
set_bit_precision(long n)247 inline void set_bit_precision(long n)
248   {RR::SetPrecision(n);}
249 
250 // Prompt user for precision
set_precision(const string prompt)251 inline void set_precision(const string prompt)
252   {long n; cerr<<prompt<<": "; cin>>n; set_precision(n);}
253 
254 // read current precision converted to decimal (approximately)
decimal_precision()255 inline long decimal_precision() {return long(RR::precision()*0.3);}
256 
257 // read current bit precision
bit_precision()258 inline long bit_precision() {return RR::precision();}
259 
is_approx_zero(const bigcomplex & z)260 inline int is_approx_zero(const bigcomplex& z)
261   {return is_approx_zero(z.real())&&is_approx_zero(z.imag());}
to_bigfloat(const int & n)262 inline RR to_bigfloat(const int& n) {return to_RR(n);}
to_bigfloat(const long & n)263 inline RR to_bigfloat(const long& n) {return to_RR(n);}
to_bigfloat(const double & x)264 inline RR to_bigfloat(const double& x) {return to_RR(x);}
I2bigfloat(const bigint & x)265 inline RR I2bigfloat(const bigint& x) { return to_RR(x);}
doublify(const bigfloat & x,double & d)266 inline int doublify(const bigfloat& x, double& d){ d=to_double(x); return 0;}
267 int longify(const bigfloat& x, long& a, int rounding=0);
is_zero(bigfloat x)268 inline int is_zero(bigfloat x) {return IsZero(x);}
is_zero(bigcomplex z)269 inline int is_zero(bigcomplex z) {return IsZero(z.real()) && IsZero(z.imag());}
Iasb(bigint & a,bigfloat x)270 inline void Iasb(bigint& a, bigfloat x) {RoundToZZ(a,x);}
Iasb(long & a,bigfloat x)271 inline void Iasb(long& a, bigfloat x) {ZZ n; RoundToZZ(n,x); a=I2long(n);}
272 istream& operator>>(istream& is, CC& z);
pow(const CC & a,int e)273 inline CC pow(const CC& a, int e)  {return exp(to_RR(e)*log(a));}
pow(const CC & a,long e)274 inline CC pow(const CC& a, long e)  {return exp(to_RR(e)*log(a));}
pow(const CC & a,const RR & e)275 inline CC pow(const CC& a, const RR& e)  {return exp(e*log(a));}
276 
277 
278 //////////////////////////////////////////////////////////////////
279 #else  // C doubles and libg++ Complexes
280 //////////////////////////////////////////////////////////////////
281 
282 // reals
283 
284 typedef double bigfloat;
285 
decimal_precision()286 inline long decimal_precision() {return 15;}
bit_precision()287 inline long bit_precision() {return 53;}
is_zero(double x)288 inline int is_zero(double x) {return fabs(x)<1e-15;}
is_approx_zero(double x)289 inline int is_approx_zero(double x) {return fabs(x)<1e-10;}
290 
291 // We cannot set internal bit precision in this mode, so we just set the output decimal precision
set_precision(long n)292 inline void set_precision(long n) {cout.precision(min(15,long(0.3*n)));}
set_precision(const string prompt)293 inline void set_precision(const string prompt)  {cout.precision(15);}
294 #define Pi()    3.1415926535897932384626433832795028841
295 #define Euler() (0.57721566490153286060651209008240243104)
296 
round(double x)297 inline double round(double x) {return floor(x+0.5);}
roundup(double x)298 inline double roundup(double x) {return ceil(x-0.5);}
Iasb(long & a,double x)299 inline void Iasb(long& a, double x) {a = (long)x;}
300 // return value is 1 for success, else 0
301 int longify(double x, long& a, int rounding=0);
doublify(const bigfloat & x,double & d)302 inline int doublify(const bigfloat& x, double& d) {d=x; return 0;}
303 
304 
to_bigfloat(const int & n)305 inline double to_bigfloat(const int& n) {return double(n);}
to_bigfloat(const long & n)306 inline double to_bigfloat(const long& n) {return double(n);}
to_bigfloat(const double & x)307 inline double to_bigfloat(const double& x) {return x;}
308 
I2bigfloat(const bigint & x)309 inline bigfloat I2bigfloat(const bigint& x) {return I2double(x);}
310 
311 // complexes
312 
313 #include <complex>
314 typedef complex<double> bigcomplex;
315 
is_zero(const bigcomplex & z)316 inline int is_zero(const bigcomplex& z)
317  {return is_zero(z.real())&&is_zero(z.imag());}
is_approx_zero(const bigcomplex & z)318 inline int is_approx_zero(const bigcomplex& z)
319  {return is_approx_zero(z.real())&&is_approx_zero(z.imag());}
320 
321 //////////////////////////////////////////////////////////////////
322 #endif // MPFP
323 //////////////////////////////////////////////////////////////////
324 
325 #undef setbit
326 
327 // Utility to return a string from an environment variable with a
328 // default to use if the variable is not set or empty.
329 
330 string getenv_with_default(string env_var, string def_val);
331 
332 #endif // #define _INTERFACE_H_
333