00001 #ifndef mmx_gmp_kernel_hpp
00002 #define mmx_gmp_kernel_hpp
00003 #include <realroot/texp_kernelof.hpp>
00004 #include <realroot/scalar_integer.hpp>
00005 #include <realroot/scalar_rational.hpp>
00006 #include <realroot/scalar_floating.hpp>
00007 #include <realroot/scalar_extended_integer.hpp>
00008 #include <realroot/scalar_extended_rational.hpp>
00009 #include <realroot/Interval.hpp>
00010
00011 namespace mmx {
00012
00025
00026 struct GMP {
00027 typedef double ieee;
00028 typedef scalar<MPZ> integer;
00029 typedef scalar<MPQ> rational;
00030 typedef scalar<extended<MPZ> > extended_integer;
00031 typedef scalar<extended<MPQ> > extended_rational;
00032 typedef scalar<MPF> floating;
00033 typedef Interval<rational> interval_rational;
00034 typedef Interval<extended_rational> interval_extended_rational;
00035 };
00036
00037 typedef GMP::rational QQ;
00038 typedef GMP::integer ZZ;
00039 typedef GMP::floating RR;
00040
00041 typedef GMP::extended_rational EQQ;
00042 typedef GMP::extended_integer EZZ;
00043
00044
00045 template<class type> struct is_extended { typedef false_t T; };
00046 template<> struct is_extended<EQQ> { typedef true_t T; };
00047 template<> struct is_extended<EZZ> { typedef true_t T; };
00048
00049 namespace texp {
00050 template<class R> struct kernelof_;
00051 template<> struct kernelof_<GMP::ieee> { typedef GMP T; };
00052 template<> struct kernelof_<GMP::integer> { typedef GMP T; };
00053 template<> struct kernelof_<GMP::rational> { typedef GMP T; };
00054 template<> struct kernelof_<GMP::floating> { typedef GMP T; };
00055
00056 template<> struct kernelof_<GMP::extended_integer> { typedef GMP T; };
00057 template<> struct kernelof_<GMP::extended_rational> { typedef GMP T; };
00058 }
00059
00060 inline int sign(const QQ& a) { return mpq_sgn(&a.rep()); }
00061
00062 inline bool with_plus_sign(const ZZ & c) { return (c>0);}
00063 inline bool with_plus_sign(const QQ & c) { return (c>0);}
00064 inline bool with_plus_sign(const RR & c) { return (c>0);}
00065
00066 inline double to_double(const RR& a) { return mpf_get_d(&a.rep()); }
00067 inline double as_double(const RR& a) { return mpf_get_d(&a.rep()); }
00068
00069 inline double to_XT(const ZZ& a) { return as_double(a); }
00070 inline double to_XT(const QQ& a) { return as_double(a); }
00071 inline double to_XT(const RR& a) { return as_double(a); }
00072
00073
00077 inline void bit_precision(unsigned long l) {
00078 mpf_set_default_prec(l);
00079 }
00080
00081
00085 inline void
00086 bit_precision( RR b, unsigned long l){
00087 mpf_set_prec(&b.rep(),l);
00088 }
00089
00090 inline double gcd (const double&, const double&) { return 1; }
00091
00092
00093
00094 namespace let
00095 {
00096 inline void assign(ZZ& x, const QQ& r) { x= numerator(r)/denominator(r);}
00097 inline void assign(QQ& x, const ZZ& r) { mpq_set_z(&x.rep(), &r.rep());}
00098 inline void assign(RR& r, const ZZ& x) { mpf_set_z(&r.rep(),&x.rep());}
00099
00100 inline void assign(mpz_t r, const ZZ& x) { mpz_set(r, &x.rep());}
00101 inline void assign(mpf_t r, const ZZ& x) { mpf_set_z(r,&x.rep());}
00102 inline void assign(mpf_t r, const RR& x) { mpf_set(r,&x.rep());}
00103 inline void assign(mpf_t r, const QQ& x)
00104 {
00105
00106 mpf_t n, d; mpf_init (n); mpf_init (d);
00107 assign (n, numerator (x));
00108 assign (d, denominator (x));
00109 mpf_div (r, n, d);
00110 mpf_clear (n);
00111 mpf_clear (d);
00112 }
00113
00114 }
00115
00116 template<class T, class U> struct as_helper;
00117
00118 template<> struct as_helper<QQ,ZZ> { static inline QQ cv(const ZZ& x)
00119 { QQ r;mpq_set_z(&r.rep(),&x.rep()); return r; } };
00120
00121 template<> struct as_helper<ZZ,QQ> { static inline ZZ cv(const QQ& r)
00122 { return ( numerator(r)/denominator(r) ); } };
00123
00124 template<> struct as_helper<QQ,RR> { static inline QQ cv(const RR& x)
00125 { QQ r;mpq_set_f(&r.rep(),&x.rep()); return r; } };
00126
00127 template<> struct as_helper<RR,QQ> { static inline RR cv(const QQ& x)
00128 { RR r;mpf_set_q(&r.rep(),&x.rep()); return r; } };
00129
00130 template<> struct as_helper<ZZ,unsigned> { static inline ZZ cv(const unsigned& x)
00131 { ZZ r;mpz_set_ui(&r.rep(),x); return r; } };
00132
00133 template<> struct as_helper<ZZ,double> { static inline ZZ cv(const double& x)
00134 { ZZ r;mpz_set_d(&r.rep(),x); return r; } };
00135
00136 template<> struct as_helper<RR,double> { static inline RR cv(const double& x)
00137 { RR r;mpf_set_d(&r.rep(),x); return r; } };
00138
00139 template<> struct as_helper<double,RR> { static inline double cv(const RR& x)
00140 { return mpf_get_d(&x.rep()); } };
00141
00142 template<> struct as_helper<double,mpf_t> { static inline double cv(const mpf_t& x)
00143 { return mpf_get_d(x); } };
00144
00145
00146 template<> struct as_helper<Interval<double>,QQ> {
00147 static inline Interval<double> cv(const QQ& x) {
00148 double l,u;
00149 {
00150 numerics::rounding<double> rnd( numerics::rounding<double>::rnd_up() );
00151 u=as<double>(x);
00152 }
00153 {
00154 numerics::rounding<double> rnd( numerics::rounding<double>::rnd_dw() );
00155 l=as<double>(x);
00156 }
00157
00158 return Interval<double>(l,u);
00159 }
00160 };
00161
00162
00163
00164
00165
00166 inline QQ to_FT(const ZZ& a, const ZZ& b = 1) {
00167 QQ r,d; let::assign(r,a); let::assign(d,b);
00168 r /=d;
00169
00170 return r;
00171 }
00172 inline QQ to_FT(const QQ& a, const QQ& b = 1) { return a/b; }
00173
00174 }
00175 #endif