00001
00013 #ifndef EF_H
00014 #define EF_H
00015
00016
00017 #include "libBM.h"
00018 #include "../math/chmat.h"
00019
00020
00021 namespace bdm {
00022
00023
00025 extern Uniform_RNG UniRNG;
00027 extern Normal_RNG NorRNG;
00029 extern Gamma_RNG GamRNG;
00030
00037 class eEF : public epdf {
00038 public:
00039
00041 eEF ( ) :epdf ( ) {};
00043 virtual double lognc() const =0;
00045 virtual void dupdate ( mat &v ) {it_error ( "Not implemented" );};
00047 virtual double evallog_nn ( const vec &val ) const{it_error ( "Not implemented" );return 0.0;};
00049 virtual double evallog ( const vec &val ) const {double tmp;tmp= evallog_nn ( val )-lognc();it_assert_debug ( std::isfinite ( tmp ),"Infinite value" ); return tmp;}
00051 virtual vec evallog ( const mat &Val ) const {
00052 vec x ( Val.cols() );
00053 for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evallog_nn ( Val.get_col ( i ) ) ;}
00054 return x-lognc();
00055 }
00057 virtual void pow ( double p ) {it_error ( "Not implemented" );};
00058 };
00059
00066 class mEF : public mpdf {
00067
00068 public:
00070 mEF ( ) :mpdf ( ) {};
00071 };
00072
00074 class BMEF : public BM {
00075 protected:
00077 double frg;
00079 double last_lognc;
00080 public:
00082 BMEF ( double frg0=1.0 ) :BM ( ), frg ( frg0 ) {}
00084 BMEF ( const BMEF &B ) :BM ( B ), frg ( B.frg ), last_lognc ( B.last_lognc ) {}
00086 virtual void set_statistics ( const BMEF* BM0 ) {it_error ( "Not implemented" );};
00088 virtual void bayes ( const vec &data, const double w ) {};
00089
00090 void bayes ( const vec &dt );
00092 virtual void flatten ( const BMEF * B ) {it_error ( "Not implemented" );}
00094
00095
00096 BMEF* _copy_ ( bool changerv=false ) {it_error ( "function _copy_ not implemented for this BM" ); return NULL;};
00097 };
00098
00099 template<class sq_T>
00100 class mlnorm;
00101
00107 template<class sq_T>
00108 class enorm : public eEF {
00109 protected:
00111 vec mu;
00113 sq_T R;
00114 public:
00117
00118 enorm ( ):eEF ( ), mu ( ),R ( ) {};
00119 enorm ( const vec &mu,const sq_T &R ) {set_parameters ( mu,R );}
00120 void set_parameters ( const vec &mu,const sq_T &R );
00122
00125
00127 void dupdate ( mat &v,double nu=1.0 );
00128
00129 vec sample() const;
00130 mat sample ( int N ) const;
00131 double evallog_nn ( const vec &val ) const;
00132 double lognc () const;
00133 vec mean() const {return mu;}
00134 vec variance() const {return diag ( R.to_mat() );}
00135
00136 mpdf* condition ( const RV &rvn ) const ;
00137
00138 epdf* marginal ( const RV &rv ) const;
00140
00143
00144 vec& _mu() {return mu;}
00145 void set_mu ( const vec mu0 ) { mu=mu0;}
00146 sq_T& _R() {return R;}
00147 const sq_T& _R() const {return R;}
00149
00150 };
00151
00158 class egiw : public eEF {
00159 protected:
00161 ldmat V;
00163 double nu;
00165 int dimx;
00167 int nPsi;
00168 public:
00171 egiw() :eEF() {};
00172 egiw ( int dimx0, ldmat V0, double nu0=-1.0 ) :eEF() {set_parameters ( dimx0,V0, nu0 );};
00173
00174 void set_parameters ( int dimx0, ldmat V0, double nu0=-1.0 ) {
00175 dimx=dimx0;
00176 nPsi = V0.rows()-dimx;
00177 dim = dimx* ( dimx+nPsi );
00178
00179 V=V0;
00180 if ( nu0<0 ) {
00181 nu = 0.1 +nPsi +2*dimx +2;
00182
00183 }
00184 else {
00185 nu=nu0;
00186 }
00187 }
00189
00190 vec sample() const;
00191 vec mean() const;
00192 vec variance() const;
00193 void mean_mat ( mat &M, mat&R ) const;
00195 double evallog_nn ( const vec &val ) const;
00196 double lognc () const;
00197 void pow ( double p ) {V*=p;nu*=p;};
00198
00201
00202 ldmat& _V() {return V;}
00203 const ldmat& _V() const {return V;}
00204 double& _nu() {return nu;}
00205 const double& _nu() const {return nu;}
00207 };
00208
00217 class eDirich: public eEF {
00218 protected:
00220 vec beta;
00222 double gamma;
00223 public:
00226
00227 eDirich () : eEF ( ) {};
00228 eDirich ( const eDirich &D0 ) : eEF () {set_parameters ( D0.beta );};
00229 eDirich ( const vec &beta0 ) {set_parameters ( beta0 );};
00230 void set_parameters ( const vec &beta0 ) {
00231 beta= beta0;
00232 dim = beta.length();
00233 gamma = sum ( beta );
00234 }
00236
00237 vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
00238 vec mean() const {return beta/gamma;};
00239 vec variance() const {return elem_mult ( beta, ( beta+1 ) ) / ( gamma* ( gamma+1 ) );}
00241 double evallog_nn ( const vec &val ) const {
00242 double tmp; tmp= ( beta-1 ) *log ( val ); it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
00243 return tmp;
00244 };
00245 double lognc () const {
00246 double tmp;
00247 double gam=sum ( beta );
00248 double lgb=0.0;
00249 for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
00250 tmp= lgb-lgamma ( gam );
00251 it_assert_debug ( std::isfinite ( tmp ),"Infinite value" );
00252 return tmp;
00253 };
00255 vec& _beta() {return beta;}
00257 };
00258
00260 class multiBM : public BMEF {
00261 protected:
00263 eDirich est;
00265 vec β
00266 public:
00268 multiBM ( ) : BMEF ( ),est ( ),beta ( est._beta() ) {if ( beta.length() >0 ) {last_lognc=est.lognc();}else{last_lognc=0.0;}}
00270 multiBM ( const multiBM &B ) : BMEF ( B ),est ( B.est ),beta ( est._beta() ) {}
00272 void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;}
00273 void bayes ( const vec &dt ) {
00274 if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();}
00275 beta+=dt;
00276 if ( evalll ) {ll=est.lognc()-last_lognc;}
00277 }
00278 double logpred ( const vec &dt ) const {
00279 eDirich pred ( est );
00280 vec &beta = pred._beta();
00281
00282 double lll;
00283 if ( frg<1.0 )
00284 {beta*=frg;lll=pred.lognc();}
00285 else
00286 if ( evalll ) {lll=last_lognc;}
00287 else{lll=pred.lognc();}
00288
00289 beta+=dt;
00290 return pred.lognc()-lll;
00291 }
00292 void flatten ( const BMEF* B ) {
00293 const multiBM* E=dynamic_cast<const multiBM*> ( B );
00294
00295 const vec &Eb=E->beta;
00296 beta*= ( sum ( Eb ) /sum ( beta ) );
00297 if ( evalll ) {last_lognc=est.lognc();}
00298 }
00299 const epdf& posterior() const {return est;};
00300 const eDirich* _e() const {return &est;};
00301 void set_parameters ( const vec &beta0 ) {
00302 est.set_parameters ( beta0 );
00303 if ( evalll ) {last_lognc=est.lognc();}
00304 }
00305 };
00306
00316 class egamma : public eEF {
00317 protected:
00319 vec alpha;
00321 vec beta;
00322 public :
00325 egamma ( ) :eEF ( ), alpha(), beta() {};
00326 egamma ( const vec &a, const vec &b ) {set_parameters ( a, b );};
00327 void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;dim = alpha.length();};
00329
00330 vec sample() const;
00332
00333 double evallog ( const vec &val ) const;
00334 double lognc () const;
00336 vec& _alpha() {return alpha;}
00337 vec& _beta() {return beta;}
00338 vec mean() const {return elem_div ( alpha,beta );}
00339 vec variance() const {return elem_div ( alpha,elem_mult ( beta,beta ) ); }
00340 };
00341
00356 class eigamma : public eEF {
00357 protected:
00359 egamma eg;
00361 vec α
00363 vec β
00364 public :
00367 eigamma ( ) :eEF ( ), eg(),alpha ( eg._alpha() ), beta ( eg._beta() ) {};
00368 eigamma ( const vec &a, const vec &b ):eEF ( ), eg(),alpha ( eg._alpha() ), beta ( eg._beta() ) {eg.set_parameters ( a,b );};
00369 void set_parameters ( const vec &a, const vec &b ) {eg.set_parameters ( a,b );};
00371
00372 vec sample() const {return 1.0/eg.sample();};
00374
00375 double evallog ( const vec &val ) const {return eg.evallog ( val );};
00376 double lognc () const {return eg.lognc();};
00378 vec mean() const {return elem_div ( beta,alpha-1 );}
00379 vec variance() const {vec mea=mean(); return elem_div ( elem_mult ( mea,mea ),alpha-2 );}
00380 vec& _alpha() {return alpha;}
00381 vec& _beta() {return beta;}
00382 };
00383
00385
00386
00387
00388
00389
00390
00392
00393
00394
00395
00396
00397
00398
00400
00401 class euni: public epdf {
00402 protected:
00404 vec low;
00406 vec high;
00408 vec distance;
00410 double nk;
00412 double lnk;
00413 public:
00416 euni ( ) :epdf ( ) {}
00417 euni ( const vec &low0, const vec &high0 ) {set_parameters ( low0,high0 );}
00418 void set_parameters ( const vec &low0, const vec &high0 ) {
00419 distance = high0-low0;
00420 it_assert_debug ( min ( distance ) >0.0,"bad support" );
00421 low = low0;
00422 high = high0;
00423 nk = prod ( 1.0/distance );
00424 lnk = log ( nk );
00425 dim = low.length();
00426 }
00428
00429 double eval ( const vec &val ) const {return nk;}
00430 double evallog ( const vec &val ) const {return lnk;}
00431 vec sample() const {
00432 vec smp ( dim );
00433 #pragma omp critical
00434 UniRNG.sample_vector ( dim ,smp );
00435 return low+elem_mult ( distance,smp );
00436 }
00438 vec mean() const {return ( high-low ) /2.0;}
00439 vec variance() const {return ( pow ( high,2 ) +pow ( low,2 ) +elem_mult ( high,low ) ) /3.0;}
00440 };
00441
00442
00448 template<class sq_T>
00449 class mlnorm : public mEF {
00450 protected:
00452 enorm<sq_T> epdf;
00453 mat A;
00454 vec mu_const;
00455 vec& _mu;
00456 public:
00459 mlnorm ( ) :mEF (),epdf ( ),A ( ),_mu ( epdf._mu() ) {ep =&epdf; };
00460 mlnorm ( const mat &A, const vec &mu0, const sq_T &R ) :epdf ( ),_mu ( epdf._mu() ) {
00461 ep =&epdf; set_parameters ( A,mu0,R );
00462 };
00464 void set_parameters ( const mat &A, const vec &mu0, const sq_T &R );
00467 void condition ( const vec &cond );
00468
00470 vec& _mu_const() {return mu_const;}
00472 mat& _A() {return A;}
00474 mat _R() {return epdf._R().to_mat();}
00475
00476 template<class sq_M>
00477 friend std::ostream &operator<< ( std::ostream &os, mlnorm<sq_M> &ml );
00478 };
00479
00487 class mlstudent : public mlnorm<ldmat> {
00488 protected:
00489 ldmat Lambda;
00490 ldmat &_R;
00491 ldmat Re;
00492 public:
00493 mlstudent ( ) :mlnorm<ldmat> (),
00494 Lambda (), _R ( epdf._R() ) {}
00495 void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0 ) {
00496 it_assert_debug ( A0.rows() ==mu0.length(),"" );
00497 it_assert_debug ( R0.rows() ==A0.rows(),"" );
00498
00499 epdf.set_parameters ( mu0,Lambda );
00500 A = A0;
00501 mu_const = mu0;
00502 Re=R0;
00503 Lambda = Lambda0;
00504 }
00505 void condition ( const vec &cond ) {
00506 _mu = A*cond + mu_const;
00507 double zeta;
00508
00509 if ( ( cond.length() +1 ) ==Lambda.rows() ) {
00510 zeta = Lambda.invqform ( concat ( cond, vec_1 ( 1.0 ) ) );
00511 }
00512 else {
00513 zeta = Lambda.invqform ( cond );
00514 }
00515 _R = Re;
00516 _R*= ( 1+zeta );
00517 };
00518
00519 };
00529 class mgamma : public mEF {
00530 protected:
00532 egamma epdf;
00534 double k;
00536 vec &_beta;
00537
00538 public:
00540 mgamma ( ) : mEF ( ), epdf (), _beta ( epdf._beta() ) {ep=&epdf;};
00542 void set_parameters ( double k, const vec &beta0 );
00543 void condition ( const vec &val ) {_beta=k/val;};
00544 };
00545
00555 class migamma : public mEF {
00556 protected:
00558 eigamma epdf;
00560 double k;
00562 vec &_alpha;
00564 vec &_beta;
00565
00566 public:
00569 migamma ( ) : mEF (), epdf ( ), _alpha ( epdf._alpha() ), _beta ( epdf._beta() ) {ep=&epdf;};
00570 migamma ( const migamma &m ) : mEF (), epdf ( m.epdf ), _alpha ( epdf._alpha() ), _beta ( epdf._beta() ) {ep=&epdf;};
00572
00574 void set_parameters ( int len, double k0 ) {
00575 k=k0;
00576 epdf.set_parameters ( ( 1.0/ ( k*k ) +2.0 ) *ones ( len ) , ones ( len ) );
00577 dimc = dimension();
00578 };
00579 void condition ( const vec &val ) {
00580 _beta=elem_mult ( val, ( _alpha-1.0 ) );
00581 };
00582 };
00583
00595 class mgamma_fix : public mgamma {
00596 protected:
00598 double l;
00600 vec refl;
00601 public:
00603 mgamma_fix ( ) : mgamma ( ),refl () {};
00605 void set_parameters ( double k0 , vec ref0, double l0 ) {
00606 mgamma::set_parameters ( k0, ref0 );
00607 refl=pow ( ref0,1.0-l0 );l=l0;
00608 dimc=dimension();
00609 };
00610
00611 void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); _beta=k/mean;};
00612 };
00613
00614
00627 class migamma_fix : public migamma {
00628 protected:
00630 double l;
00632 vec refl;
00633 public:
00635 migamma_fix ( ) : migamma (),refl ( ) {};
00637 void set_parameters ( double k0 , vec ref0, double l0 ) {
00638 migamma::set_parameters ( ref0.length(), k0 );
00639 refl=pow ( ref0,1.0-l0 );
00640 l=l0;
00641 dimc = dimension();
00642 };
00643
00644 void condition ( const vec &val ) {
00645 vec mean=elem_mult ( refl,pow ( val,l ) );
00646 migamma::condition ( mean );
00647 };
00648 };
00650 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
00656 class eEmp: public epdf {
00657 protected :
00659 int n;
00661 vec w;
00663 Array<vec> samples;
00664 public:
00667 eEmp ( ) :epdf ( ),w ( ),samples ( ) {};
00668 eEmp (const eEmp &e ): epdf(e), w(e.w), samples(e.samples) {};
00670
00672 void set_parameters ( const vec &w0, const epdf* pdf0 );
00674 void set_samples ( const epdf* pdf0 );
00676 void set_n ( int n0, bool copy=true ) {w.set_size ( n0,copy );samples.set_size ( n0,copy );};
00678 vec& _w() {return w;};
00680 const vec& _w() const {return w;};
00682 Array<vec>& _samples() {return samples;};
00684 const Array<vec>& _samples() const {return samples;};
00686 ivec resample ( RESAMPLING_METHOD method = SYSTEMATIC );
00688 vec sample() const {it_error ( "Not implemented" );return 0;}
00690 double evallog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
00691 vec mean() const {
00692 vec pom=zeros ( dim );
00693 for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
00694 return pom;
00695 }
00696 vec variance() const {
00697 vec pom=zeros ( dim );
00698 for ( int i=0;i<n;i++ ) {pom+=pow ( samples ( i ),2 ) *w ( i );}
00699 return pom-pow ( mean(),2 );
00700 }
00701 };
00702
00703
00705
00706 template<class sq_T>
00707 void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 ) {
00708
00709 mu = mu0;
00710 R = R0;
00711 dim = mu0.length();
00712 };
00713
00714 template<class sq_T>
00715 void enorm<sq_T>::dupdate ( mat &v, double nu ) {
00716
00717 };
00718
00719
00720
00721
00722
00723
00724 template<class sq_T>
00725 vec enorm<sq_T>::sample() const {
00726 vec x ( dim );
00727 #pragma omp critical
00728 NorRNG.sample_vector ( dim,x );
00729 vec smp = R.sqrt_mult ( x );
00730
00731 smp += mu;
00732 return smp;
00733 };
00734
00735 template<class sq_T>
00736 mat enorm<sq_T>::sample ( int N ) const {
00737 mat X ( dim,N );
00738 vec x ( dim );
00739 vec pom;
00740 int i;
00741
00742 for ( i=0;i<N;i++ ) {
00743 #pragma omp critical
00744 NorRNG.sample_vector ( dim,x );
00745 pom = R.sqrt_mult ( x );
00746 pom +=mu;
00747 X.set_col ( i, pom );
00748 }
00749
00750 return X;
00751 };
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 template<class sq_T>
00762 double enorm<sq_T>::evallog_nn ( const vec &val ) const {
00763
00764 double tmp=-0.5* ( R.invqform ( mu-val ) );
00765 return tmp;
00766 };
00767
00768 template<class sq_T>
00769 inline double enorm<sq_T>::lognc () const {
00770
00771 double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
00772 return tmp;
00773 };
00774
00775 template<class sq_T>
00776 void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 ) {
00777 it_assert_debug ( A0.rows() ==mu0.length(),"" );
00778 it_assert_debug ( A0.rows() ==R0.rows(),"" );
00779
00780 epdf.set_parameters ( zeros ( A0.rows() ),R0 );
00781 A = A0;
00782 mu_const = mu0;
00783 dimc=A0.cols();
00784 }
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 template<class sq_T>
00812 void mlnorm<sq_T>::condition ( const vec &cond ) {
00813 _mu = A*cond + mu_const;
00814
00815 }
00816
00817 template<class sq_T>
00818 epdf* enorm<sq_T>::marginal ( const RV &rvn ) const {
00819 it_assert_debug(isnamed(), "rv description is not assigned");
00820 ivec irvn = rvn.dataind ( rv );
00821
00822 sq_T Rn ( R,irvn );
00823
00824 enorm<sq_T>* tmp = new enorm<sq_T>;
00825 tmp->set_rv ( rvn );
00826 tmp->set_parameters ( mu ( irvn ), Rn );
00827 return tmp;
00828 }
00829
00830 template<class sq_T>
00831 mpdf* enorm<sq_T>::condition ( const RV &rvn ) const {
00832
00833 it_assert_debug ( isnamed(),"rvs are not assigned" );
00834
00835 RV rvc = rv.subt ( rvn );
00836 it_assert_debug ( ( rvc._dsize() +rvn._dsize() ==rv._dsize() ),"wrong rvn" );
00837
00838 ivec irvn = rvn.dataind ( rv );
00839 ivec irvc = rvc.dataind ( rv );
00840 ivec perm=concat ( irvn , irvc );
00841 sq_T Rn ( R,perm );
00842
00843
00844 mat S=Rn.to_mat();
00845
00846 int n=rvn._dsize()-1;
00847 int end=R.rows()-1;
00848 mat S11 = S.get ( 0,n, 0, n );
00849 mat S12 = S.get ( 0, n , rvn._dsize(), end );
00850 mat S22 = S.get ( rvn._dsize(), end, rvn._dsize(), end );
00851
00852 vec mu1 = mu ( irvn );
00853 vec mu2 = mu ( irvc );
00854 mat A=S12*inv ( S22 );
00855 sq_T R_n ( S11 - A *S12.T() );
00856
00857 mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( );
00858 tmp->set_rv(rvn); tmp->set_rvc(rvc);
00859 tmp->set_parameters ( A,mu1-A*mu2,R_n );
00860 return tmp;
00861 }
00862
00864
00865 template<class sq_T>
00866 std::ostream &operator<< ( std::ostream &os, mlnorm<sq_T> &ml ) {
00867 os << "A:"<< ml.A<<endl;
00868 os << "mu:"<< ml.mu_const<<endl;
00869 os << "R:" << ml.epdf._R().to_mat() <<endl;
00870 return os;
00871 };
00872
00873 }
00874 #endif //EF_H