realroot_doc 0.1.1
|
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