realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/solver_mv_bernstein.hpp
Go to the documentation of this file.
00001 /********************************************************************
00002  *   This file is part of the source code of the realroot library.
00003  *   Author(s): J.P. Pavone, GALAAD, INRIA
00004  *   $Id: realroot.h,v 1.1 2005/07/11 10:03:51 jppavone Exp $
00005  ********************************************************************/
00006 #ifndef realroot_SOLVE_mslvbst_H
00007 #define realroot_SOLVE_mslvbst_H
00008 /********************************************************************/
00015 #include <set>
00016 #include <vector>
00017 #include <math.h>
00018 #include <realroot/texp_kernelof.hpp>
00019 #include <realroot/solver.hpp>
00020 
00021 #include <realroot/tensor_bernstein.hpp>
00022 
00023 #define REP(x) (x).rep()
00024 
00025 #include <realroot/GMP.hpp>
00026 #include <realroot/polynomial.hpp>
00027 #include <realroot/system_method.hpp>
00028 #include <realroot/system_support.hpp>
00029 #include <realroot/Seq.hpp>
00030 
00031 
00032 //====================================================================
00033 namespace mmx {
00034 //====================================================================
00035 namespace realroot
00036 {
00037 #define SBD_RD       0
00038 #define SBD_RDL      1
00039 #define SBD_RDS      2
00040 #define SBD_RDRDL    3
00041 #define SBD_RDRDLRDS 4
00042 #define SBD_RDRDS    5
00043 #define SBD_RDLRDS   6
00044 #define SBD_RDSRDL   7
00045 #ifndef SBD_MTH
00046 #define SBD_MTH SBD_RDRDL
00047 #endif
00048   
00049   template< class system, int mth > /* selection de methodes */
00050   struct select_mth
00051   { typedef realroot::method<system,strgy::newton<system>,rdslv::parallel,sbdrl::parametric> result_t; };
00052   template< class system > 
00053   struct select_mth<system,SBD_RD>
00054   { typedef realroot::method<system,strgy::simple<system>,rdslv::parallel,sbdrl::parametric> result_t; };
00055   template< class system > 
00056   struct select_mth<system,SBD_RDL>
00057   { typedef realroot::method<system,strgy::newton<system>,rdslv::parallel,sbdrl::parametric> result_t; };
00058   template< class system>
00059   struct select_mth<system,SBD_RDRDL>
00060   { typedef realroot::method<system,strgy::newton< system, strgy::simple<system> >,rdslv::parallel,sbdrl::parametric> 
00061     result_t; };
00062   template< class system >
00063   struct select_mth<system,SBD_RDRDLRDS>
00064   { typedef realroot::method<system,strgy::cvmatrix< system, strgy::newton<system,strgy::simple<system> > >,rdslv::parallel,sbdrl::parametric> result_t; };
00065   template< class system > 
00066     struct select_mth<system,SBD_RDS>
00067   { typedef realroot::method<system,strgy::cvmatrix<system>,rdslv::parallel,sbdrl::parametric> result_t; };
00068 
00069   template< class system > 
00070     struct select_mth<system,SBD_RDRDS>
00071   { typedef realroot::method<system,strgy::cvmatrix<system, strgy::simple<system> >,rdslv::parallel,sbdrl::parametric> result_t; };
00072   
00073   template< class system > 
00074     struct select_mth<system,SBD_RDLRDS>
00075   { typedef realroot::method<system,strgy::cvmatrix<system, strgy::newton<system> >,rdslv::parallel,sbdrl::parametric> result_t; };
00076 
00077   template< class system > 
00078     struct select_mth<system,SBD_RDSRDL>
00079   { typedef realroot::method<system,strgy::cvmatrix<system, strgy::newton<system> >,rdslv::parallel,sbdrl::parametric> result_t; };
00080   
00081   template< class T, class eenv_t, class MPOL >
00082   void fill_data( T * data, eenv_t * env, const MPOL& p, binomials<T>& benv  )
00083   {
00084     std::fill(data,data+env->sz(),0); 
00085     mpolfill(data,p.rep(),*env);
00086     convertm2b (data,*env,benv);
00087   };
00088   template< class monom >
00089   void scan_monom_env ( std::set< int >& env, const monom& m )
00090   { for ( unsigned i = 0; i < (m.rep()).size(); i++ ) if ( (m.rep())[i] != 0 ) env.insert(i); };
00091 }
00092 
00093   template<int MTH> struct ProjRd {};
00094   
00095 //====================================================================
00107 template<class C, int MTH>
00108 struct solver< C, ProjRd<MTH> >
00109 {
00110   typedef C coeff_t;
00111   typedef Seq<std::vector<C> >  Solutions;
00112   typedef realroot::system<C>   system_t;
00113   
00114   static C eps;
00115   static system_t* sys;
00116 
00118   // solver_multivariate_bernstein( const C& precision = (C)1e-6 ): eps(precision), sys(0){};
00119 
00120   
00121   static void set_precision(int prec) { using std::pow; eps = pow(2.0,-prec); }
00122 
00123   template< class MPDI >  static
00124   void init_bernstein( MPDI  first, MPDI last)
00125   {
00126 
00127     int    ne = 0;
00128     MPDI eptr;
00129     for ( eptr = first; eptr != last; eptr ++ ) ne++;
00130     int nvrs[ne];
00131     const int *szs[ne];
00132     int e;
00133     //    int mxvr = 0;
00134     std::set<int> gvrs;
00135     for ( e = 0, eptr = first; eptr != last; eptr ++, e++  ) { 
00136       nvrs[e] = eptr->rep().nbvar(); 
00137       szs[e]  = eptr->rep().szs();
00138       const int * tmp = eptr->rep().vrs();
00139       for ( int v = 0; v < eptr->rep().nvr(); v ++ ) gvrs.insert(tmp[v]);
00140     };
00141     int mxv = *(gvrs.rend());
00142     int lnames[ mxv+1 ];
00143     int nv = 0;
00144     for ( std::set<int>::const_iterator it = gvrs.begin(); it != gvrs.end(); lnames[*it++] = nv++ ) ;
00145     int * vrdat = new int[ nv * ne ];
00146     int * vrptr = vrdat;
00147     const int *  vrs[ne];
00148     e = 0;
00149     for ( eptr = first; eptr != last; vrptr+= eptr->rep().nbvar(), e++, eptr ++ ) {
00150       vrs[e] = vrptr;
00151       const int * tmp = eptr->rep().vrs();
00152       for ( int v = 0; v < eptr->rep().nvr();  v ++ )
00153         vrptr[v] = lnames[ tmp[v] ];    
00154     };
00155     //    std::cout << ne << " " << nv << std::endl;
00156     assert(ne>=nv);
00157     sys = new realroot::system<C>( ne, nv, nvrs, (const int**)vrs, (const int**)szs, eps );
00158     e=0; for ( MPDI eptr = first; eptr != last; add_equation( REP(*eptr), e++  ), eptr++ ) ;
00159     delete[] vrdat;
00160   };
00161   
00162   static void add_equation( const tensor::bernstein<C>& data, int e )
00163   {
00164     sys->set_bernstein2( data.begin(), e );
00165   };
00166   
00167   static void add_equation( const tensor::monomials<C>& data, int e ) 
00168   {
00169     sys->set_monomial2( data.begin(), e );
00170   };
00171   
00172   static int run( std::vector<C> & R, int& nv )
00173   {
00174     R.resize(0);
00175     typename realroot::select_mth<system_t,MTH>::result_t __mth;
00176     //int e = 0;for ( MPDI eptr = first; eptr != last; add( eptr->rep(), e++  ), eptr++ );
00177     //std::vector<C> tmp;
00178     realroot::system_ctrl< std::vector< C > >  intf(R);
00179     int nvars = sys->nvr();
00180     __mth.launch(sys,intf,(C*)0);
00181 
00182     int nsols = R.size() / (2*nvars);
00183     int nsols2 = realroot::clean_result( &R[0], nvars, nsols,(C)1e-3 );
00184     R.resize(nsols2 * nvars) ;
00185     int ns = nsols2;
00186     nv = nvars;
00187     return ns;
00188   };
00189   
00190   static int run( std::vector<C> & sol, C* dom, int& nv )
00191   {
00192     sol.resize(0);
00193     typename realroot::select_mth<system_t,MTH>::result_t __mth;
00194     realroot::system_ctrl< std::vector< C > >  intf(sol);
00195     int nvars = sys->nvr();
00196     //    C* dmns = &dom[0];
00197     // if ( (int)dom.size() >= 2*nvars )
00198 //       {
00199 //      dmns = new C[ 2*nvars ];
00200 //      for ( int i = 0; i < 2*nvars; i ++ ) let::assign(dmns[i],dom[i]);
00201 //       };
00202     __mth.launch(sys,intf,dom);
00203 
00204     int nsols = sol.size() / (2*nvars);
00205     int nsols2 = realroot::clean_result( &sol[0], nvars, nsols,(C)1e-3 );
00206     sol.resize(nsols2 * nvars) ;
00207     int ns = nsols2;
00208     nv = nvars;
00209     return ns;
00210   };
00211 
00212   //--------------------------------------------------------------------
00220   template< class output, class MPC, class Domains >
00221   static void solve_monomial( output& res, 
00222                               const MPC& l, const Domains & dom, 
00223                               bool verbose = false )
00224   {
00225     typedef C T;
00226     typedef typename MPC::value_type          mpoly_t;
00227     typedef MPC                               plist_t;
00228     typedef typename plist_t::const_iterator  pptr_t;
00229     typedef typename mpoly_t::const_iterator  mptr_t;
00230     //    typedef typename mpoly_t::monom_t         monom_t;
00231     //    typedef solver_multivariate_bernstein<C, MTH>           mth_t;
00232     typedef int                               sz_t;
00233     sz_t  nvars = 0, neqs, * nvrs, ** vrs, ** szs; 
00234     int e;
00235     pptr_t cpl; 
00236     // recuperation de l'environement global
00237     for ( neqs = 0, cpl = l.begin(); cpl != l.end(); cpl++, neqs++  )
00238       for ( mptr_t mn = cpl->begin(); mn != cpl->end(); mn++ )
00239         nvars = std::max(nvars,mn->nvars()+1);
00240     // recuperation de l'environement de chaque equation
00241     std::set<int> * seenvs = new std::set< int > [ neqs ];
00242     for ( e = 0, cpl = l.begin(); e < neqs; e++, cpl++  )
00243       for ( mptr_t mn = cpl->begin(); mn != cpl->end(); mn++ ) 
00244         realroot::scan_monom_env(seenvs[e],*mn);
00245     
00246     //  assert(sizeof(sz_t)==sizeof(sz_t*));
00247     sz_t  s = 0;
00248     for ( e = 0; e < neqs; s += seenvs[e].size(), e++ ) ;
00249     nvrs = new sz_t [neqs+2*s];
00250     vrs  = new sz_t*[2*neqs];
00251     szs  = vrs + neqs;
00252     sz_t * base = nvrs + neqs;
00253     std::set<int>::iterator seenvit;  
00254     for ( e = 0, cpl = l.begin(); e < neqs; base += 2*nvrs[e++], cpl++ )
00255       {
00256         nvrs[e] = seenvs[e].size();
00257         vrs [e] = base;
00258         szs [e] = base + nvrs[e];
00259         int k = 0;
00260         for ( seenvit = seenvs[e].begin(); k < nvrs[e]; seenvit++, k++  ) 
00261         {
00262           vrs[e][k]  = *seenvit;
00263           szs[e][k]  = degree( *cpl, *seenvit ) + 1;
00264         };
00265       };
00266     
00267     std::vector<C> result;
00268     C * dmns = 0;
00269     if ( (sz_t)dom.size() >= 2*nvars )
00270       {
00271         dmns = new C[ 2*nvars ];
00272         for ( int i = 0; i < 2*nvars; i ++ ) let::assign(dmns[i],dom[i]);
00273       };
00274     
00275     //  chrono tm;
00276     std::vector<T> tmp;
00277     
00278     {  /* remplissage et appel */
00279       using namespace realroot;
00280       binomials<T> bznv;
00281       typedef  realroot::system<T> system_t;
00282       system_t sys( neqs, nvars, nvrs, (const int**)vrs, (const int**)szs, (T)eps);
00283       for ( e = 0, cpl = l.begin(); e < neqs; e ++, cpl++  )
00284         realroot::fill_data( sys.data(e), sys.env(e), *cpl, bznv );
00285       realroot::system_ctrl< std::vector< T > >  intf(tmp);
00286       //    tm.start();
00287       typename realroot::select_mth<system_t,MTH>::result_t __mth;
00288       __mth.launch(&sys,intf,dmns);
00289       //tm.stop();
00290       if ( verbose )
00291         {
00292           std::cout << " iterations  = " << __mth.m_niter << std::endl;
00293           std::cout << "subdivisions = "<< __mth.m_nsbd  << std::endl;
00294         };
00295     };
00296     
00297     if ( !verbose && dmns ) delete[] dmns;
00298     delete[] seenvs;
00299     delete[] nvrs;
00300     delete[] vrs;
00301     if ( verbose )
00302       {
00303         std::cout << "<domain>";
00304         if  ( dmns )
00305           {
00306             std::cout << std::endl;
00307             for ( int i = 0; i < nvars; i ++ )
00308               std::cout << "\t" 
00309                         << "x" << i//monom_t::var_of_index(i) 
00310                         << " = [ " << dmns[2*i] 
00311                         << "," 
00312                         << dmns[2*i+1] 
00313                         << " ]";
00314           }
00315         else std::cout << "[0,1]^" << nvars;
00316         std::cout << "</domain>\n";
00317         //      std::cout << "\treductions   = " << bsys.nrest() << std::endl;
00318         //      std::cout << "\titerations   = " << bsys.niter() << std::endl;
00319         //      std::cout << "<solver_time>"; tm.write(std::cout); 
00320         //      std::cout <<"</solver_time>"<< std::endl;       
00321         if ( dmns ) delete[] dmns;
00322       };
00323     
00324     unsigned nsols = tmp.size() / (2*nvars);
00325     T boxes[nsols*2*nvars];
00326     std::copy(&tmp[0], &tmp[0]+2*nvars*nsols,boxes);
00327     int nsols2 = realroot::clean_result( &tmp[0], nvars, nsols,(T)1e-3 );
00328     if ( verbose ) { 
00329       //    xml::print(std::cout,nsols,"nb_box")<< std::endl;
00330       for ( unsigned i = 0; i < nsols; i ++ )
00331         {
00332           std::cout << "\t[ ";
00333           for (int j = 0; j < nvars; j ++ )
00334             std::cout << (boxes[2*(i*nvars+j)]+boxes[2*(i*nvars+j)+1])/2.0 << " ";
00335           std::cout << "]";
00336           std::cout << std::endl;
00337         };
00338       //    xml::print(std::cout,nsols2,"nb_sol")<< std::endl; 
00339       //    if ( nsols ) vctops::print(&tmp[0],nvars*nsols );
00340     };
00341     
00342     
00343     tmp.resize( nsols2 * nvars );
00344     //  cout <<"-----"<<endl;
00345     std::vector<T> vsol(nvars);
00346     //    Seq<vectdse<T> > res;
00347     for(int i=0;i<nsols2;++i)
00348       {
00349         for(int j=0; j<nvars; j++)
00350           vsol[j]=tmp[i*nvars+j];
00351         res.push_back(vsol);
00352       }
00353     //    return res;
00354   };
00355 
00356   template< class output, class MPC>
00357   static void solve_bernstein(output& sol, const MPC& l)
00358   {
00359      init_bernstein(l.begin(), l.end());
00360      std::vector<C> res; 
00361      int ns, nv; 
00362      ns=run(sol,nv);
00363      //     std::cout<<"system: nv="<<nv<< " ns="<< ns<<std::endl;
00364 
00365   }
00366 
00367 
00368   template< class output, class MPL, class DOM>
00369   static void solve(output& sol, const MPL& eqs, const DOM& dom)
00370   {
00371      init_bernstein(eqs.begin(), eqs.end());
00372      int nvars = sys->nvr();
00373      int ns, nv; 
00374      DOM dmns(dom);
00375      if((int)dom.size()>=2*nvars)
00376        ns=run(sol,&dmns[0],nv);
00377      else
00378        ns=run(sol,nv);
00379 
00380      //     std::cout<<"system: nv="<<nv<< " ns="<< ns<<std::endl;
00381 
00382   }
00383   //  ~solver_multivariate_bernstein() { delete sys; };
00384 
00385 };
00386 
00387   template<class C, int M> C solver<C,ProjRd<M> >::eps = std::pow(2.0,-solver_default_precision);
00388   template<class C, int M> realroot::system<C>* solver<C,ProjRd<M> >::sys = 0;
00389 
00390 //====================================================================
00391 // template<class C,int MTH= SBD_RDRDL> struct MVBST 
00392 // {
00393 //   static void set_precision(unsigned prec) 
00394 //   {
00395 //     solver_multivariate_bernstein<C,MTH>::set_precision(prec);
00396 //   }
00397 // };
00398 //====================================================================
00399 // template< class MPC, class Domains,  class C, int MTH>
00400 // Seq<std::vector<C> > solve( const MPC& l, MVBST<C,MTH> slv, const Domains& D, 
00401 //                          bool verbose = false  )
00402 // {
00403 //   Seq<std::vector<C> > sol; 
00404 //   solver_multivariate_bernstein<C,MTH>::solve(sol,l,D,verbose);
00405 //   return sol;
00406 // }
00407 //====================================================================
00408 #if 0
00409 template<class C, class MPC, class Domains, int MTH>
00410 Seq<std::vector<C> > 
00411 solve( const MPC& l, 
00412        const ProjRd<MTH> &, const Domains& D , 
00413        bool verbose = false ) {
00414 
00415   typedef typename MPC::value_type  POL;
00416   typedef typename POL::value_type coeff;
00417   typedef tensor::bernstein<QQ> bpol;
00418   typedef QQ Rational;
00419   typedef polynomial<C,   with<Bernstein> > Polynomial;
00420   typedef polynomial<Rational, with<Bernstein> > PolynomialQQ;
00421 
00422   typedef polynomial<Rational, with<Sparse,DegRevLex> > PolynomialSparse;
00423 
00424   Seq<Rational> box(D.size()); 
00425   for(unsigned i=0;i<D.size();i++) 
00426     let::assign(box[i],D[i]);
00427   std::cout<<"Box: "<<box<<std::endl;
00428 
00429   Polynomial   p;
00430   PolynomialQQ q;
00431   Seq<Polynomial> L;
00432   typedef typename MPC::const_iterator iterator;
00433   for(iterator i=l.begin();i!=l.end();i++) {
00434     let::assign(q.rep(),i->rep(),box);
00435     Rational mx = array::max_abs(q);
00436     //    q/=mx;
00437     //    std::cout<<q<<std::endl;
00438     let::assign(p.rep(),q.rep());
00439     //    std::cout<<p.rep()<<std::endl;
00440     L<<p;
00441   }
00442 
00443   Seq<std::vector<C> > sol; 
00444   solver<C, ProjRd<MTH> >::solve_bernstein(sol,L,D,verbose);
00445   return sol;
00446 }
00447 #endif
00448 //====================================================================
00449 template<class C, class MPC, class Domains, int MTH>
00450 Seq<std::vector<C> > 
00451 solve( const MPC& l, const ProjRd<MTH> &, const Domains& D , 
00452                             bool verbose = false ) {
00453   typedef typename MPC::value_type  POL;
00454   typedef typename POL::value_type coeff;
00455   //  typedef typename kernelof<coeff>::ieee C;
00456     typedef QQ Rational;
00457         Seq<Rational> box(D.size());
00458         for(unsigned i=0;i<D.size();i++)
00459                 let::assign(box[i],D[i]);
00460         std::cout<<"Box: "<<box<<std::endl;
00461         
00462         Seq<std::vector<C> > sol; 
00463         solver<C, ProjRd<MTH> >::solve_monomial(sol,l,D,verbose);
00464   return sol;
00465 }
00466 //====================================================================
00467 } //namespace mmx
00468 /********************************************************************/
00469 #endif //realroot_SOLVE_mslvbst_H