synaps/usolve/Aberth.h

Go to the documentation of this file.
00001 /**********************************************************************
00002  *    This file is part of the source code of the SYNAPS library. 
00003  *    Author(s): B. Mourrain, GALAAD, INRIA                    
00004  *    $Id: Aberth.H,v 1.5 2005/09/28 06:30:38 mourrain Exp $
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     //    std::cout<<x<<" ";
00039     RR u=RR(x.get_num())/RR(x.get_den()); mpf_set(r,u.get_mpf_t());
00040     //    std::cout<<u<<std::endl;
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     //DBG_PRINT(x->r<<" "<<x->i);
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     //DBG_PRINT(x->r<<" "<<x->i);
00081     d=to_double(r);
00082     if(i<eps && i>-eps) 
00083       return true;
00084     else 
00085       return false;
00086   }
00087   // inline void assign(mpz_t r, const Scl<MPZ>& x)  { mpz_set(r,&x.rep());}
00088   // inline void assign(mpf_t r, const Scl<MPZ>& x)  { mpf_set_z(r,&x.rep());}
00089   // inline void assign(mpf_t r, const Scl<MPF>& x)  { mpf_set(r,&x.rep());}
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   /* set flags */
00099   DOLOG = false;
00100   DOWARN = true;
00101   DOSORT = true;
00102 
00103   /* set streams */
00104   outstr = stdout;
00105   logstr = stderr;
00106 
00107   /* set default values */
00108   prec_in = pi;         /* if != -1 ignore precision from file */
00109   prec_out = po;        /* 2*DBL_DIG; default output precision */
00110   goal = new char[5];
00111   strncpy(goal, G, 5);  /* default goal */
00112   //DBG_PRINT(goal<<"\n");
00113   /* Read polynomial */
00114   //  read_poly(instr, p);
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   //mpz_out_str(stdout,10,p->mip_r[i]);
00135 
00136   validate_poly(p, num_coeff);
00137 
00138   /* Set polynomial */
00139   set_poly(p);
00140 
00141   /* allocate global variables */
00142   allocate_data();
00143   /*#G  atexit(free_data);      call free_data at exit */
00144   mpsolve();
00145 
00146   /* copy roots */
00147   copy_roots();
00148   //DBG_PRINT(n);
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 

SYNAPS DOCUMENTATION
logo