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