00001
00002
00003
00004
00005
00006 #ifndef realroot_SOLVE_SBDSLV_METHOD_HPP
00007 #define realroot_SOLVE_SBDSLV_METHOD_HPP
00008
00009
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
00020
00021 namespace realroot
00022 {
00023
00024
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
00032 const int C_ACCEPT = 5;
00033
00034
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
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
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
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
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
00115 };
00116 };
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 int reduction( system * sys )
00127 {
00128 int nvrTemp = sys->nvr();
00129
00130
00131
00132 std::vector<interval_t> *ri = new std::vector<interval_t>[nvrTemp];
00133
00134 m_state = R_FAIL;
00135 for ( sz_t v = 0; v < sys->nvr(); v ++ )
00136 {
00137 if ( sys->projections(v).nbp() == 0 ) continue;
00138 m_state = E_RDSLV;
00139 creal_t prc = sys->current()[v].size();
00140 creal_t eps = std::min(std::max(sys->peps()/(10*prc),(creal_t)1e-4),(creal_t)1e-2);
00141 if ( ! m_rdslv.process(ri[v],sys->projections(v),eps) ) return R_REJECT;
00142 };
00143
00144 if ( m_state == R_FAIL ) {
00145 delete ri;
00146 return R_FAIL;
00147 };
00148
00149 int r = sys->reduce(ri,sys->nvr())?R_ISOK:R_WEAK;
00150
00151 delete ri;
00152
00153 return r;
00154 };
00155
00156 void
00157 subdivision( system * sys )
00158 {
00159 m_state = E_SBDRL;
00160 m_sbdrl.process( sys );
00161 };
00162
00163 int m_niter;
00164 int m_nsbd ;
00165 int m_seq;
00166
00167
00168 template<class Prm, class Bounds>
00169 void launch( system * sys, Prm& prm,
00170 Bounds * inits,
00171 method_debug * dbg = 0 )
00172 {
00173 m_seq = 0;
00174 m_niter = 0;
00175 m_nsbd = 0;
00176
00177 m_dbg = (dbg)?dbg:&m_dbgdefault;
00178 unsigned answ;
00179 sys->receiver(this);
00180 m_state = E_INIT;
00181 sys->init( inits );
00182
00183 while ( sys->current() )
00184 {
00185
00186
00187 m_niter++;
00188 m_seq ++;
00189 sys->reset();
00190
00191 m_state = E_CTRL;
00192
00193 answ = prm.check(sys->current(),sys->nvr());
00194
00195 m_state = D_REJECT; if ( !answ ) { sys->pop(); continue; };
00196
00197 m_state = E_STRGY, answ = m_strgy.process(sys);
00198
00199 if ( m_state == C_ACCEPT ) {
00200
00201 prm.output(sys->current(),sys->nvr()); sys->pop(); continue; };
00202
00203 m_state = D_REJECT; if ( !answ ) { sys->pop(); continue; };
00204
00205
00206 if ( sys->thickness() ) {
00207
00208 prm.output(sys->current(),sys->nvr()); sys->pop(); continue; };
00209
00210 switch(reduction(sys))
00211 {
00212 case R_REJECT:
00213 m_state = R_REJECT;
00214 sys->pop();
00215 continue;
00216 case R_ISOK:
00217 m_state = R_ISOK;
00218 break;
00219 case R_WEAK:
00220 break;
00221 case R_FAIL:
00222 m_state = R_FAIL;
00223 error("");
00224 break;
00225 };
00226
00227 if ( m_state == R_ISOK ) { sys->dreset(); };
00228
00229 if ( sys->prc() < sys->peps() )
00230 {
00231
00232 prm.output(sys->current(),sys->nvr());
00233 sys->pop();
00234 }
00235 else
00236 {
00237 if ( m_state != R_ISOK )
00238 {
00239 m_seq = 0;
00240 m_nsbd ++;
00241 m_state = E_SBDRL;
00242 if ( !m_sbdrl.process(sys) ) {
00243
00244 prm.output(sys->current(),sys->nvr()); sys->pop();
00245 };
00246 };
00247 };
00248 };
00249
00250 };
00251 };
00252 };
00253
00254 }
00255
00256 #endif //