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: parallel.h,v 1.1 2005/07/11 10:03:56 jppavone Exp $ 00005 ********************************************************************/ 00006 #ifndef realroot_SOLVE_SBDSLV_PARALLEL_HPP 00007 #define realroot_SOLVE_SBDSLV_PARALLEL_HPP 00008 //-------------------------------------------------------------------- 00009 //#include <realroot/debug_stream.hpp> 00010 //-------------------------------------------------------------------- 00011 namespace mmx { 00012 //-------------------------------------------------------------------- 00013 namespace realroot 00014 { 00015 /* solveur de reduction parallèle */ 00016 /* ------------------------------- */ 00017 /* améliorations: */ 00018 /* (1) rejet acceleré: subdiviser au niveau des intersections entre bornes */ 00019 /* (2) si (1) est implementé on devrait assez vite arriver a la situation ou il n'y a */ 00020 /* qu'une borne à traiter => solveur de descartes */ 00021 /* oops: la version utilisée dans la thèse ne permettait pas les réductions multiples !!! */ 00022 /* je m'en suis rendu compte un peu tard, à une époque je prétendait que certains */ 00023 /* systèmes pouvaient être résolus sans subdivision, cela a dû être vrai avec le */ 00024 /* solveur de descartes que je n'ai plus utilisé par la suite ... */ 00025 00026 namespace rdslv 00027 { 00028 template< class system > 00029 struct parallel : system::vstack_t 00030 { 00031 typedef typename system::creal_t creal_t; 00032 typedef typename system::interval_t interval_t; 00033 typedef typename system::vstack_t vstack_t; 00034 typedef typename vstack_t::sz_t sz_t; 00035 00036 /* incrementation et decrementation de la pile */ 00037 sz_t pinc ( sz_t iptr ) 00038 { 00039 assert(iptr%4 == 0); 00040 sz_t i,s; 00041 for ( s = i = 0; i < 4*this->nbp(); s += pmsz(iptr+i)+pMsz(iptr+i), i += 4 ) ; 00042 s = allocc(s+2)+2; 00043 sz_t inext = alloci(this->nbp()*4); 00044 for ( i = 0; i < 4*this->nbp(); s += pmsz(iptr+i)+pMsz(iptr+i), i += 4 ) 00045 { 00046 pmsz(inext+i) = pmsz(iptr+i); 00047 pmad(inext+i) = s; 00048 pMad(inext+i) = s + pmsz(iptr+i); 00049 pMsz(inext+i) = pMsz(iptr+i); 00050 }; 00051 return inext; 00052 }; 00053 00054 sz_t pdec( sz_t iptr ) 00055 { 00056 sz_t s,i; 00057 for ( s = i = 0; i < 4*this->m_nbp; s += pmsz(iptr+i)+pMsz(iptr+i), i += 4 ) ; 00058 this->m_cpchnk.dec( s + 2 ); 00059 this->m_ipchnk.dec(4*this->nbp()); 00060 iptr = iptr - 4*this->nbp(); 00061 return iptr; 00062 }; 00063 00064 00065 bool process( std::vector<interval_t>& reductions, const vstack_t& vp, const creal_t& eps = 1e-3, int k = 12 ) 00066 { 00067 this->copy(vp); /* duplication de la pile de projections */ 00068 sz_t iptr, inext, mxsgn, sgn, i, nmult; 00069 int itk = 0; 00070 nmult = iptr = 0; 00071 00072 for ( ; itk >= 0; ) 00073 { 00074 sgn = mxsgn = 0; 00075 00076 /* projections basses */ 00077 for ( mxsgn = i = 0; i < 4*this->nbp(); i += 4 ) 00078 { 00079 if ( pmsz(iptr+i) && !(sgn = vctops::sgnchg(pmdata(iptr+i),pmsz(iptr+i))) ) 00080 { 00081 pmsz(iptr+i) = 0; 00082 if ( *pmdata(iptr+i) > 0.0 ) break; 00083 }; 00084 if ( mxsgn < sgn ) mxsgn = sgn; 00085 }; 00086 if ( i < 4*this->nbp() ) { iptr = pdec(iptr); itk --; continue; }; 00087 00088 /* projection hautes */ 00089 for ( i = 0; i < 4*this->nbp(); i += 4 ) 00090 { 00091 if ( pMsz(iptr+i) && !(sgn = vctops::sgnchg( pMdata(iptr+i), pMsz(iptr+i))) ) 00092 { 00093 pMsz(iptr+i) = 0; 00094 if ( *pMdata(iptr+i) < 0.0 ) break; 00095 }; 00096 if ( mxsgn < sgn ) mxsgn = sgn; 00097 }; 00098 if ( i < 4*this->nbp() ) { iptr = pdec(iptr); itk --; continue; }; 00099 00100 /* si le domaine a été accepté, si la précision ou le quota de multiplication est dépassé. */ 00101 if ( !mxsgn || (pupper(iptr)-plower(iptr)) < eps )/* || nmult > m_ssz * m_esz ) */ 00102 { 00103 if ( reductions.size() == 0 || reductions.back().upper() != plower(iptr) ) 00104 reductions.push_back(interval_t(plower(iptr),pupper(iptr))); 00105 else 00106 reductions.back().define(reductions.back().lower(),pupper( iptr )); 00107 iptr = pdec( iptr ); itk --; 00108 continue; 00109 }; 00110 00111 /* incrémentation de la pile */ 00112 inext = pinc(iptr); 00113 00114 // sz_t nbcstl = 0; 00115 /* subdivision des projections basses */ 00116 { 00117 numerics::rounding<creal_t> rnd( numerics::rnd_dw() ); 00118 for ( i = 0; i < 4*this->nbp(); i += 4 ) 00119 if ( pmsz(iptr+i) ) 00120 { 00121 nmult += pmsz(iptr+i)*(pmsz(iptr+i)-1); 00122 brnops::decasteljau(pmdata(iptr+i),pmdata(inext+i),pmsz(iptr+i)); 00123 // nbcstl++; 00124 }; 00125 }; 00126 00127 /* subdivision des projections hautes */ 00128 { 00129 numerics::rounding<creal_t> rnd( numerics::rnd_up() ); 00130 for ( i = 0; i < 4*this->nbp(); i += 4 ) 00131 if ( pMsz(iptr+i) ) 00132 { 00133 nmult += pMsz(iptr+i)*(pMsz(iptr+i)-1); 00134 brnops::decasteljau(pMdata(iptr+i),pMdata(inext+i),pMsz(iptr+i) ); 00135 // nbcstl++; 00136 }; 00137 }; 00138 00139 /* if ( nbcstl == 0 ) 00140 { 00141 print(iptr); 00142 }; */ 00143 00144 // assert(nbcstl); 00145 plower(inext) = plower(iptr); 00146 pupper(inext) = (plower(iptr)+pupper(iptr))/2; 00147 plower(iptr) = pupper(inext); 00148 iptr = inext; 00149 itk ++; 00150 }; 00151 00152 return reductions.size() != 0; 00153 assert(k>0); 00154 } 00155 00156 }; 00157 } 00158 } 00159 //-------------------------------------------------------------------- 00160 } //namespace mmx 00161 /********************************************************************/ 00162 #endif //