00001
00013 #ifndef PF_H
00014 #define PF_H
00015
00016
00017 #include "../stat/libEF.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 mpdf *par;
00040 mpdf *obs;
00041 public:
00044 PF ( ) :est(), _w ( est._w() ),_samples ( est._samples() ) {};
00045 PF( mpdf *par0, mpdf *obs0, epdf *epdf0, int n0 ) :
00046 est ( ),_w ( est._w() ),_samples ( est._samples() )
00047 { par = par0; obs=obs0; est.set_parameters ( ones(n0),epdf0 ); };
00048 void set_parameters ( mpdf *par0, mpdf *obs0, int n0 )
00049 { par = par0; obs=obs0; n=n0; };
00050 void set_statistics (const vec w0, epdf *epdf0){est.set_parameters ( w0,epdf0 );};
00053 void set_est ( const epdf &epdf0 );
00054 void bayes ( const vec &dt );
00056 vec* __w() {return &_w;}
00057 };
00058
00065 template<class BM_T>
00066
00067 class MPF : public PF {
00068 BM_T* Bms[10000];
00069
00071
00072 class mpfepdf : public epdf {
00073 protected:
00074 eEmp &E;
00075 vec &_w;
00076 Array<const epdf*> Coms;
00077 public:
00078 mpfepdf ( eEmp &E0) :
00079 epdf ( ), E ( E0 ), _w ( E._w() ),
00080 Coms ( _w.length() ) {
00081 };
00082
00083 void set_elements ( int &i, double wi, const epdf* ep )
00084 {_w ( i ) =wi; Coms ( i ) =ep;};
00085
00086 vec mean() const {
00087
00088 vec pom=zeros ( Coms(0)->dimension() );
00089 for ( int i=0; i<_w.length(); i++ ) {pom += Coms ( i )->mean() * _w ( i );}
00090 return concat ( E.mean(),pom );
00091 }
00092 vec variance() const {
00093
00094 vec pom=zeros ( Coms ( 0 )->dimension() );
00095 vec pom2=zeros ( Coms ( 0 )->dimension() );
00096 for ( int i=0; i<_w.length(); i++ ) {
00097 pom += Coms ( i )->mean() * _w ( i );
00098 pom2 += ( Coms ( i )->variance() + pow ( Coms ( i )->mean(),2 ) ) * _w ( i );
00099 }
00100 return concat ( E.variance(),pom2-pow ( pom,2 ) );
00101 }
00102
00103 vec sample() const {it_error ( "Not implemented" );return 0;}
00104
00105 double evallog ( const vec &val ) const {it_error ( "not implemented" ); return 0.0;}
00106 };
00107
00109 mpfepdf jest;
00110
00111 public:
00113 MPF ( mpdf *par0, mpdf *obs0, int n, const BM_T &BMcond0 ) : PF (), jest ( est ) {
00114 PF::set_parameters(par0,obs0,n);
00115
00116
00117
00118
00119
00120 if ( n>10000 ) {it_error ( "increase 10000 here!" );}
00121
00122 for ( int i=0;i<n;i++ ) {
00123 Bms[i] = new BM_T ( BMcond0 );
00124 const epdf& pom=Bms[i]->posterior();
00125 jest.set_elements ( i,1.0/n,&pom );
00126 }
00127 };
00128
00129 ~MPF() {
00130 }
00131
00132 void bayes ( const vec &dt );
00133 const epdf& posterior() const {return jest;}
00134 const epdf* _e() const {return &jest;}
00136 void set_est ( const epdf& epdf0 ) {
00137 PF::set_est ( epdf0 );
00138
00139
00140 for ( int i=0;i<n;i++ ) {Bms[i]->condition ( _samples ( i ) );}
00141 }
00142
00144 BM* _BM ( int i ) {return Bms[i];}
00145 };
00146
00147 template<class BM_T>
00148 void MPF<BM_T>::bayes ( const vec &dt ) {
00149 int i;
00150 vec lls ( n );
00151 vec llsP ( n );
00152 ivec ind;
00153 double mlls=-std::numeric_limits<double>::infinity();
00154
00155 #pragma omp parallel for
00156 for ( i=0;i<n;i++ ) {
00157
00158 _samples ( i ) = par->samplecond ( _samples ( i ) );
00159 llsP ( i ) = par->_e()->evallog ( _samples ( i ) );
00160 Bms[i]->condition ( _samples ( i ) );
00161 Bms[i]->bayes ( dt );
00162 lls ( i ) = Bms[i]->_ll();
00163 if ( lls ( i ) >mlls ) mlls=lls ( i );
00164 }
00165
00166 double sum_w=0.0;
00167
00168 #pragma omp parallel for
00169 for ( i=0;i<n;i++ ) {
00170 _w ( i ) *= exp ( lls ( i ) - mlls );
00171 sum_w+=_w ( i );
00172 }
00173
00174 if ( sum_w >0.0 ) {
00175 _w /=sum_w;
00176 }
00177 else {
00178 cout<<"sum(w)==0"<<endl;
00179 }
00180
00181
00182 double eff = 1.0/ ( _w*_w );
00183 if ( eff < ( 0.3*n ) ) {
00184 ind = est.resample();
00185
00186
00187 #pragma omp parallel for
00188 for ( i=0;i<n;i++ ) {
00189 if ( ind ( i ) !=i ) {
00190
00191
00192
00193
00194
00195 delete Bms[i];
00196 Bms[i] = new BM_T ( *Bms[ind ( i ) ] );
00197 const epdf& pom=Bms[i]->posterior();
00198 jest.set_elements ( i,1.0/n,&pom );
00199 }
00200 };
00201 cout << '.';
00202 }
00203 }
00204
00205 }
00206 #endif // KF_H
00207
00208