00001 
00013 #ifndef PARTICLES_H
00014 #define PARTICLES_H
00015 
00016 
00017 #include "../stat/exp_family.h"
00018 
00019 namespace bdm {
00020 
00027 class PF : public BM {
00028 protected:
00030         int n;
00032         eEmp est;
00034         vec &_w;
00036         Array<vec> &_samples;
00038         shared_ptr<mpdf> par;
00040         shared_ptr<mpdf> obs;
00042         vec lls;
00043         
00045         RESAMPLING_METHOD resmethod;
00048         double res_threshold;
00049         
00052 
00054         bool opt_L_smp;
00056         bool opt_L_wei;
00058 
00059 public:
00062         PF ( ) : est(), _w ( est._w() ), _samples ( est._samples() ), opt_L_smp ( false ), opt_L_wei ( false ) {
00063                 LIDs.set_size ( 5 );
00064         };
00065         
00066         void set_parameters (int n0, double res_th0=0.5, RESAMPLING_METHOD rm = SYSTEMATIC ) {
00067                 n = n0;
00068                 res_threshold = res_th0;
00069                 resmethod = rm;
00070         };
00071         void set_model ( shared_ptr<mpdf> par0, shared_ptr<mpdf> obs0) {
00072                 par = par0;
00073                 obs = obs0;
00074                 
00075                 est.set_rv(par->_rv());
00076         };
00077         void set_statistics ( const vec w0, const epdf &epdf0 ) {
00078                 est.set_statistics ( w0, epdf0 );
00079         };
00080         void set_statistics ( const eEmp &epdf0 ) {
00081                 bdm_assert_debug(epdf0._rv().equal(par->_rv()),"Incompatibel input");
00082                 est=epdf0;
00083         };
00089         void set_options ( const string &opt ) {
00090                 BM::set_options ( opt );
00091                 opt_L_wei = ( opt.find ( "logweights" ) != string::npos );
00092                 opt_L_smp = ( opt.find ( "logsamples" ) != string::npos );
00093         }
00095         virtual void bayes_gensmp();
00097         virtual void bayes_weights();
00099         virtual bool do_resampling(){   
00100                 double eff = 1.0 / ( _w * _w );
00101                 return eff < ( res_threshold*n );
00102         }
00103         void bayes ( const vec &dt );
00105         vec& __w() { return _w; }
00107         vec& _lls() { return lls; }
00108         RESAMPLING_METHOD _resmethod() const { return resmethod; }
00110         const eEmp& posterior() const {return est;}
00111         
00124         void from_setting(const Setting &set){
00125                 par = UI::build<mpdf>(set,"parameter_pdf",UI::compulsory);
00126                 obs = UI::build<mpdf>(set,"observation_pdf",UI::compulsory);
00127                 
00128                 prior_from_set(set);
00129                 resmethod_from_set(set);
00130                 
00131                 
00132                 
00133                 RV u = par->_rvc().remove_time().subt( par->_rv() ); 
00134                 
00135                 RV obs_u = obs->_rvc().remove_time().subt( par->_rv() ); 
00136                 
00137                 u.add(obs_u); 
00138                 
00139                 set_drv(concat(obs->_rv(),u) );
00140         }
00142         void resmethod_from_set(const Setting &set){
00143                 string resmeth;
00144                 if (UI::get(resmeth,set,"resmethod",UI::optional)){
00145                         if (resmeth=="systematic") {
00146                                 resmethod= SYSTEMATIC;
00147                         } else  {
00148                                 if (resmeth=="multinomial"){
00149                                         resmethod=MULTINOMIAL;
00150                                 } else {
00151                                         if (resmeth=="stratified"){
00152                                                 resmethod= STRATIFIED;
00153                                         } else {
00154                                                 bdm_error("Unknown resampling method");
00155                                         }
00156                                 }
00157                         }
00158                 } else {
00159                         resmethod=SYSTEMATIC;
00160                 };
00161                 if(!UI::get(res_threshold, set, "res_threshold", UI::optional)){
00162                         res_threshold=0.5;
00163                 }
00164         }
00166         void prior_from_set(const Setting & set){
00167                 shared_ptr<epdf> pri = UI::build<epdf>(set,"prior",UI::compulsory);
00168                 
00169                 eEmp *test_emp=dynamic_cast<eEmp*>(&(*pri));
00170                 if (test_emp) { 
00171                         est=*test_emp;
00172                 } else {
00173                         int n;
00174                         if (!UI::get(n,set,"n",UI::optional)){n=10;}
00175                         
00176                         set_statistics(ones(n)/n, *pri);
00177                 }
00178                 
00179         }
00180         
00181         void validate(){
00182                 n=_w.length();
00183                 lls=zeros(n);
00184                 if (par->_rv()._dsize()>0) {
00185                         bdm_assert(par->_rv()._dsize()==est.dimension(),"Mismatch of RV and dimension of posterior" );
00186                 }
00187         }
00189         void resample(ivec &ind){
00190                 est.resample(ind,resmethod);
00191         }
00192         Array<vec>& __samples(){return _samples;}
00193 };
00194 UIREGISTER(PF);
00195 
00203 class MPF : public BM  {
00204         protected:
00205         shared_ptr<PF> pf;
00206         Array<BM*> BMs;
00207 
00209 
00210         class mpfepdf : public epdf  {
00211                 shared_ptr<PF> &pf;
00212                 Array<BM*> &BMs;
00213         public:
00214                 mpfepdf (shared_ptr<PF> &pf0, Array<BM*> &BMs0): epdf(), pf(pf0), BMs(BMs0) { };
00216                 void read_parameters(){
00217                         rv = concat(pf->posterior()._rv(), BMs(0)->posterior()._rv());
00218                         dim = pf->posterior().dimension() + BMs(0)->posterior().dimension();
00219                         bdm_assert_debug(dim == rv._dsize(), "Wrong name ");
00220                 }
00221                 vec mean() const {
00222                         const vec &w = pf->posterior()._w();
00223                         vec pom = zeros ( BMs(0)->posterior ().dimension() );
00224                         
00225                         for ( int i = 0; i < w.length(); i++ ) {
00226                                 pom += BMs ( i )->posterior().mean() * w ( i );
00227                         }
00228                         return concat ( pf->posterior().mean(), pom );
00229                 }
00230                 vec variance() const {
00231                         const vec &w = pf->posterior()._w();
00232                         
00233                         vec pom = zeros ( BMs(0)->posterior ().dimension() );
00234                         vec pom2 = zeros ( BMs(0)->posterior ().dimension() );
00235                         vec mea;
00236                         
00237                         for ( int i = 0; i < w.length(); i++ ) {
00238                                 
00239                                 mea = BMs ( i )->posterior().mean();
00240                                 pom += mea * w ( i );
00241                                 
00242                                 pom2 += ( BMs ( i )->posterior().variance() + pow ( mea, 2 ) ) * w ( i );
00243                         }
00244                         return concat ( pf->posterior().variance(), pom2 - pow ( pom, 2 ) );
00245                 }
00246                 
00247                 void qbounds ( vec &lb, vec &ub, double perc = 0.95 ) const {
00248                         
00249                         vec lbp;
00250                         vec ubp;
00251                         pf->posterior().qbounds ( lbp, ubp );
00252 
00253                         
00254                         int dimC = BMs ( 0 )->posterior().dimension();
00255                         int j;
00256                         
00257                         vec lbc ( dimC );
00258                         vec ubc ( dimC );
00259                         
00260                         vec Lbc ( dimC );
00261                         vec Ubc ( dimC );
00262                         Lbc = std::numeric_limits<double>::infinity();
00263                         Ubc = -std::numeric_limits<double>::infinity();
00264 
00265                         for ( int i = 0; i < BMs.length(); i++ ) {
00266                                 
00267                                 BMs ( i )->posterior().qbounds ( lbc, ubc );
00268                                 
00269                                 for ( j = 0; j < dimC; j++ ) {
00270                                         if ( lbc ( j ) < Lbc ( j ) ) {
00271                                                 Lbc ( j ) = lbc ( j );
00272                                         }
00273                                         if ( ubc ( j ) > Ubc ( j ) ) {
00274                                                 Ubc ( j ) = ubc ( j );
00275                                         }
00276                                 }
00277                         }
00278                         lb = concat ( lbp, Lbc );
00279                         ub = concat ( ubp, Ubc );
00280                 }
00281 
00282                 vec sample() const {
00283                         bdm_error ( "Not implemented" );
00284                         return vec();
00285                 }
00286 
00287                 double evallog ( const vec &val ) const {
00288                         bdm_error ( "not implemented" );
00289                         return 0.0;
00290                 }
00291         };
00292 
00294         mpfepdf jest;
00295 
00297         bool opt_L_mea;
00298 
00299 public:
00301         MPF () :  jest (pf,BMs) {};
00302         void set_parameters ( shared_ptr<mpdf> par0, shared_ptr<mpdf> obs0, int n0, RESAMPLING_METHOD rm = SYSTEMATIC ) {
00303                 pf->set_model ( par0, obs0); 
00304                 pf->set_parameters(n0, rm );
00305                 BMs.set_length ( n0 );
00306         }
00307         void set_BM ( const BM &BMcond0 ) {
00308 
00309                 int n=pf->__w().length();
00310                 BMs.set_length(n);
00311                 
00312                 
00313                 for ( int i = 0; i < n; i++ ) {
00314                         BMs ( i ) = BMcond0._copy_();
00315                         BMs ( i )->condition ( pf->posterior()._sample ( i ) );
00316                 }
00317         };
00318 
00319         void bayes ( const vec &dt );
00320         const epdf& posterior() const {
00321                 return jest;
00322         }
00325         void set_options ( const string &opt ) {
00326                 BM::set_options(opt);
00327                 opt_L_mea = ( opt.find ( "logmeans" ) != string::npos );
00328         }
00329 
00331         const BM* _BM ( int i ) {
00332                 return BMs ( i );
00333         }
00334         
00346         void from_setting(const Setting &set){
00347                 shared_ptr<mpdf> par = UI::build<mpdf>(set,"parameter_pdf",UI::compulsory);
00348                 shared_ptr<mpdf> obs= new mpdf(); 
00349 
00350                 pf = new PF;
00351                 
00352                 pf->prior_from_set(set);
00353                 pf->resmethod_from_set(set);
00354                 pf->set_model(par,obs);
00355                 
00356                 shared_ptr<BM> BM0 =UI::build<BM>(set,"BM",UI::compulsory);
00357                 set_BM(*BM0);
00358                 
00359                 string opt;
00360                 if (UI::get(opt,set,"options",UI::optional)){
00361                         set_options(opt);
00362                 }
00363                 
00364                 
00365                 RV u = par->_rvc().remove_time().subt( par->_rv() );            
00366                 set_drv(concat(BM0->_drv(),u) );
00367                 validate();
00368         }
00369         void validate(){
00370                 try{
00371                 pf->validate();
00372                 } catch (std::exception &e){
00373                         throw UIException("Error in PF part of MPF:");
00374                 }
00375                 jest.read_parameters();
00376         }
00377         
00378 };
00379 UIREGISTER(MPF);
00380 
00381 }
00382 #endif // KF_H
00383 
00384