00001
00002
00003
00004
00005 #ifndef _realroot_SOLVE_MV_CONFRAC_BOXREP_H
00006 #define _realroot_SOLVE_MV_CONFRAC_BOXREP_H
00007
00008
00010 # include <realroot/ring_monomial_tensor.hpp>
00012
00013
00014
00015 # include <realroot/polynomial.hpp>
00016 # include <realroot/homography.hpp>
00017 # include <realroot/sign_variation.hpp>
00018 # include <realroot/Interval.hpp>
00019 # include <stack>
00020
00021 # include <realroot/solver_ucf.hpp>
00022 # include <realroot/solver_uv_bspline.hpp>
00023
00024
00025
00026 # define DPOL polynomial<double,with<MonomialTensor> >
00027
00028 # define INFO 1
00029
00030 # define TODOUBLE as<double>
00031
00032
00033
00034 namespace mmx {
00035
00036 namespace realroot {
00037
00039 template<class POL>
00040 class box_rep
00041 {
00042 typedef typename POL::scalar_t C;
00043 typedef Seq<POL *> system_t;
00044 typedef std::stack<box_rep<POL> *> STACK;
00045
00046
00047 unsigned dim;
00048 homography_mv<C> hg;
00049
00050
00051
00052 public:
00053
00054
00055 Seq<POL> S;
00056
00057 void inline update_data()
00058 {
00059
00060
00061
00062
00063 #ifdef DIVISION
00064 for( unsigned i=0; i<S.size(); i++ ){
00065 t= *std::max_element( (S[i]).begin(), (S[i]).end() );
00066 S[i]= S[i]/t;
00067 }
00068 #endif
00069
00070
00071 Seq<double> c= this->point( this->middle() ) ;
00072
00073 Seq<POL> S1= S;
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 }
00087
00088 box_rep() {};
00089
00090 box_rep(Seq<POL>& sys, homography_mv<C>& h)
00091 {
00092 hg = h ;
00093 dim= h.size();
00094 S= sys;
00095
00096 update_data();
00097 };
00098
00099
00100 box_rep( box_rep<POL> b, int i)
00101 {
00102 dim= b.nbvar();
00103 hg = b.homography();
00104
00105 hg.shift_hom(b.middle(i) ,i);
00106 hg.colapse();
00107
00108 S= b.system();
00109 };
00110
00111
00112 box_rep( Seq<POL>& sys, unsigned d)
00113 {
00114 dim=d;
00115 hg = homography_mv<C>(dim) ;
00116
00117 S= sys;
00118 }
00119
00120
00121 ~box_rep() {};
00122
00123 void restrict( Seq<Interval<C> > & dom0 )
00124 {
00125
00126
00127
00128 unsigned i,j;
00129
00130 for (i=0; i!=dim; i++)
00131 {
00132 hg.shift_hom ( dom0[i].m , i );
00133 hg.contract_hom ( dom0[i].width(), i );
00134 hg.reciprocal_hom( 1 , i );
00135 hg.shift_hom ( 1 , i );
00136 hg.reciprocal_hom( 1 , i );
00137 for (j=0; j!=S.size(); j++)
00138 {
00139 shift ( S[j].rep(), dom0[i].m , i);
00140 contraction( S[j].rep(), dom0[i].width(), i);
00141 reciprocal ( S[j].rep(), i);
00142 shift ( S[j].rep(), C(1), i);
00143 reciprocal ( S[j].rep(), i);
00144 }
00145 }
00146 update_data();
00147 }
00148
00150 inline Seq<POL> system() { return S; }
00151 inline homography_mv<C> homography() { return this->hg; }
00152 inline POL system(unsigned i) { return S[i]; }
00153 inline unsigned nbvar() { return dim; }
00154 inline unsigned nbpol() { return S.size(); }
00155
00156 template<class FT>
00157 FT volume()
00158 {
00159 Seq<Interval<FT> > s;
00160 FT v(1);
00161
00162 s= domain<FT>();
00163
00164 for (unsigned i=0; i!=s.size(); i++ )
00165 v *= s[i].width();
00166
00167 return v;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177 template<class C>
00178 int** submatrix(C **matrix, int order, int i, int j)
00179 {
00180
00181 C **subm;
00182 int p, q;
00183 int a = 0, b;
00184 subm = new int* [order - 1];
00185
00186 for(p = 0; p < order; p++) {
00187 if(p==i) continue;
00188 subm[a] = new C[order - 1];
00189
00190 b = 0;
00191
00192 for(q = 0; q< order; q++) {
00193 if(q==j) continue;
00194 subm[a][b++] = matrix[p][q];
00195 }
00196 a++;
00197 }
00198 return subm;
00199 }
00200
00201
00202 template<class C>
00203 C det(C **matrix, int order)
00204 {
00205 if(order == 1)
00206 return **matrix;
00207
00208 int i;
00209 C ev(0);
00210 for(i = 0; i < order; i++)
00211 ev += (i%2==0?1:-1)* matrix[i][0] * det(submatrix(matrix, order, i, 0), order - 1);
00212 return ev;
00213 }
00214
00215
00216 inline int signof(DPOL * p)
00217 {
00218
00219 Interval<double> ev;
00220
00221
00222 tensor::eval( ev , p->rep() ,
00223 this->template domain<double>() , dim );
00224
00225 if (ev< .1e-15) return (0);
00226 return (ev>0?1:-1);
00227 }
00228
00229
00230
00231 homography_mv<C> hom() { return hg; }
00232 POL system(const int i) { return S[i]; }
00233
00234 template<class FT>
00235 Seq<Interval<FT> > domain()
00236 {
00237 FT l, r;
00238 Seq<Interval<FT> > s ;
00239
00240 for ( unsigned i=0; i!=dim; ++i )
00241 {
00242
00243 if ( hg[i].b!=0 && hg[i].d!=0 )
00244 l= as<FT>(hg[i].b)/as<FT>(hg[i].d);
00245 else if ( hg[i].d==0 )
00246 l= 10000000;
00247 else if ( hg[i].b==0 )
00248 l= 0 ;
00249 else
00250 l= as<FT>(hg[i].a)/as<FT>(hg[i].c) ;
00251
00252
00253 if ( hg[i].a!=0 && hg[i].c!=0 )
00254 r= as<FT>(hg[i].a)/as<FT>(hg[i].c);
00255 else if ( hg[i].c==0 )
00256 r=10000000;
00257 else if ( hg[i].a==0 )
00258 r= 0 ;
00259 else
00260 r= as<FT>(hg[i].b)/as<FT>(hg[i].d);
00261
00262 if ( l<=r ) s << Interval<FT>(l,r);
00263 else s << Interval<FT>(r,l);
00264 }
00265 return s;
00266 }
00267
00268 Seq<C> middle()
00269 {
00270 Seq<C> m;
00271 for ( unsigned i=0; i!=dim; ++i )
00272 m << as<C>( floor( as<double>(hg[i].d/hg[i].c) )) ;
00273 return (m);
00274 }
00275
00276 C middle(int i)
00277 {
00278 C t;
00279 t= as<C>( floor( as<double>(hg[i].d/hg[i].c) ));
00280
00281 return (t+1);
00282 }
00283
00284
00285 template<class FT>
00286 Seq<FT> point(Seq<FT> t)
00287 {
00288 assert( t.size()==dim );
00289 Seq<FT> m;
00290 for ( unsigned i=0; i!=dim; ++i )
00291 m << ( as<FT>(hg[i].a)*(t[i]) + as<FT>(hg[i].b) ) /
00292 ( as<FT>(hg[i].c)*(t[i]) + as<FT>(hg[i].d) ) ;
00293 return m;
00294 }
00295
00296 Seq<C> subdiv_center(const unsigned& i)
00297 {
00298 Seq<C> tt;
00299
00300 tt.resize( dim );
00301 tt[i]= this->middle(i);
00302
00303 return tt;
00304 }
00305
00306 Seq<double> subdiv_point(const unsigned& i)
00307 {
00308 return this->template point<double>(this->subdiv_center(i));
00309 }
00310
00311 template<class FT> inline
00312 Seq<FT> eval(Seq<FT> t)
00313 {
00314 assert( t.size()==dim );
00315 Seq<FT> res;
00316 FT ev;
00317 for ( unsigned i=0; i!=S.size() ; ++i )
00318 {
00319 tensor::eval( ev , S[i].rep(), t, dim );
00320 res<< ev;
00321 }
00322 return res;
00323 }
00324
00325
00326 inline bool is_root(Seq<C> t)
00327 {
00328 assert( t.size()==dim );
00329 C ev;
00330 for ( unsigned i=0; i!=S.size() ; ++i )
00331 {
00332 tensor::eval( ev , S[i].rep() , t , dim );
00333 if ( ev != 0 )
00334 return false;
00335 }
00336 return true;
00337 }
00338
00339
00341 bool reduce_domain()
00342 {
00343 C lb;
00344 unsigned i;
00345 bool flag= false;
00346
00347 Seq<C> track;
00348
00349
00350 for ( i=0; i<dim ;++i)
00351 {
00352 lb= l_bound(i);
00353 track<< lb;
00354 if ( lb!=0 )
00355 {
00356 this->shift_box(lb,i);
00357 update_data();
00358 flag= true;
00359 }
00360 }
00361 return flag;
00362 };
00363
00365 C l_bound( const int v )
00366 {
00367 C l(0) ;
00368 unsigned i;
00369 POL m0, m1 ;
00370
00371 for (i=0; i!=S.size(); ++i )
00372 {
00373 m1= maxs( & S[i] , v);
00374 m0= mins( & S[i] , v);
00375
00376
00377 if ( m0( C(0) ) > 0 )
00378 l= solver<ring<C,MonomialTensor>, CFfirstFloor>::template solve<C>(m0);
00379
00380 else if ( m1( C(0) ) < 0 )
00381 l= solver<ring<C,MonomialTensor>, CFfirstFloor>::template solve<C>(m1);
00382
00383 }
00384 return l;
00385 };
00386
00387
00388 POL mins( POL * f, int v)
00389 {
00390 POL h(0,f->rep().szs()[v]-1,0) ;
00391 tensor::mins(h.rep(), f->rep(), v );
00392 return h;
00393 };
00394
00395
00396 POL maxs( POL * f, int v)
00397 {
00398 POL h(0,f->rep().szs()[v]-1,0) ;
00399 tensor::maxs(h.rep(), f->rep(), v );
00400 return h;
00401 };
00402
00403
00405 void subdivide( STACK & stck )
00406 {
00407 int i;
00408 Seq<int> ind(dim);
00409 box_rep * b;
00410
00411 for (;;)
00412 {
00413
00414 b = new box_rep( *this ) ;
00415
00416
00417 for (i = 0; i < dim ; ++i)
00418 if ( ind[i] )
00419 b->shift_box(1,i);
00420 else
00421 b->reverse_and_shift_box(i);
00422 b->update_data();
00423
00424
00425 stck.push ( b );
00426
00427
00428 for (i = 0; i < dim ; ++i)
00429 if (++ind[i] <2 ) break; else ind[i]=0 ;
00430 if (i == dim ) break;
00431 }
00432 };
00433
00434
00436 void safe_split(const int &v, C m=C(1) )
00437 {
00438 box_rep * b;
00439
00440 b = new box_rep( *this ) ;
00441
00442
00443
00444
00445 };
00446
00447
00448
00450 void subdivide( const int &v, STACK & stck, C m=C(1) )
00451 {
00452 box_rep * b;
00453
00454
00455 b = new box_rep( *this ) ;
00456 b->shift_box( m ,v);
00457 b->update_data();
00458 stck.push ( b );
00459
00460
00461 b = new box_rep( *this ) ;
00462 b->contract_box(m,v);
00463 b->reverse_and_shift_box(v);
00464
00465 b->update_data();
00466 stck.push ( b );
00467 };
00468
00470 void subdivide( const int &v, C & m, STACK & stck )
00471 {
00472 box_rep * b;
00473 box_rep tmp(*this);
00474
00475
00476 b = new box_rep( tmp ) ;
00477 b->contract_box( m ,v);
00478 b->reverse_and_shift_box(v);
00479 b->reverse_box( v);
00480 b->update_data();
00481 stck.push ( b );
00482
00483
00484 b = new box_rep( tmp ) ;
00485 b->shift_box( m, v);
00486 b->update_data();
00487 stck.push ( b );
00488 };
00489
00491 void shift_box(const C& t, const int & v = 0)
00492 {
00493 unsigned i;
00494
00495 for (i = 0; i < S.size() ; ++i)
00496 shift( S[i].rep() , t, v);
00497
00498
00499 hg.shift_hom(t,v);
00500 };
00501
00503 void contract_box(const C & t, const int & v )
00504 {
00505 unsigned i;
00506
00507 for (i = 0; i < S.size() ; ++i)
00508 contraction( S[i].rep() , t, v);
00509
00510
00511 hg.contract_hom(t,v);
00512 };
00513
00514
00515 void reverse_box(const int & v )
00516 {
00517 for (unsigned i = 0; i < S.size() ; ++i)
00518 reciprocal( S[i].rep() , v);
00519
00520
00521 hg.reciprocal_hom(1,v);
00522 };
00523
00524
00525 void reverse_and_shift_box(const int & v )
00526 {
00527 for (unsigned i = 0; i < S.size() ; ++i)
00528 {
00529 reciprocal( S[i].rep() , v);
00530 shift ( S[i].rep() ,C(1), v);
00531 }
00532
00533
00534 hg.reciprocal_hom(1,v);
00535 hg.shift_hom (1,v);
00536 };
00537
00538
00539 bool inline miranda_test(const int i,const int j)
00540 {
00541 POL u,l;
00542
00543 tensor::face(l, S[i], j, 0);
00544 tensor::face(u, S[i], j, 1);
00545
00546 return ( no_variation(l) &&
00547 no_variation(u) &&
00548 (l[0]>0)!=(u[0]>0) );
00549 };
00550
00552
00553 template<class FT>
00554 bool include1(DPOL * J)
00555 {
00556 Interval<double> ev;
00557 unsigned i,j,c;
00558 POL u,l;
00559
00560 bool t[dim][dim];
00561
00562 tensor::eval( ev , J->rep() ,
00563 this->template domain<double>() , dim );
00564 if ( ev.m*ev.M < 0 )
00565 return false;
00566
00567 for (i=0; i!=dim;++i)
00568 for (j=0; j!=dim;++j)
00569 t[i][j]= miranda_test(i,j);
00570
00571 c=0;
00572 for (i=0; i!=dim;++i)
00573 for (j=0; j!=dim;++j)
00574 if (t[i][j]==true)
00575 {
00576 c++; break;
00577 }
00578 if (c<dim) return false;
00579
00580 c=0;
00581 for (i=0; i!=dim;++i)
00582 for (j=0; j!=dim;++j)
00583 if (t[j][i]==true)
00584 {
00585 c++; break;
00586 }
00587 if (c<dim) return false;
00588
00589
00590
00591 return true;
00592 };
00593
00595 bool include2(DPOL * J)
00596 {
00597 Interval<double> ev;
00598
00599 tensor::eval( ev , J->rep() ,
00600 this->domain<double>(), dim );
00601
00602
00603 if ( ev.m*ev.M < 0 )
00604 return false;
00605
00606
00607
00608
00609
00610
00611 return ( 0 );
00612 }
00613
00615 bool include3(DPOL * J)
00616 {
00617
00618
00619
00620
00621 Interval<double> ev;
00622
00623 tensor::eval( ev , J->rep() ,
00624 this->domain<double>(), dim );
00625
00626
00627 if ( ev.m*ev.M < 0 )
00628 return false;
00629
00630
00631
00632
00633
00634
00635 return ( 0 );
00636 }
00637
00638
00640 template<class FT>
00641 bool exclude1( Seq<POL *>& S0)
00642 {
00643 Interval<FT> ev;
00644 Seq<Interval<FT> > dom;
00645 dom= domain<FT>();
00646
00647 for (unsigned i=0; i!=nbpol(); ++i)
00648 {
00649 tensor::eval( ev , S0[i]->rep(),
00650 dom , dim );
00651 if ( ev.m*ev.M > 0 )
00652 {
00653
00654
00655
00656
00657
00658 return true;
00659 }
00660
00661 }
00662 return false;
00663 };
00664
00666 template<class FT>
00667 inline FT width()
00668 {
00669 unsigned i;
00670 FT m=this->width<FT>(i);
00671
00672 return m;
00673 };
00674
00676 template<class FT>
00677 FT width(unsigned & t)
00678 {
00679 unsigned i;
00680 FT w;
00681 Seq<Interval<FT> > s ;
00682
00683 s= domain<FT>();
00684 w= s[0].width(); t= 0;
00685
00686 for ( i=0; i!=s.size(); ++i )
00687 if ( s[i].width() > w)
00688 { w=s[i].width() ; t=i; }
00689
00690 return w;
00691 };
00692
00693 POL lface(const int & i, const int & v)
00694 {
00695 POL t;
00696
00697 tensor::face(t, S[i], v , 0 );
00698 rename_var( t.rep() , 1-v, 0 ) ;
00699
00700 return t;
00701 };
00702
00703 POL rface(const int & i, const int & v)
00704 {
00705 POL tmp;
00706 tensor::face(tmp, S[i], v , 1 );
00707 rename_var( tmp.rep() , 1-v, 0 ) ;
00708
00709 return tmp;
00710 };
00711
00712 void print()
00713 {
00714 std::cout << "-------------Box---------------" << "\n" ;
00715 std::cout << system() << "\n";
00716 for (unsigned i=0; i!=dim;++i)
00717 std::cout<< "("<<hg[i].a <<"x + " << hg[i].b<<")/("<<hg[i].c<<"x+ "<<hg[i].d << ")"<<std::endl; ;
00718
00719
00720 std::cout << this->template domain<double>()<<"\n" ;
00721 std::cout << "-------------------------------" << "\n" ;
00722 };
00723
00724
00725 };
00726
00727 }
00728 }
00729
00730 # undef DPOL
00731 #endif