00001
00013 #ifndef EF_H
00014 #define EF_H
00015
00016 #include <itpp/itbase.h>
00017 #include "../math/libDC.h"
00018 #include "libBM.h"
00019 #include "../itpp_ext.h"
00020
00021
00022 using namespace itpp;
00023
00024
00026 extern Uniform_RNG UniRNG;
00028 extern Normal_RNG NorRNG;
00030 extern Gamma_RNG GamRNG;
00031
00038 class eEF : public epdf {
00039 public:
00040
00042 eEF ( const RV &rv ) :epdf ( rv ) {};
00044 virtual double lognc() const =0;
00046 virtual void dupdate ( mat &v ) {it_error ( "Not implemneted" );};
00048 virtual double evalpdflog_nn ( const vec &val ) const{it_error ( "Not implemneted" );return 0.0;};
00050 virtual double evalpdflog ( const vec &val ) const {return evalpdflog_nn ( val )-lognc();}
00052 virtual vec evalpdflog ( const mat &Val ) const {
00053 vec x ( Val.cols() );
00054 for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evalpdflog_nn ( Val.get_col ( i ) ) ;}
00055 return x-lognc();
00056 }
00058 virtual void pow ( double p ) {it_error ( "Not implemented" );};
00059 };
00060
00067 class mEF : public mpdf {
00068
00069 public:
00071 mEF ( const RV &rv0, const RV &rvc0 ) :mpdf ( rv0,rvc0 ) {};
00072 };
00073
00075 class BMEF : public BM {
00076 protected:
00078 double frg;
00080 double last_lognc;
00081 public:
00083 BMEF ( const RV &rv, double frg0=1.0 ) :BM ( rv ), frg ( frg0 ) {}
00085 BMEF ( const BMEF &B ) :BM ( B ), frg ( B.frg ), last_lognc ( B.last_lognc ) {}
00087 virtual void set_statistics ( const BMEF* BM0 ) {it_error ( "Not implemented" );};
00089 virtual void bayes ( const vec &data, const double w ) {};
00090
00091 void bayes ( const vec &dt );
00093 virtual void flatten ( BMEF * B ) {it_error ( "Not implemented" );}
00094 };
00095
00101 template<class sq_T>
00102 class enorm : public eEF {
00103 protected:
00105 vec mu;
00107 sq_T R;
00109 int dim;
00110 public:
00112 enorm ( RV &rv );
00114 void set_parameters ( const vec &mu,const sq_T &R );
00116 void tupdate ( double phi, mat &vbar, double nubar );
00118 void dupdate ( mat &v,double nu=1.0 );
00119
00120 vec sample() const;
00122 mat sample ( int N ) const;
00123 double eval ( const vec &val ) const ;
00124 double evalpdflog_nn ( const vec &val ) const;
00125 double lognc () const;
00126 vec mean() const {return mu;}
00127
00128
00130 vec& _mu() {return mu;}
00131
00133 void set_mu ( const vec mu0 ) { mu=mu0;}
00134
00136 sq_T& _R() {return R;}
00137
00139
00140 };
00141
00148 class egiw : public eEF {
00149 protected:
00151 ldmat V;
00153 double nu;
00155 int xdim;
00157 int nPsi;
00158 public:
00160 egiw ( RV rv, mat V0, double nu0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) {
00161 xdim = rv.count() /V.rows();
00162 it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." );
00163 nPsi = V.rows()-xdim;
00164 }
00166 egiw ( RV rv, ldmat V0, double nu0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) {
00167 xdim = rv.count() /V.rows();
00168 it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." );
00169 nPsi = V.rows()-xdim;
00170 }
00171
00172 vec sample() const;
00173 vec mean() const;
00174 void mean_mat ( mat &M, mat&R ) const;
00176 double evalpdflog_nn ( const vec &val ) const;
00177 double lognc () const;
00178
00179
00181 ldmat& _V() {return V;}
00183 double& _nu() {return nu;}
00184 void pow ( double p );
00185 };
00186
00195 class eDirich: public eEF {
00196 protected:
00198 vec beta;
00199 public:
00201 eDirich ( const RV &rv, const vec &beta0 ) : eEF ( rv ),beta ( beta0 ) {it_assert_debug ( rv.count() ==beta.length(),"Incompatible statistics" ); };
00203 eDirich ( const eDirich &D0 ) : eEF ( D0.rv ),beta ( D0.beta ) {};
00204 vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
00205 vec mean() const {return beta/sum ( beta );};
00207 double evalpdflog_nn ( const vec &val ) const {return ( beta-1 ) *log ( val );};
00208 double lognc () const {
00209 double gam=sum ( beta );
00210 double lgb=0.0;
00211 for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
00212 return lgb-lgamma ( gam );
00213 };
00215 vec& _beta() {return beta;}
00217 void set_parameters(const vec &beta0){
00218 if(beta0.length()!=beta.length()){
00219 it_assert_debug(rv.length()==1,"Undefined");
00220 rv.set_size(0,beta0.length());
00221 }
00222 beta= beta0;
00223 }
00224 };
00225
00227 class multiBM : public BMEF {
00228 protected:
00230 eDirich est;
00231 vec β
00232 public:
00234 multiBM ( const RV &rv, const vec beta0 ) : BMEF ( rv ),est ( rv,beta0 ),beta ( est._beta() ) {last_lognc=est.lognc();}
00236 multiBM ( const multiBM &B ) : BMEF ( B ),est ( rv,B.beta ),beta ( est._beta() ) {}
00237
00238 void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;}
00239 void bayes ( const vec &dt ) {
00240 if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();}
00241 beta+=dt;
00242 if ( evalll ) {ll=est.lognc()-last_lognc;}
00243 }
00244 double logpred ( const vec &dt ) const {
00245 eDirich pred ( est );
00246 vec &beta = pred._beta();
00247
00248 double lll;
00249 if ( frg<1.0 )
00250 {beta*=frg;lll=pred.lognc();}
00251 else
00252 if ( evalll ) {lll=last_lognc;}
00253 else{lll=pred.lognc();}
00254
00255 beta+=dt;
00256 return pred.lognc()-lll;
00257 }
00258 void flatten ( BMEF* B ) {
00259 eDirich* E=dynamic_cast<eDirich*> ( B );
00260
00261 const vec &Eb=E->_beta();
00262 est.pow ( sum ( beta ) /sum ( Eb ) );
00263 if ( evalll ) {last_lognc=est.lognc();}
00264 }
00265 const epdf& _epdf() const {return est;};
00266 void set_parameters ( const vec &beta0 ) {
00267 est.set_parameters(beta0);
00268 rv = est._rv();
00269 if(evalll){last_lognc=est.lognc();}
00270 }
00271 };
00272
00282 class egamma : public eEF {
00283 protected:
00285 vec alpha;
00287 vec beta;
00288 public :
00290 egamma ( const RV &rv ) :eEF ( rv ) {};
00292 void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;};
00293 vec sample() const;
00295
00296 double evalpdflog ( const vec &val ) const;
00297 double lognc () const;
00299 void _param ( vec* &a, vec* &b ) {a=αb=β};
00300 vec mean() const {vec pom ( alpha ); pom/=beta; return pom;}
00301 };
00302
00304
00305
00306
00307
00308
00309
00311
00312
00313
00314
00315
00316
00317
00319
00320 class euni: public epdf {
00321 protected:
00323 vec low;
00325 vec high;
00327 vec distance;
00329 double nk;
00331 double lnk;
00332 public:
00334 euni ( const RV rv ) :epdf ( rv ) {}
00335 double eval ( const vec &val ) const {return nk;}
00336 double evalpdflog ( const vec &val ) const {return lnk;}
00337 vec sample() const {
00338 vec smp ( rv.count() );
00339 #pragma omp critical
00340 UniRNG.sample_vector ( rv.count(),smp );
00341 return low+elem_mult ( distance,smp );
00342 }
00344 void set_parameters ( const vec &low0, const vec &high0 ) {
00345 distance = high0-low0;
00346 it_assert_debug ( min ( distance ) >0.0,"bad support" );
00347 low = low0;
00348 high = high0;
00349 nk = prod ( 1.0/distance );
00350 lnk = log ( nk );
00351 }
00352 vec mean() const {vec pom=high; pom-=low; pom/=2.0; return pom;}
00353 };
00354
00355
00361 template<class sq_T>
00362 class mlnorm : public mEF {
00364 enorm<sq_T> epdf;
00365 mat A;
00366 vec& _mu;
00367 public:
00369 mlnorm ( RV &rv,RV &rvc );
00371 void set_parameters ( const mat &A, const sq_T &R );
00373 vec samplecond ( vec &cond, double &lik );
00375 mat samplecond ( vec &cond, vec &lik, int n );
00377 void condition ( vec &cond );
00378 };
00379
00389 class mgamma : public mEF {
00390 protected:
00392 egamma epdf;
00394 double k;
00396 vec* _beta;
00397
00398 public:
00400 mgamma ( const RV &rv,const RV &rvc );
00402 void set_parameters ( double k );
00403 void condition ( const vec &val ) {*_beta=k/val;};
00404 };
00405
00417 class mgamma_fix : public mgamma {
00418 protected:
00420 double l;
00422 vec refl;
00423 public:
00425 mgamma_fix ( const RV &rv,const RV &rvc ) : mgamma ( rv,rvc ),refl ( rv.count() ) {};
00427 void set_parameters ( double k0 , vec ref0, double l0 ) {
00428 mgamma::set_parameters ( k0 );
00429 refl=pow ( ref0,1.0-l0 );l=l0;
00430 };
00431
00432 void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); *_beta=k/mean;};
00433 };
00434
00436 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
00442 class eEmp: public epdf {
00443 protected :
00445 int n;
00447 vec w;
00449 Array<vec> samples;
00450 public:
00452 eEmp ( const RV &rv0 ,int n0 ) :epdf ( rv0 ),n ( n0 ),w ( n ),samples ( n ) {};
00454 void set_parameters ( const vec &w0, const epdf* pdf0 );
00456 void set_samples ( const epdf* pdf0 );
00458 vec& _w() {return w;};
00460 Array<vec>& _samples() {return samples;};
00462 ivec resample ( RESAMPLING_METHOD method = SYSTEMATIC );
00464 vec sample() const {it_error ( "Not implemented" );return 0;}
00466 double evalpdflog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
00467 vec mean() const {
00468 vec pom=zeros ( rv.count() );
00469 for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
00470 return pom;
00471 }
00472 };
00473
00474
00476
00477 template<class sq_T>
00478 enorm<sq_T>::enorm ( RV &rv ) :eEF ( rv ), mu ( rv.count() ),R ( rv.count() ),dim ( rv.count() ) {};
00479
00480 template<class sq_T>
00481 void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 ) {
00482
00483 mu = mu0;
00484 R = R0;
00485 };
00486
00487 template<class sq_T>
00488 void enorm<sq_T>::dupdate ( mat &v, double nu ) {
00489
00490 };
00491
00492 template<class sq_T>
00493 void enorm<sq_T>::tupdate ( double phi, mat &vbar, double nubar ) {
00494
00495 };
00496
00497 template<class sq_T>
00498 vec enorm<sq_T>::sample() const {
00499 vec x ( dim );
00500 NorRNG.sample_vector ( dim,x );
00501 vec smp = R.sqrt_mult ( x );
00502
00503 smp += mu;
00504 return smp;
00505 };
00506
00507 template<class sq_T>
00508 mat enorm<sq_T>::sample ( int N ) const {
00509 mat X ( dim,N );
00510 vec x ( dim );
00511 vec pom;
00512 int i;
00513
00514 for ( i=0;i<N;i++ ) {
00515 NorRNG.sample_vector ( dim,x );
00516 pom = R.sqrt_mult ( x );
00517 pom +=mu;
00518 X.set_col ( i, pom );
00519 }
00520
00521 return X;
00522 };
00523
00524 template<class sq_T>
00525 double enorm<sq_T>::eval ( const vec &val ) const {
00526 double pdfl,e;
00527 pdfl = evalpdflog ( val );
00528 e = exp ( pdfl );
00529 return e;
00530 };
00531
00532 template<class sq_T>
00533 double enorm<sq_T>::evalpdflog_nn ( const vec &val ) const {
00534
00535 return -0.5* (R.invqform ( mu-val ) );
00536 };
00537
00538 template<class sq_T>
00539 inline double enorm<sq_T>::lognc () const {
00540
00541 return 0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
00542 };
00543
00544 template<class sq_T>
00545 mlnorm<sq_T>::mlnorm ( RV &rv0,RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu ( epdf._mu() ) {
00546 ep =&epdf;
00547 }
00548
00549 template<class sq_T>
00550 void mlnorm<sq_T>::set_parameters ( const mat &A0, const sq_T &R0 ) {
00551 epdf.set_parameters ( zeros ( rv.count() ),R0 );
00552 A = A0;
00553 }
00554
00555 template<class sq_T>
00556 vec mlnorm<sq_T>::samplecond ( vec &cond, double &lik ) {
00557 this->condition ( cond );
00558 vec smp = epdf.sample();
00559 lik = epdf.eval ( smp );
00560 return smp;
00561 }
00562
00563 template<class sq_T>
00564 mat mlnorm<sq_T>::samplecond ( vec &cond, vec &lik, int n ) {
00565 int i;
00566 int dim = rv.count();
00567 mat Smp ( dim,n );
00568 vec smp ( dim );
00569 this->condition ( cond );
00570
00571 for ( i=0; i<n; i++ ) {
00572 smp = epdf.sample();
00573 lik ( i ) = epdf.eval ( smp );
00574 Smp.set_col ( i ,smp );
00575 }
00576
00577 return Smp;
00578 }
00579
00580 template<class sq_T>
00581 void mlnorm<sq_T>::condition ( vec &cond ) {
00582 _mu = A*cond;
00583
00584 }
00585
00587
00588
00589 #endif //EF_H