00001
00002
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
00017
00018
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
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?)
00048 //# define C_INCLUDE include3(b,J,S0) // Rump's Test
00049
00050
00052 # define C_EXCLUDE exclude3(b) //Sign Inspection
00053
00054
00055
00056
00057 namespace mmx {
00058 namespace realroot
00059 {
00060
00061
00062
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;
00072
00073 DPOL * J;
00074 Seq<POL *> S0;
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
00108 out= false;
00109 red= true;
00110 while ( !out && red )
00111 {
00112 if ( C_EXCLUDE )
00113 {
00114 out=true;
00115 if (VERBOSE) {
00116
00117
00118 }
00119 if (ALLBOXES)
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
00133
00134 }
00135
00136 }
00137 }
00138
00139 if ( out )
00140 {
00141 free(b);
00142 continue;
00143 }
00144
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
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
00178
00179
00180 ver++;
00181 }
00182
00183 b->subdivide (i,boxes, b->middle(i) );
00184
00185
00186
00187 free(b);
00188 }
00189 else
00190 {
00191 if ( C_EXCLUDE ){
00192 if (ALLBOXES) sol << (*b);
00193 }else
00194 {
00195 cand++;
00196 sol << (*b);
00197 if (VERBOSE) {
00198 std::cout<<"- EPS reached:"<<std::endl;
00199
00200 }
00201 }
00202 free(b);
00203 }
00204 }
00205 }
00206
00207 unsigned j=0;
00208
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 {
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
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
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
00261
00262
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
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
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
00289
00290
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
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
00309
00310 Seq<FT> t;
00311 Seq< BOX> s(solve_system(sys) );
00312
00313 Seq< std::vector<FT> > a;
00314
00315
00316
00317
00318
00319
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
00328
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
00341
00342 sys->restrict(dom);
00343 unsigned v;
00344 Seq<FT> d;
00345 BOX * l, * b;
00346 Seq<C> t;
00347
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
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 };
00412
00413 }
00414
00415
00416
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 }
00507
00508 # undef TMPL
00509 # undef SOLVER
00510 # undef DPOL
00511
00512 #endif