00001
00002
00003
00004
00005
00008 #ifndef SYNAPS_SOLVE_ABERTH_H
00009 #define SYNAPS_SOLVE_ABERTH_H
00010 #ifdef SYNAPS_WITH_GMP
00011
00012 #include <synaps/init.h>
00013 #include <synaps/base/Seq.h>
00014 #include <synaps/arithm/gmp.h>
00015 #include <synaps/arithm/CC.h>
00016 #include <mpsolve/mps_poly.h>
00017
00018 __BEGIN_NAMESPACE_SYNAPS
00019 namespace arithm {
00020 template <> struct realof_<CC> {typedef RR T;};
00021 }
00022
00023 namespace aberth_solver
00024 {
00025 #ifdef SYNAPS_WITH_GMP
00026 inline void assign(mpf_t r, double x) { mpf_set_d (r,x);}
00027 inline void assign(mpf_t r, signed long int x) { mpf_set_si(r,x);}
00028 inline void assign(mpf_t r, unsigned long int x){ mpf_set_ui(r,x);}
00029 inline void assign(mpf_t r, mpz_t x) { mpf_set_z(r,x);}
00030 inline void assign(mpz_t r, double x) { mpz_set_d(r,x);}
00031 inline void assign(mpf_t r, const mpf_t & x) { mpf_set(r,x);}
00032 inline void assign(mpc_t r, mpc_t x) { mpc_set(r,x);}
00033 inline void assign(mpz_t r, const ZZ& x) { mpz_set(r, x.get_mpz_t());}
00034 inline void assign(mpf_t r, const ZZ& x) { mpf_set_z(r,x.get_mpz_t());}
00035 inline void assign(mpf_t r, const RR& x) { mpf_set(r,x.get_mpf_t());}
00036 inline void assign(mpf_t r, const QQ& x)
00037 {
00038
00039 RR u=RR(x.get_num())/RR(x.get_den()); mpf_set(r,u.get_mpf_t());
00040
00041 }
00042
00043 inline void assign(double& d,const mpf_t& r)
00044 {
00045 d=mpf_get_d(r);
00046 }
00047
00048 template<class T>
00049 bool assign(std::complex<T> & z, const mpc_t & x, const T& eps)
00050 {
00051 T r,i;
00052 assign(r,x->r);
00053 assign(i,x->i);
00054 z = std::complex<T>(r,i);
00055 return true;
00056 }
00057
00058 template<class T>
00059 inline bool assign(CC& z, const mpc_t & x, const T & eps)
00060 {
00061 mpc_set(&z.rep(),x);
00062 return true;
00063 }
00064 inline bool assign(RR& r, const mpc_t & x, const RR & eps)
00065 {
00066 mpf_set(r.get_mpf_t(),x->r);
00067 RR i; mpf_set(i.get_mpf_t(),x->i);
00068
00069 if(i<eps && i>-eps)
00070 return true;
00071 else
00072 return false;
00073 }
00074
00075 inline bool assign(double& d, const mpc_t & x, const RR & eps)
00076 {
00077 RR r;
00078 mpf_set(r.get_mpf_t(),x->r);
00079 RR i; mpf_set(i.get_mpf_t(),x->i);
00080
00081 d=to_double(r);
00082 if(i<eps && i>-eps)
00083 return true;
00084 else
00085 return false;
00086 }
00087
00088
00089
00090 #endif
00091 }
00092
00093 template<class S, class P>
00094 void run_mpsolve(Seq<S>& r, const P& t, int pi, int po, char* G= "iannc")
00095 {
00096 mpspoly_t p;
00097
00098
00099 DOLOG = false;
00100 DOWARN = true;
00101 DOSORT = true;
00102
00103
00104 outstr = stdout;
00105 logstr = stderr;
00106
00107
00108 prec_in = pi;
00109 prec_out = po;
00110 goal = new char[5];
00111 strncpy(goal, G, 5);
00112
00113
00114
00115 p->data_type[0]='d';
00116 p->data_type[1]='r';
00117 if(pi==0)
00118 p->data_type[2]='i';
00119 else
00120 p->data_type[2]='f';
00121 p->prec_in = prec_in;
00122 mp_set_prec(p->prec_in);
00123 p->deg = degree(t);
00124 p->n = p->deg;
00125 int num_coeff = degree(t) + 1;
00126 allocate_poly(p);
00127
00128 if(p->data_type[2]=='i')
00129 for (int i = 0; i < num_coeff; i++)
00130 aberth_solver::assign(p->mip_r[i],t[i]);
00131 else
00132 for (int i = 0; i < num_coeff; i++)
00133 aberth_solver::assign(p->mfpr[i],t[i]);
00134
00135
00136 validate_poly(p, num_coeff);
00137
00138
00139 set_poly(p);
00140
00141
00142 allocate_data();
00143
00144 mpsolve();
00145
00146
00147 copy_roots();
00148
00149
00150 S s;
00151 bool valid;
00152
00153 typename realof<S>::T eps=1;
00154 for(int i=0;i<po/2;++i) eps/=10;
00155
00156 if(n != p->deg)
00157 r.push_back(S(0));
00158 for (int i = 0; i < n; i++)
00159 {
00160 valid = aberth_solver::assign(s,mroot[i],eps);
00161 if(valid)
00162 {
00163 r.push_back(s);
00164 }
00165 }
00166 }
00167
00168 template<class C> inline int input_prec(const C & x) { return -1; }
00169 template<class C> inline int output_prec(const C & x) { return -1; }
00170 template<> inline int input_prec(const double & x) { return 16; }
00171 template<> inline int output_prec(const double & x) { return 16; }
00172
00173
00175
00185 template<class C>
00186 struct SlvAberth {
00187 typedef C sol_t;
00188 int pin, pout;
00189 SlvAberth():pin(0), pout(DBL_DIG){}
00190 SlvAberth(int o):pout(o), pin(0){}
00191 SlvAberth(int o, int i):pin(i), pout(o){}
00192 };
00193
00194
00195 template<class C>
00196 struct IslAberth {
00197 typedef C sol_t;
00198 int pin, pout;
00199 IslAberth():pin(0), pout(DBL_DIG){}
00200 IslAberth(int o):pout(o), pin(0){}
00201 IslAberth(int o, int i):pin(i), pout(o){}
00202 };
00203
00204 template<class C, class P>
00205 void runmpsolve(Seq<C>& r, const P& t, int pi, int po, const SlvAberth<C> & mth)
00206 {
00207 run_mpsolve(r,t,pi,po,"aannc");
00208 }
00209
00210 template<class C, class P>
00211 void runmpsolve(Seq<C>& r, const P& t, int pi, int po, const IslAberth<C> & mth)
00212 {
00213 run_mpsolve(r,t,pi,po,"iannc");
00214 }
00215
00216
00217 #ifdef SYNAPS_WITH_GMP
00218 template<class P>
00219 int runmpsolve(Seq<RR>& r, const P& t, int pi, int po, const SlvAberth<RR> & mth)
00220 {
00221 run_mpsolve(r,t,pi,po,"aRrnc");
00222 }
00223
00224 template<class P>
00225 int runmpsolve(Seq<RR>& r, const P& t, int pi, int po, const IslAberth<RR> & mth)
00226 {
00227 run_mpsolve(r,t,pi,po,"iRrnc");
00228 }
00229 #endif
00230
00234 template<class S, class P>
00235 Seq<S> solve(const P &p, const SlvAberth<S> & A)
00236 {
00237 Seq<S> r;
00238 run_mpsolve(r,
00239 p,
00240 std::max(A.pin, input_prec(p[0])),
00241 std::max(A.pout, output_prec(p[0])),
00242 "iannc");
00243 return r;
00244 }
00245
00246 template<>
00247 Seq<double> solve(const UPolDse<double> &p, const SlvAberth<double> & A)
00248 {
00249 UPolDse<QQ> q(p.size(),AsSize());
00250 for(unsigned i=0;i<p.size();i++)
00251 let::assign(q[i],p[i]);
00252 return solve(q,A);
00253 }
00254
00258 template<class P,class S>
00259 Seq<S> solve(const P &p, const IslAberth<S> & A)
00260 {
00261 Seq<S> r;
00262 runmpsolve(r,
00263 p,
00264 std::max(A.pin, input_prec(p[0])),
00265 std::max(A.pout, output_prec(p[0])),
00266 A);
00267 return r;
00268 }
00269
00270 __END_NAMESPACE_SYNAPS
00271
00272 #endif // SYNAPS_WITH_GMP
00273 #endif // SYNAPS_SOLVE_ABERTH_H
00274