realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/system_method.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: method.hpp,v 1.1 2005/07/11 10:03:55 jppavone Exp $
00005  ********************************************************************/
00006 #ifndef realroot_SOLVE_SBDSLV_METHOD_HPP
00007 #define realroot_SOLVE_SBDSLV_METHOD_HPP
00008 // JW - the following file is not under svn control ...
00009 //#include "../realroot2/system.H"
00010 #include <realroot/system_system.h>
00011 #include <realroot/strgy_simple.h>
00012 #include <realroot/strgy_newton.h>
00013 #include <realroot/strgy_cvmatrix.h>
00014 #include <realroot/strgy_rdslv_parallel.hpp>
00015 #include <realroot/strgy_sbdrl_parametric.hpp>
00016 //--------------------------------------------------------------------
00017 namespace mmx {
00018 //--------------------------------------------------------------------
00019 //#include "debug_stream.hpp"
00020 
00021 namespace realroot
00022 {
00023   
00024   /* erreur detectées par le system provoquées par un les parametres */
00025   const int E_CTRL   = 0;
00026   const int E_STRGY  = 1;
00027   const int E_RDSLV  = 2;
00028   const int E_SBDRL  = 3;
00029   const int E_INIT   = 4;
00030   
00031   /* ordre recu par le systeme depuis l'un des parametres */
00032   const int C_ACCEPT = 5;
00033   
00034   /* reponses possibles de la méthode de réduction */
00035   
00036   const int R_REJECT = 6;
00037 
00038   const int R_ISOK   = 7;
00039   const int R_WEAK   = 8;
00040   const int R_FAIL   = 9;
00041   const int R_ERROR  = 10;
00042   const int D_REJECT = 11;
00043   
00044   struct method_debug /* retour d'erreurs */
00045   { 
00046       virtual     ~method_debug(void)       {}
00047       virtual void output(const char * msg) {
00048           std::cerr << msg << std::endl;
00049           exit(1);
00050       }
00051   } ;
00052 
00053   /* méthode paramétree par strate'gie, solveur de réduction et règle de subdivision */
00054   template< class system, 
00055             class _strgy_ = strgy::newton<system> ,
00056             template<class> class _rdslv_ = rdslv::parallel, 
00057             template<class> class _sbdrl_ = sbdrl::parametric >
00058   struct method : method_base 
00059   {
00060     typedef typename system::creal_t    creal_t;
00061     typedef typename system::interval_t interval_t;
00062     typedef typename system::sz_t       sz_t;
00063     method_debug * m_dbg;
00064     method_debug   m_dbgdefault; 
00065     /* paramètres de la methode */
00066     _strgy_         m_strgy;
00067     _rdslv_<system> m_rdslv;
00068     _sbdrl_<system> m_sbdrl;
00069     
00070     int m_state;
00071     
00072     void accept()
00073     {
00074       /* le system a recu l'ordre d'une des methodes d'accepter le domaine */
00075       m_state = C_ACCEPT;
00076     };
00077     
00078     void error( const char * sysmsg )
00079     {
00080       char msg[ 200 ];
00081       switch( m_state )
00082         {
00083         case E_CTRL:
00084           sprintf(msg,"domain control:\n\t%s\n",sysmsg);
00085           break;
00086         case E_STRGY:
00087           sprintf(msg,"strategy:\n\t%s\n",sysmsg);
00088           break;
00089         case E_RDSLV:
00090           sprintf(msg,"reduction(solveur):\n\t%s\n",sysmsg);
00091           break;
00092         case E_SBDRL:
00093           sprintf(msg,"subdivision:\n\t%s\n",sysmsg);
00094           break;
00095         case E_INIT:
00096           sprintf(msg,"initialisation:\n\t%s\n",sysmsg);
00097           break;
00098         case R_ERROR:
00099           sprintf(msg,"reduction:\n\t%s\n",sysmsg);
00100           break;
00101         case R_FAIL:
00102           sprintf(msg,"%s","reduction: projection stack is empty !\n");
00103           break;
00104         case D_REJECT:
00105           sprintf(msg,"%s","rejection: pb in pop()\n");
00106         };
00107       m_dbg->output( msg );
00108     };    
00109     
00110     void check_pstack( system * sys )
00111     {
00112       for ( sz_t v = 0; v < sys->nvr(); v ++ )
00113         {
00114           //      std::cout << "projection : " << v << std::endl;
00115         };
00116     };
00117     /* la méthode de réduction consiste à appliquer le solveur de réduction sur   */
00118     /* toutes les projections disponibles, et à mettre à jour la pile de domaines */
00119     /* paramètres: le systeme utilisé et le taux de réduction esperé              */
00120     /* retourne:                                                                  */
00121     /*          R_ISOK   en cas de succès                                         */
00122     /*          R_WEAK   en cas de réduction trop faible (i.e. < ratio)           */
00123     /*          R_FAIL   si la pile de projections est vide.                      */
00124     /*          R_REJECT si le solveur de réduction rejette le domaine            */
00125     
00126     int reduction( system * sys )
00127     {
00128       std::vector<interval_t> ri[ sys->nvr() ];
00129       m_state = R_FAIL;
00130       for ( sz_t v = 0; v < sys->nvr(); v ++ )
00131         {
00132           if ( sys->projections(v).nbp()  ==  0 ) continue;
00133           m_state = E_RDSLV;
00134           creal_t prc = sys->current()[v].size();
00135           creal_t eps = std::min(std::max(sys->peps()/(10*prc),(creal_t)1e-4),(creal_t)1e-2);
00136           if ( ! m_rdslv.process(ri[v],sys->projections(v),eps) ) return R_REJECT;
00137         };      
00138       
00139       if ( m_state == R_FAIL ) { 
00140         return R_FAIL;
00141       };
00142       /* on propose les réductions au système, c'est à lui de disposer */
00143       return  sys->reduce(ri,sys->nvr())?R_ISOK:R_WEAK;
00144     };
00145     
00146     void//int 
00147     subdivision( system * sys )
00148     {
00149       m_state = E_SBDRL;
00150       m_sbdrl.process( sys );
00151     };
00152     
00153     int m_niter;
00154     int m_nsbd ; 
00155     int m_seq;
00156 
00157     /* allumage de l'usine à gaz */
00158     template<class Prm, class Bounds> 
00159     void launch( system * sys, Prm& prm, 
00160                  Bounds * inits,//creal_t  * inits,
00161                  method_debug * dbg = 0  )
00162     {
00163       m_seq   = 0;
00164       m_niter = 0;
00165       m_nsbd  = 0;
00166       /* si la stream de debug n'est pas fourni on utilise celle donnée par défaut */
00167       m_dbg = (dbg)?dbg:&m_dbgdefault;
00168       unsigned answ;
00169       sys->receiver(this);       /* la methode ecoute les messages du systeme */
00170       m_state = E_INIT;
00171       sys->init( inits );  /* initialisation du domaine de recherche    */
00172       /* tant que la pile de domaines n'est pas vide */
00173       while ( sys->current() ) /* tant que la pile de domaines n'est pas vide */
00174         {
00175           // 12
00176           //      if ( m_niter == 12 ) std::cout << "POPO\n";
00177           m_niter++;
00178           m_seq ++;
00179           sys->reset();
00180           /* on passe le domaine à la classe de contrôle */
00181           m_state = E_CTRL;
00182           //      vctops::print(sys->current(),sys->nvr());
00183           answ = prm.check(sys->current(),sys->nvr());
00184           /* si elle retourne false on rejette le domaine */
00185           m_state = D_REJECT; if ( !answ ) { sys->pop(); continue; };
00186           /* on applique la strategie qui consiste à remplir la pile de projection */
00187           m_state = E_STRGY, answ = m_strgy.process(sys);
00188           /* pour une raison inconnue la strategie veut que l'on accepte le domaine*/
00189           if ( m_state == C_ACCEPT ) { 
00190             //      std::cout << " ACCEPT = STRGY\n";
00191             prm.output(sys->current(),sys->nvr()); sys->pop();  continue; };
00192           /* la strategie peut rejeter le domaine                                  */
00193           m_state = D_REJECT; if ( !answ ) { sys->pop(); continue; };
00194           /* phase de réduction du domaine par l'utilisation de la pile de projection          */
00195 
00196           if ( sys->thickness()  ) { 
00197             //      std::cout << "ACCEPT = THICK \n";
00198             prm.output(sys->current(),sys->nvr()); sys->pop();  continue; };
00199 
00200           switch(reduction(sys))
00201             {
00202             case R_REJECT:  /* le domaine est à rejeter */
00203               m_state = R_REJECT;
00204               sys->pop(); 
00205               continue;
00206             case R_ISOK:      /* le domaine est réduit    */
00207               m_state = R_ISOK;
00208               break;
00209             case R_WEAK:   /* la réduction n'est pas acceptée */
00210               break;
00211             case R_FAIL:   /* échec de la réduction    */
00212               m_state = R_FAIL;
00213               error("");
00214               break;
00215             };
00216           
00217           if ( m_state == R_ISOK ) { sys->dreset(); };
00218           
00219           if ( sys->prc() < sys->peps() )
00220             {
00221               //              std::cout << " ACCEPT = PREC\n";
00222               prm.output(sys->current(),sys->nvr());
00223               sys->pop();
00224             }
00225           else
00226             {
00227               if ( m_state != R_ISOK )
00228                 {
00229                   m_seq = 0;
00230                   m_nsbd ++;
00231                   m_state = E_SBDRL;
00232                   if ( !m_sbdrl.process(sys) ) { 
00233                     //          std::cout << " ACCEPT = SBD\n";
00234                     prm.output(sys->current(),sys->nvr()); sys->pop(); 
00235                   };
00236                 };
00237             };
00238         };
00239 
00240     };
00241   };
00242 };
00243 //--------------------------------------------------------------------
00244 } //namespace mmx
00245 /********************************************************************/
00246 #endif //