realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/strgy_rdslv_parallel.hpp
Go to the documentation of this file.
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 //