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 implemented" );};
00048 virtual double evallog_nn ( const vec &val ) const{it_error ( "Not implemented" );return 0.0;};
00050 virtual double evallog ( const vec &val ) const {double tmp;tmp= evallog_nn ( val )-lognc();it_assert_debug(std::isfinite(tmp),"Infinite value"); return tmp;}
00052 virtual vec evallog ( const mat &Val ) const {
00053 vec x ( Val.cols() );
00054 for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evallog_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 ( const BMEF * B ) {it_error ( "Not implemented" );}
00095
00096
00097 BMEF* _copy_ ( bool changerv=false ) {it_error ( "function _copy_ not implemented for this BM" ); return NULL;};
00098 };
00099
00100 template<class sq_T>
00101 class mlnorm;
00102
00108 template<class sq_T>
00109 class enorm : public eEF {
00110 protected:
00112 vec mu;
00114 sq_T R;
00116 int dim;
00117 public:
00119 enorm ( const RV &rv );
00121 void set_parameters ( const vec &mu,const sq_T &R );
00123
00125 void dupdate ( mat &v,double nu=1.0 );
00126
00127 vec sample() const;
00129 mat sample ( int N ) const;
00130
00131 double evallog_nn ( const vec &val ) const;
00132 double lognc () const;
00133 vec mean() const {return mu;}
00134
00135 mpdf* condition ( const RV &rvn ) const ;
00136
00137 epdf* marginal ( const RV &rv ) const;
00138
00140 vec& _mu() {return mu;}
00141
00143 void set_mu ( const vec mu0 ) { mu=mu0;}
00144
00146 sq_T& _R() {return R;}
00147 const sq_T& _R() const {return R;}
00148
00150
00151 };
00152
00159 class egiw : public eEF {
00160 protected:
00162 ldmat V;
00164 double nu;
00166 int xdim;
00168 int nPsi;
00169 public:
00171 egiw ( RV rv, mat V0, double nu0=-1.0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) {
00172 xdim = rv.count() /V.rows();
00173 it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." );
00174 nPsi = V.rows()-xdim;
00175
00176 if (nu0<0){
00177 nu = 0.1 +nPsi +2*xdim +2;
00178
00179 }
00180 }
00182 egiw ( RV rv, ldmat V0, double nu0=-1.0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) {
00183 xdim = rv.count() /V.rows();
00184 it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." );
00185 nPsi = V.rows()-xdim;
00186 if (nu0<0){
00187 nu = 0.1 +nPsi +2*xdim +2;
00188
00189 }
00190 }
00191
00192 vec sample() const;
00193 vec mean() const;
00194 void mean_mat ( mat &M, mat&R ) const;
00196 double evallog_nn ( const vec &val ) const;
00197 double lognc () const;
00198
00199
00201 ldmat& _V() {return V;}
00203 const ldmat& _V() const {return V;}
00205 double& _nu() {return nu;}
00206 const double& _nu() const {return nu;}
00207 void pow ( double p ) {V*=p;nu*=p;};
00208 };
00209
00218 class eDirich: public eEF {
00219 protected:
00221 vec beta;
00222 public:
00224 eDirich ( const RV &rv, const vec &beta0 ) : eEF ( rv ),beta ( beta0 ) {it_assert_debug ( rv.count() ==beta.length(),"Incompatible statistics" ); };
00226 eDirich ( const eDirich &D0 ) : eEF ( D0.rv ),beta ( D0.beta ) {};
00227 vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
00228 vec mean() const {return beta/sum ( beta );};
00230 double evallog_nn ( const vec &val ) const {double tmp; tmp=( beta-1 ) *log ( val ); it_assert_debug(std::isfinite(tmp),"Infinite value");
00231 return tmp;};
00232 double lognc () const {
00233 double tmp;
00234 double gam=sum ( beta );
00235 double lgb=0.0;
00236 for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
00237 tmp= lgb-lgamma ( gam );
00238 it_assert_debug(std::isfinite(tmp),"Infinite value");
00239 return tmp;
00240 };
00242 vec& _beta() {return beta;}
00244 void set_parameters ( const vec &beta0 ) {
00245 if ( beta0.length() !=beta.length() ) {
00246 it_assert_debug ( rv.length() ==1,"Undefined" );
00247 rv.set_size ( 0,beta0.length() );
00248 }
00249 beta= beta0;
00250 }
00251 };
00252
00254 class multiBM : public BMEF {
00255 protected:
00257 eDirich est;
00259 vec β
00260 public:
00262 multiBM ( const RV &rv, const vec beta0 ) : BMEF ( rv ),est ( rv,beta0 ),beta ( est._beta() ) {if(beta.length()>0){last_lognc=est.lognc();}else{last_lognc=0.0;}}
00264 multiBM ( const multiBM &B ) : BMEF ( B ),est ( rv,B.beta ),beta ( est._beta() ) {}
00266 void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;}
00267 void bayes ( const vec &dt ) {
00268 if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();}
00269 beta+=dt;
00270 if ( evalll ) {ll=est.lognc()-last_lognc;}
00271 }
00272 double logpred ( const vec &dt ) const {
00273 eDirich pred ( est );
00274 vec &beta = pred._beta();
00275
00276 double lll;
00277 if ( frg<1.0 )
00278 {beta*=frg;lll=pred.lognc();}
00279 else
00280 if ( evalll ) {lll=last_lognc;}
00281 else{lll=pred.lognc();}
00282
00283 beta+=dt;
00284 return pred.lognc()-lll;
00285 }
00286 void flatten ( const BMEF* B ) {
00287 const multiBM* E=dynamic_cast<const multiBM*> ( B );
00288
00289 const vec &Eb=E->beta;
00290 beta*= ( sum ( Eb ) /sum ( beta ) );
00291 if ( evalll ) {last_lognc=est.lognc();}
00292 }
00293 const epdf& _epdf() const {return est;};
00294 const eDirich* _e() const {return &est;};
00295 void set_parameters ( const vec &beta0 ) {
00296 est.set_parameters ( beta0 );
00297 rv = est._rv();
00298 if ( evalll ) {last_lognc=est.lognc();}
00299 }
00300 };
00301
00311 class egamma : public eEF {
00312 protected:
00314 vec alpha;
00316 vec beta;
00317 public :
00319 egamma ( const RV &rv ) :eEF ( rv ) {};
00321 void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;};
00322 vec sample() const;
00324
00325 double evallog ( const vec &val ) const;
00326 double lognc () const;
00328 void _param ( vec* &a, vec* &b ) {a=αb=β};
00329 vec mean() const {vec pom ( alpha ); pom/=beta; return pom;}
00330 };
00331
00333
00334
00335
00336
00337
00338
00340
00341
00342
00343
00344
00345
00346
00348
00349 class euni: public epdf {
00350 protected:
00352 vec low;
00354 vec high;
00356 vec distance;
00358 double nk;
00360 double lnk;
00361 public:
00363 euni ( const RV rv ) :epdf ( rv ) {}
00364 double eval ( const vec &val ) const {return nk;}
00365 double evallog ( const vec &val ) const {return lnk;}
00366 vec sample() const {
00367 vec smp ( rv.count() );
00368 #pragma omp critical
00369 UniRNG.sample_vector ( rv.count(),smp );
00370 return low+elem_mult ( distance,smp );
00371 }
00373 void set_parameters ( const vec &low0, const vec &high0 ) {
00374 distance = high0-low0;
00375 it_assert_debug ( min ( distance ) >0.0,"bad support" );
00376 low = low0;
00377 high = high0;
00378 nk = prod ( 1.0/distance );
00379 lnk = log ( nk );
00380 }
00381 vec mean() const {vec pom=high; pom-=low; pom/=2.0; return pom;}
00382 };
00383
00384
00390 template<class sq_T>
00391 class mlnorm : public mEF {
00392 protected:
00394 enorm<sq_T> epdf;
00395 mat A;
00396 vec mu_const;
00397 vec& _mu;
00398 public:
00400 mlnorm ( const RV &rv, const RV &rvc );
00402 void set_parameters ( const mat &A, const vec &mu0, const sq_T &R );
00403
00404
00405
00406
00408 void condition ( const vec &cond );
00409
00411 vec& _mu_const() {return mu_const;}
00413 mat& _A() {return A;}
00415 mat _R() {return epdf._R().to_mat();}
00416
00417 template<class sq_M>
00418 friend std::ostream &operator<< ( std::ostream &os, mlnorm<sq_M> &ml );
00419 };
00420
00423 class mlstudent : public mlnorm<ldmat> {
00424 protected:
00425 ldmat Lambda;
00426 ldmat &_R;
00427 ldmat Re;
00428 public:
00429 mlstudent ( const RV &rv0, const RV &rvc0 ) :mlnorm<ldmat> ( rv0,rvc0 ),
00430 Lambda ( rv0.count() ),
00431 _R ( epdf._R() ) {}
00432 void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0) {
00433 epdf.set_parameters ( zeros ( rv.count() ),Lambda );
00434 A = A0;
00435 mu_const = mu0;
00436 Re=R0;
00437 Lambda = Lambda0;
00438 }
00439 void condition ( const vec &cond ) {
00440 _mu = A*cond + mu_const;
00441 double zeta;
00442
00443 if ((cond.length()+1)==Lambda.rows()){
00444 zeta = Lambda.invqform ( concat(cond, vec_1(1.0)) );
00445 } else {
00446 zeta = Lambda.invqform ( cond );
00447 }
00448 _R = Re;
00449 _R*=( 1+zeta );
00450 };
00451
00452 };
00462 class mgamma : public mEF {
00463 protected:
00465 egamma epdf;
00467 double k;
00469 vec* _beta;
00470
00471 public:
00473 mgamma ( const RV &rv,const RV &rvc );
00475 void set_parameters ( double k );
00476 void condition ( const vec &val ) {*_beta=k/val;};
00477 };
00478
00490 class mgamma_fix : public mgamma {
00491 protected:
00493 double l;
00495 vec refl;
00496 public:
00498 mgamma_fix ( const RV &rv,const RV &rvc ) : mgamma ( rv,rvc ),refl ( rv.count() ) {};
00500 void set_parameters ( double k0 , vec ref0, double l0 ) {
00501 mgamma::set_parameters ( k0 );
00502 refl=pow ( ref0,1.0-l0 );l=l0;
00503 };
00504
00505 void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); *_beta=k/mean;};
00506 };
00507
00509 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
00515 class eEmp: public epdf {
00516 protected :
00518 int n;
00520 vec w;
00522 Array<vec> samples;
00523 public:
00525 eEmp ( const RV &rv0 ,int n0 ) :epdf ( rv0 ),n ( n0 ),w ( n ),samples ( n ) {};
00527 void set_parameters ( const vec &w0, const epdf* pdf0 );
00529 void set_samples ( const epdf* pdf0 );
00531 void set_n ( int n0, bool copy=true ){w.set_size(n0,copy);samples.set_size(n0,copy);};
00533 vec& _w() {return w;};
00535 const vec& _w() const {return w;};
00537 Array<vec>& _samples() {return samples;};
00539 const Array<vec>& _samples() const {return samples;};
00541 ivec resample ( RESAMPLING_METHOD method = SYSTEMATIC );
00543 vec sample() const {it_error ( "Not implemented" );return 0;}
00545 double evallog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
00546 vec mean() const {
00547 vec pom=zeros ( rv.count() );
00548 for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
00549 return pom;
00550 }
00551 };
00552
00553
00555
00556 template<class sq_T>
00557 enorm<sq_T>::enorm ( const RV &rv ) :eEF ( rv ), mu ( rv.count() ),R ( rv.count() ),dim ( rv.count() ) {};
00558
00559 template<class sq_T>
00560 void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 ) {
00561
00562 mu = mu0;
00563 R = R0;
00564 };
00565
00566 template<class sq_T>
00567 void enorm<sq_T>::dupdate ( mat &v, double nu ) {
00568
00569 };
00570
00571
00572
00573
00574
00575
00576 template<class sq_T>
00577 vec enorm<sq_T>::sample() const {
00578 vec x ( dim );
00579 NorRNG.sample_vector ( dim,x );
00580 vec smp = R.sqrt_mult ( x );
00581
00582 smp += mu;
00583 return smp;
00584 };
00585
00586 template<class sq_T>
00587 mat enorm<sq_T>::sample ( int N ) const {
00588 mat X ( dim,N );
00589 vec x ( dim );
00590 vec pom;
00591 int i;
00592
00593 for ( i=0;i<N;i++ ) {
00594 NorRNG.sample_vector ( dim,x );
00595 pom = R.sqrt_mult ( x );
00596 pom +=mu;
00597 X.set_col ( i, pom );
00598 }
00599
00600 return X;
00601 };
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 template<class sq_T>
00612 double enorm<sq_T>::evallog_nn ( const vec &val ) const {
00613
00614 double tmp=-0.5* ( R.invqform ( mu-val ) );
00615 return tmp;
00616 };
00617
00618 template<class sq_T>
00619 inline double enorm<sq_T>::lognc () const {
00620
00621 double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
00622 return tmp;
00623 };
00624
00625 template<class sq_T>
00626 mlnorm<sq_T>::mlnorm ( const RV &rv0, const RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu ( epdf._mu() ) {
00627 ep =&epdf;
00628 }
00629
00630 template<class sq_T>
00631 void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 ) {
00632 epdf.set_parameters ( zeros ( rv.count() ),R0 );
00633 A = A0;
00634 mu_const = mu0;
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662 template<class sq_T>
00663 void mlnorm<sq_T>::condition ( const vec &cond ) {
00664 _mu = A*cond + mu_const;
00665
00666 }
00667
00668 template<class sq_T>
00669 epdf* enorm<sq_T>::marginal ( const RV &rvn ) const {
00670 ivec irvn = rvn.dataind ( rv );
00671
00672 sq_T Rn ( R,irvn );
00673 enorm<sq_T>* tmp = new enorm<sq_T> ( rvn );
00674 tmp->set_parameters ( mu ( irvn ), Rn );
00675 return tmp;
00676 }
00677
00678 template<class sq_T>
00679 mpdf* enorm<sq_T>::condition ( const RV &rvn ) const {
00680
00681 RV rvc = rv.subt ( rvn );
00682 it_assert_debug ( ( rvc.count() +rvn.count() ==rv.count() ),"wrong rvn" );
00683
00684 ivec irvn = rvn.dataind ( rv );
00685 ivec irvc = rvc.dataind ( rv );
00686 ivec perm=concat ( irvn , irvc );
00687 sq_T Rn ( R,perm );
00688
00689
00690 mat S=Rn.to_mat();
00691
00692 int n=rvn.count()-1;
00693 int end=R.rows()-1;
00694 mat S11 = S.get ( 0,n, 0, n );
00695 mat S12 = S.get ( 0, n , rvn.count(), end );
00696 mat S22 = S.get ( rvn.count(), end, rvn.count(), end );
00697
00698 vec mu1 = mu ( irvn );
00699 vec mu2 = mu ( irvc );
00700 mat A=S12*inv ( S22 );
00701 sq_T R_n ( S11 - A *S12.T() );
00702
00703 mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( rvn,rvc );
00704
00705 tmp->set_parameters ( A,mu1-A*mu2,R_n );
00706 return tmp;
00707 }
00708
00710
00711 template<class sq_T>
00712 std::ostream &operator<< ( std::ostream &os, mlnorm<sq_T> &ml ) {
00713 os << "A:"<< ml.A<<endl;
00714 os << "mu:"<< ml.mu_const<<endl;
00715 os << "R:" << ml.epdf._R().to_mat() <<endl;
00716 return os;
00717 };
00718
00719 #endif //EF_H