realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/solver_mv_monomial.hpp
Go to the documentation of this file.
00001 /********************************************************************
00002  *   Author(s): A. Mantzaflaris, GALAAD, INRIA
00003  ********************************************************************/
00004 #ifndef _realroot_SOLVE_MV_CONFRAC_H
00005 #define _realroot_SOLVE_MV_CONFRAC_H
00006 /********************************************************************/
00012 # include <realroot/Interval.hpp>
00013 #include <realroot/texp_rationalof.hpp>
00014 #include <ctime>
00015 
00016 //# include <realroot/IEEE754.hpp>
00017 //# include <realroot/polynom.hpp>
00018 //# include <realroot/ring_tens.hpp>
00019 
00020 # include <realroot/univariate_bounds.hpp>
00021 # include <realroot/linear_doolittle.hpp>
00022 
00023 # include <realroot/homography.hpp>
00024 # include <realroot/solver_mv_monomial_box_rep.hpp>
00025 # include <realroot/solver_mv_monomial_tests.hpp>
00026 
00027 # include <stack>
00028 //# include <realroot/solver.hpp>
00029 
00030 //====================================================================
00031 # define TMPL  template<class POL>
00032 # define TMPLF template<class FT, class POL>
00033 # define SOLVER solver<C,MCFisolate >
00034 
00035 # define BOX   box_rep<POL>
00036 # define N_ITER 50000
00037 
00038 
00039 # define ALLBOXES 0
00040 # define VERBOSE  0
00041 
00042 # define DPOL polynomial<double,with<MonomialTensor> >
00043 
00045 
00046 # define C_INCLUDE include1(b,J) // Miranda test.  (degens?)
00047 
00048 //# define C_INCLUDE include3(b,J,S0) // Rump's Test
00049 
00050 //# define C_EXCLUDE exclude1(b,S0) // Interval arithmetic
00052 # define C_EXCLUDE exclude3(b)  //Sign Inspection
00053 //# define C_EXCLUDE exclude1(b,S0) || exclude3(b) //both
00054 
00055 
00056 //====================================================================
00057 namespace mmx {
00058 namespace realroot
00059 {
00060 
00061 //====================================================================
00062 // ---------------------- Solver class  ------------------------------
00063 //====================================================================
00064 
00065 TMPLF
00066 class solver_mv_monomial
00067 {
00068   typedef typename POL::scalar_t C;
00069   typedef std::stack< BOX * >  STACK;
00070   
00071   double    eps;// precision
00072   //DPOL   *  jac;// jacobian matrix with double coefficients
00073   DPOL      * J;// jacobian matrix with double coefficients
00074   Seq<POL *> S0;// initial polynomials 
00075 public:
00076   
00078   solver_mv_monomial(double e=1e-7)
00079     {
00080       J=NULL;
00081       eps=e;
00082     }; 
00083   
00085   Seq<BOX> solve_system(BOX & sys)
00086     {
00087       unsigned c=0,cand=0, i, it=0, subs=0, ver=0;
00088       BOX * b = NULL;
00089       BOX * r = NULL;
00090       Seq<BOX> sol;
00091       Seq<BOX> psol;
00092       bool red, out;
00093       STACK boxes;
00094 
00095       FT v(0), bx;
00096       bx= sys.template volume <FT>();
00097       if (VERBOSE) sys.print();
00098       
00099       boxes.push( new BOX(sys) );
00100       
00101       while ( !boxes.empty() )
00102       {
00103         it++;
00104         b = boxes.top() ;
00105         boxes.pop();
00106 
00107         /*reduce the domain */
00108         out= false;
00109         red= true;
00110         while ( !out && red )
00111         {
00112           if ( C_EXCLUDE )
00113           { 
00114             out=true;
00115             if (VERBOSE) { 
00116               //std::cout<<"- Excluded:"<<std::endl;
00117               //b->print();
00118             }                       
00119             if (ALLBOXES) //FOR AXEL
00120             {
00121               v+= b->template volume<FT>();
00122               r = new BOX( *b ) ;
00123               sol << (*r); 
00124               free(r);
00125             }
00126             c++;
00127           }
00128           else
00129           {
00130             red= b->reduce_domain(); 
00131             if (VERBOSE && red) { 
00132               //std::cout<<"- Reduced:"<<std::endl;
00133               //b->print();
00134             }            
00135             //red= false;
00136           }
00137         }
00138 
00139         if ( out ) 
00140         {
00141           free(b);
00142           continue;
00143         }               
00144         /*check for root */
00145         if ( C_INCLUDE )
00146         { 
00147           if (VERBOSE) { 
00148             std::cout<<"- Solution found:"<<std::endl;
00149             b->print();
00150           }
00151           
00152           ver++ ;
00153           sol << (*b);
00154           free(b);
00155           continue; 
00156         }
00157         
00158         /*Subdivide*/
00159         if ( it > N_ITER )
00160         {
00161           cand++;
00162           std::cout<<"MAX iters"<<" ("<<N_ITER<<") "
00163                    <<"reached!" << std::endl;
00164           b->print();
00165           sol << (*b);
00166           free(b);
00167         }
00168         else
00169         {
00170           if ( b->template width<double>(i) > eps )
00171           {     
00172             subs++;
00173           
00174             if (check_root( b->subdiv_point(i),eps) )
00175             {
00176               psol <<BOX( *b, i);
00177               //free(b);
00178               //continue; 
00179               //sol[sol.size()-1].print();
00180               ver++;
00181             }
00182 
00183             b->subdivide (i,boxes, b->middle(i) );
00184             //b->subdivide (i,boxes);
00185             //b->subdivide (i,boxes,   1 );
00186             //b->subdivide (boxes);
00187             free(b); 
00188           }
00189           else 
00190           {
00191             if ( C_EXCLUDE  ){
00192               if (ALLBOXES) sol << (*b); //FOR AXEL
00193             }else
00194             {   
00195               cand++;
00196               sol << (*b);
00197               if (VERBOSE) { 
00198                 std::cout<<"- EPS reached:"<<std::endl;
00199                 //b->print();
00200               }
00201             }
00202             free(b);
00203           }
00204         }               
00205       }/*while*/
00206       
00207       unsigned j=0;
00208       //if (0)
00209       if ( !ALLBOXES && S0.size()==2)
00210       while (j<sol.size())
00211       {
00212         if ( exclude2( &sol[j],J) )
00213         {
00214           sol.erase(j);
00215           cand--;
00216         }
00217         else 
00218         { //std::cout  <<"td="<<sol[j].td<<std::endl;
00219           ++j; 
00220         }
00221       }
00222 
00223       if (VERBOSE) {
00224       std::cout<< "Iterations= "<< it           <<std::endl;    
00225       std::cout<< "Excluded  = "<< c            <<std::endl;    
00226       std::cout<< "Verified  = "<< ver          <<std::endl;    
00227       std::cout<< "Subdivs   = "<< subs         <<std::endl;
00228       if (ALLBOXES)
00229         std::cout<< "Reduced volume= "<< 
00230           as<double>(  100*(bx-v)/bx )<< "\%"     <<std::endl;  
00231       std::cout<< "#stack=     "<< cand         <<std::endl;    
00232       }
00233       sol<< psol;
00234 
00235       return sol;
00236     }
00237   
00238   Seq< std::vector<Interval<FT> > > isolate(Seq<POL>& p, unsigned &d)
00239     {
00240       homography_mv<C> h(d);                            
00241       BOX sys= BOX(p,h);
00242       
00243       /*Global data*/
00244       free(J);
00245       for (unsigned i=0;i<S0.size();++i) 
00246         free(S0[i]);
00247       S0=Seq<POL *>();
00248       for (unsigned i=0;i<sys.nbpol();++i) 
00249         S0 << new POL( sys.system(i) );     
00250       J= jacobian(S0);
00251       /*end Global data*/
00252       
00253       Seq< BOX> s(solve_system(sys) );
00254       
00255       Seq< std::vector<Interval<FT> > > a;
00256       
00257       for (unsigned i=0; i<s.size(); ++i)
00258         a << s[i].template domain<FT>().rep();
00259                
00260 //      free(J);
00261 //      for (unsigned i=0;i<S0.size();++i) 
00262 //        free(S0[i]);  
00263       return a;
00264     }
00265   
00266   Seq< std::vector<Interval<FT> > > isolate(Seq<POL>& p, Seq<Interval<C> > & dom)
00267         {
00268           BOX * sys= new BOX(p, dom.size() );
00269           
00270           /*Global data*/
00271           free(J);
00272           for (unsigned i=0;i<S0.size();++i) 
00273             free(S0[i]);
00274           S0=Seq<POL *>();
00275           for (unsigned i=0;i<sys->nbpol();++i) 
00276             S0 << new POL( sys->system(i) );        
00277           J= jacobian(S0);
00278           /*end Global data*/
00279 
00280           sys->restrict(dom);
00281           Seq< BOX> s(solve_system( *sys) );
00282       
00283           Seq< std::vector<Interval<FT> > > a;
00284 
00285           for (unsigned i=0; i<s.size(); ++i)
00286             a << s[i].template domain<FT>().rep();
00287           
00288 //          free(J);
00289 //          for (unsigned i=0;i<S0.size();++i) 
00290 //            free(S0[i]);
00291           return a;
00292         }
00293   
00294   
00295   Seq< std::vector<FT> > approximate(Seq<POL>& p, unsigned &d)
00296     {
00297       homography_mv<C> h(d);                            
00298       BOX sys= BOX(p,h);
00299       
00300       /*Global data*/
00301       free(J);
00302       for (unsigned i=0;i<S0.size();++i) 
00303         free(S0[i]);
00304       S0=Seq<POL *>();
00305       for (unsigned i=0;i<sys->nbpol();++i) 
00306         S0 << new POL( sys->system(i) );            
00307       J= jacobian(S0);
00308       /*end Global data*/
00309       
00310       Seq<FT> t;
00311       Seq< BOX> s(solve_system(sys) );
00312       
00313       Seq< std::vector<FT> > a;
00314       
00315       // ... inf ?
00316       
00317 //      free(J);
00318 //      for (unsigned i=0;i<S0.size();++i) 
00319 //        free(S0[i]);
00320       return a;
00321         }
00322   
00323   Seq< std::vector<FT> > approximate(Seq<POL>& p, Seq<Interval<C> > & dom)
00324     {
00325       BOX * sys= new BOX(p, dom.size() );
00326       
00327        /*Global data*/
00328        // free(J); //crash
00329       for (unsigned i=0;i<S0.size();++i) 
00330         free(S0[i]);
00331       S0=Seq<POL *>();
00332       for (unsigned i=0;i<sys->nbpol();++i) 
00333         S0 << new POL( sys->system(i) );            
00334 
00335 
00336 
00337       
00338 
00339       J= jacobian(S0);
00340       /*end Global data*/
00341       
00342       sys->restrict(dom);
00343       unsigned v; //, dim(dom.size() );
00344       Seq<FT> d;
00345       BOX * l, * b;
00346       Seq<C> t;
00347       //FT ev;
00348       Seq<BOX> s(solve_system(*sys) );
00349       
00350       Seq< std::vector<FT> > a;
00351       
00352       for (unsigned i=0;i<s.size(); ++i )
00353       {
00354         b= new BOX(s[i]);
00355         
00356         while ( b->template width<FT>(v) > eps )
00357         {
00358           t= b->middle();
00359           if ( b->is_root(t) ) 
00360           {
00361             d= b->template point<FT>(t);
00362             a << d.rep();
00363           }
00364           
00365           l= new BOX( *b ) ;
00366           l->shift_box( t[v] , v );
00367           
00368           if ( C_INCLUDE ) 
00369           {   
00370             free(b);
00371             b=l; 
00372             continue;
00373           }
00374           else 
00375           {   
00376             free(l);
00377             b->contract_box(t[i],v);
00378             b->reverse_and_shift_box(v);
00379             b->reverse_box(v);
00380           }
00381         }
00382         d= b->template domain<FT>();
00383         a << d.rep();
00384         free(b);
00385       }
00386       return a;
00387     }
00388   
00389 
00390   bool check_root(const Seq<double> t, const double eps) 
00391     {
00392       DPOL p(0);
00393       double ev;
00394       for (unsigned j=0; j!=S0.size(); ++j)
00395       {
00396         
00397         let::assign(p, *S0[j]);
00398         tensor::eval( ev , p.rep() , 
00399                       t , t.size() );
00400 
00401         //std::cout<<"check: "<< ev<<std::endl;
00402         if ( abs(ev) > 1e-10 )
00403           return false;
00404       } 
00405       std::cout<<"Root on split: "<< t  <<std::endl;
00406       return true;
00407 
00408     };
00409 
00410   
00411 };// solver_mv_monomial
00412   
00413 } //namespace realroot
00414   
00415 //====================================================================
00416 // --------------------------- INTERFACE -----------------------------
00417 //====================================================================
00418 
00419     struct MCFisolate{};
00420     struct MCFapproximate{};
00421 
00422 //--------------------------------------------------------------------
00423 
00424     template<class C>
00425     struct solver<C, MCFisolate > {
00426 
00427         typedef C   base_t;
00428 
00429         template<class FT, class POL> 
00430         static Seq< std::vector<Interval<FT> > >
00431         solve( Seq<POL>& p, Seq< Interval<base_t> > & dom);
00432 
00433         template<class FT, class POL>
00434         static Seq<std::vector<Interval<FT> > >
00435         solve( Seq<POL>& p);
00436 };
00437 
00441 template<class C> 
00442 template<class FT, class POL> 
00443 Seq< std::vector<Interval<FT> > >
00444 SOLVER::solve( Seq<POL>& p, Seq<Interval<base_t> > & dom)
00445 {
00446 
00447     realroot::solver_mv_monomial<FT,POL> slv(1e-3);
00448     return  slv.isolate(p, dom);
00449 }
00450 
00454 template<class C> 
00455 template<class FT,class POL> 
00456 Seq<std::vector<Interval<FT> > >
00457 SOLVER::solve(Seq<POL>& p) {
00458     
00459     unsigned d(p[0].nbvar() );
00460     realroot::solver_mv_monomial<FT,POL>  slv(1e-3);
00461     return slv.isolate(p,d);
00462 }
00463 
00464 
00465 //--------------------------------------------------------------------
00466 template<class C>
00467 struct solver<C, MCFapproximate > {
00468 
00469         typedef C   base_t;
00470         template<class FT, class POL> static Seq< std::vector<FT> >
00471         solve( Seq<POL>& p, Seq<Interval<base_t> > & dom);
00472 
00473         template<class FT, class POL> static Seq< std::vector<FT> >
00474         solve( Seq<POL>& p);
00475 };
00476 
00481 template<class Ring> 
00482 template<class FT, class POL> 
00483 Seq< std::vector<FT> >
00484 solver<Ring,MCFapproximate >::solve( Seq<POL>& p, Seq<Interval<base_t> > & dom)
00485 {
00486     realroot::solver_mv_monomial<FT,POL> slv(1e-3);
00487     return slv.approximate(p, dom );
00488 }
00489 
00493 template<class C> 
00494 template<class FT, class POL> 
00495 Seq< std::vector<FT> >
00496 solver<C,MCFapproximate >::solve( Seq<POL>& p)
00497 {
00498     
00499     unsigned d( p[0].nbvar() );
00500     realroot::solver_mv_monomial<FT,POL> slv(1e-3);
00501     
00502     return slv.approximate(p,d);
00503 }
00504 
00505 
00506 } //namespace mmx 
00507 //====================================================================
00508 # undef TMPL
00509 # undef SOLVER
00510 # undef DPOL
00511 //====================================================================
00512 #endif