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 ( const RV &rv ) :epdf ( rv ) {};
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 ( const RV &rv0, const RV &rvc0 ) :mpdf ( rv0,rvc0 ) {};
00071 };
00072
00074 class BMEF : public BM {
00075 protected:
00077 double frg;
00079 double last_lognc;
00080 public:
00082 BMEF ( const RV &rv, double frg0=1.0 ) :BM ( rv ), 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;
00115 int dim;
00116 public:
00118 enorm ( const RV &rv );
00120 void set_parameters ( const vec &mu,const sq_T &R );
00122
00124 void dupdate ( mat &v,double nu=1.0 );
00125
00126 vec sample() const;
00128 mat sample ( int N ) const;
00129
00130 double evallog_nn ( const vec &val ) const;
00131 double lognc () const;
00132 vec mean() const {return mu;}
00133 vec variance() const {return diag(R.to_mat());}
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 vec variance() const;
00195 void mean_mat ( mat &M, mat&R ) const;
00197 double evallog_nn ( const vec &val ) const;
00198 double lognc () const;
00199
00200
00202 ldmat& _V() {return V;}
00204 const ldmat& _V() const {return V;}
00206 double& _nu() {return nu;}
00207 const double& _nu() const {return nu;}
00208 void pow ( double p ) {V*=p;nu*=p;};
00209 };
00210
00219 class eDirich: public eEF {
00220 protected:
00222 vec beta;
00224 double gamma;
00225 public:
00227 eDirich ( const RV &rv, const vec &beta0 ) : eEF ( rv ),beta ( beta0 ) {it_assert_debug ( rv.count() ==beta.length(),"Incompatible statistics" ); };
00229 eDirich ( const eDirich &D0 ) : eEF ( D0.rv ),beta ( D0.beta ) {};
00230 vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
00231 vec mean() const {return beta/gamma;};
00232 vec variance() const {return elem_mult(beta,(beta+1))/ (gamma*(gamma+1));}
00234 double evallog_nn ( const vec &val ) const {double tmp; tmp=( beta-1 ) *log ( val ); it_assert_debug(std::isfinite(tmp),"Infinite value");
00235 return tmp;};
00236 double lognc () const {
00237 double tmp;
00238 double gam=sum ( beta );
00239 double lgb=0.0;
00240 for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
00241 tmp= lgb-lgamma ( gam );
00242 it_assert_debug(std::isfinite(tmp),"Infinite value");
00243 return tmp;
00244 };
00246 vec& _beta() {return beta;}
00248 void set_parameters ( const vec &beta0 ) {
00249 if ( beta0.length() !=beta.length() ) {
00250 it_assert_debug ( rv.length() ==1,"Undefined" );
00251 rv.set_size ( 0,beta0.length() );
00252 }
00253 beta= beta0;
00254 gamma = sum(beta);
00255 }
00256 };
00257
00259 class multiBM : public BMEF {
00260 protected:
00262 eDirich est;
00264 vec β
00265 public:
00267 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;}}
00269 multiBM ( const multiBM &B ) : BMEF ( B ),est ( rv,B.beta ),beta ( est._beta() ) {}
00271 void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;}
00272 void bayes ( const vec &dt ) {
00273 if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();}
00274 beta+=dt;
00275 if ( evalll ) {ll=est.lognc()-last_lognc;}
00276 }
00277 double logpred ( const vec &dt ) const {
00278 eDirich pred ( est );
00279 vec &beta = pred._beta();
00280
00281 double lll;
00282 if ( frg<1.0 )
00283 {beta*=frg;lll=pred.lognc();}
00284 else
00285 if ( evalll ) {lll=last_lognc;}
00286 else{lll=pred.lognc();}
00287
00288 beta+=dt;
00289 return pred.lognc()-lll;
00290 }
00291 void flatten ( const BMEF* B ) {
00292 const multiBM* E=dynamic_cast<const multiBM*> ( B );
00293
00294 const vec &Eb=E->beta;
00295 beta*= ( sum ( Eb ) /sum ( beta ) );
00296 if ( evalll ) {last_lognc=est.lognc();}
00297 }
00298 const epdf& _epdf() const {return est;};
00299 const eDirich* _e() const {return &est;};
00300 void set_parameters ( const vec &beta0 ) {
00301 est.set_parameters ( beta0 );
00302 rv = est._rv();
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 :
00324 egamma ( const RV &rv ) :eEF ( rv ), alpha(rv.count()), beta(rv.count()) {};
00326 void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;};
00327 vec sample() const;
00329
00330 double evallog ( const vec &val ) const;
00331 double lognc () const;
00333 void _param ( vec* &a, vec* &b ) {a=αb=β};
00334 vec mean() const {return elem_div(alpha,beta);}
00335 vec variance() const {return elem_div(alpha,elem_mult(beta,beta)); }
00336 };
00337
00352 class eigamma : public eEF {
00353 protected:
00355 vec* alpha;
00357 vec* beta;
00359 egamma eg;
00360 public :
00362 eigamma ( const RV &rv ) :eEF ( rv ), eg(rv) {eg._param(alpha,beta);};
00364 void set_parameters ( const vec &a, const vec &b ) {*alpha=a,*beta=b;};
00365 vec sample() const {return 1.0/eg.sample();};
00367
00368 double evallog ( const vec &val ) const {return eg.evallog(val);};
00369 double lognc () const {return eg.lognc();};
00371 void _param ( vec* &a, vec* &b ) {a=alpha;b=beta;};
00372 vec mean() const {return elem_div(*beta,*alpha-1);}
00373 vec variance() const {vec mea=mean(); return elem_div(elem_mult(mea,mea),*alpha-2);}
00374 };
00375
00377
00378
00379
00380
00381
00382
00384
00385
00386
00387
00388
00389
00390
00392
00393 class euni: public epdf {
00394 protected:
00396 vec low;
00398 vec high;
00400 vec distance;
00402 double nk;
00404 double lnk;
00405 public:
00407 euni ( const RV rv ) :epdf ( rv ) {}
00408 double eval ( const vec &val ) const {return nk;}
00409 double evallog ( const vec &val ) const {return lnk;}
00410 vec sample() const {
00411 vec smp ( rv.count() );
00412 #pragma omp critical
00413 UniRNG.sample_vector ( rv.count(),smp );
00414 return low+elem_mult ( distance,smp );
00415 }
00417 void set_parameters ( const vec &low0, const vec &high0 ) {
00418 distance = high0-low0;
00419 it_assert_debug ( min ( distance ) >0.0,"bad support" );
00420 low = low0;
00421 high = high0;
00422 nk = prod ( 1.0/distance );
00423 lnk = log ( nk );
00424 }
00425 vec mean() const {return (high-low)/2.0;}
00426 vec variance() const {return (pow(high,2)+pow(low,2)+elem_mult(high,low))/3.0;}
00427 };
00428
00429
00435 template<class sq_T>
00436 class mlnorm : public mEF {
00437 protected:
00439 enorm<sq_T> epdf;
00440 mat A;
00441 vec mu_const;
00442 vec& _mu;
00443 public:
00445 mlnorm ( const RV &rv, const RV &rvc );
00447 void set_parameters ( const mat &A, const vec &mu0, const sq_T &R );
00448
00449
00450
00451
00453 void condition ( const vec &cond );
00454
00456 vec& _mu_const() {return mu_const;}
00458 mat& _A() {return A;}
00460 mat _R() {return epdf._R().to_mat();}
00461
00462 template<class sq_M>
00463 friend std::ostream &operator<< ( std::ostream &os, mlnorm<sq_M> &ml );
00464 };
00465
00473 class mlstudent : public mlnorm<ldmat> {
00474 protected:
00475 ldmat Lambda;
00476 ldmat &_R;
00477 ldmat Re;
00478 public:
00479 mlstudent ( const RV &rv0, const RV &rvc0 ) :mlnorm<ldmat> ( rv0,rvc0 ),
00480 Lambda ( rv0.count() ),
00481 _R ( epdf._R() ) {}
00482 void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0) {
00483 epdf.set_parameters ( zeros ( rv.count() ),Lambda );
00484 A = A0;
00485 mu_const = mu0;
00486 Re=R0;
00487 Lambda = Lambda0;
00488 }
00489 void condition ( const vec &cond ) {
00490 _mu = A*cond + mu_const;
00491 double zeta;
00492
00493 if ((cond.length()+1)==Lambda.rows()){
00494 zeta = Lambda.invqform ( concat(cond, vec_1(1.0)) );
00495 } else {
00496 zeta = Lambda.invqform ( cond );
00497 }
00498 _R = Re;
00499 _R*=( 1+zeta );
00500 };
00501
00502 };
00512 class mgamma : public mEF {
00513 protected:
00515 egamma epdf;
00517 double k;
00519 vec* _beta;
00520
00521 public:
00523 mgamma ( const RV &rv,const RV &rvc ): mEF ( rv,rvc ), epdf ( rv ) {vec* tmp; epdf._param ( tmp,_beta );ep=&epdf;};
00525 void set_parameters ( double k );
00526 void condition ( const vec &val ) {*_beta=k/val;};
00527 };
00528
00538 class migamma : public mEF {
00539 protected:
00541 eigamma epdf;
00543 double k;
00545 vec* _beta;
00547 vec* _alpha;
00548
00549 public:
00551 migamma ( const RV &rv,const RV &rvc ): mEF ( rv,rvc ), epdf ( rv ) {epdf._param ( _alpha,_beta );ep=&epdf;};
00553 void set_parameters ( double k0 ){k=k0;*_alpha=1.0/(k*k)+2;};
00554 void condition ( const vec &val ) {
00555 *_beta=elem_mult(val,(*_alpha-1));
00556 };
00557 };
00558
00570 class mgamma_fix : public mgamma {
00571 protected:
00573 double l;
00575 vec refl;
00576 public:
00578 mgamma_fix ( const RV &rv,const RV &rvc ) : mgamma ( rv,rvc ),refl ( rv.count() ) {};
00580 void set_parameters ( double k0 , vec ref0, double l0 ) {
00581 mgamma::set_parameters ( k0 );
00582 refl=pow ( ref0,1.0-l0 );l=l0;
00583 };
00584
00585 void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); *_beta=k/mean;};
00586 };
00587
00588
00601 class migamma_fix : public migamma {
00602 protected:
00604 double l;
00606 vec refl;
00607 public:
00609 migamma_fix ( const RV &rv,const RV &rvc ) : migamma ( rv,rvc ),refl ( rv.count() ) {};
00611 void set_parameters ( double k0 , vec ref0, double l0 ) {
00612 migamma::set_parameters ( k0 );
00613 refl=pow ( ref0,1.0-l0 );l=l0;
00614 };
00615
00616 void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); migamma::condition(mean);};
00617 };
00619 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
00625 class eEmp: public epdf {
00626 protected :
00628 int n;
00630 vec w;
00632 Array<vec> samples;
00633 public:
00635 eEmp ( const RV &rv0 ,int n0 ) :epdf ( rv0 ),n ( n0 ),w ( n ),samples ( n ) {};
00637 void set_parameters ( const vec &w0, const epdf* pdf0 );
00639 void set_samples ( const epdf* pdf0 );
00641 void set_n ( int n0, bool copy=true ){w.set_size(n0,copy);samples.set_size(n0,copy);};
00643 vec& _w() {return w;};
00645 const vec& _w() const {return w;};
00647 Array<vec>& _samples() {return samples;};
00649 const Array<vec>& _samples() const {return samples;};
00651 ivec resample ( RESAMPLING_METHOD method = SYSTEMATIC );
00653 vec sample() const {it_error ( "Not implemented" );return 0;}
00655 double evallog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
00656 vec mean() const {
00657 vec pom=zeros ( rv.count() );
00658 for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
00659 return pom;
00660 }
00661 vec variance() const {
00662 vec pom=zeros ( rv.count() );
00663 for ( int i=0;i<n;i++ ) {pom+=pow(samples ( i ),2) *w ( i );}
00664 return pom-pow(mean(),2);
00665 }
00666 };
00667
00668
00670
00671 template<class sq_T>
00672 enorm<sq_T>::enorm ( const RV &rv ) :eEF ( rv ), mu ( rv.count() ),R ( rv.count() ),dim ( rv.count() ) {};
00673
00674 template<class sq_T>
00675 void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 ) {
00676
00677 mu = mu0;
00678 R = R0;
00679 };
00680
00681 template<class sq_T>
00682 void enorm<sq_T>::dupdate ( mat &v, double nu ) {
00683
00684 };
00685
00686
00687
00688
00689
00690
00691 template<class sq_T>
00692 vec enorm<sq_T>::sample() const {
00693 vec x ( dim );
00694 #pragma omp critical
00695 NorRNG.sample_vector ( dim,x );
00696 vec smp = R.sqrt_mult ( x );
00697
00698 smp += mu;
00699 return smp;
00700 };
00701
00702 template<class sq_T>
00703 mat enorm<sq_T>::sample ( int N ) const {
00704 mat X ( dim,N );
00705 vec x ( dim );
00706 vec pom;
00707 int i;
00708
00709 for ( i=0;i<N;i++ ) {
00710 #pragma omp critical
00711 NorRNG.sample_vector ( dim,x );
00712 pom = R.sqrt_mult ( x );
00713 pom +=mu;
00714 X.set_col ( i, pom );
00715 }
00716
00717 return X;
00718 };
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 template<class sq_T>
00729 double enorm<sq_T>::evallog_nn ( const vec &val ) const {
00730
00731 double tmp=-0.5* ( R.invqform ( mu-val ) );
00732 return tmp;
00733 };
00734
00735 template<class sq_T>
00736 inline double enorm<sq_T>::lognc () const {
00737
00738 double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
00739 return tmp;
00740 };
00741
00742 template<class sq_T>
00743 mlnorm<sq_T>::mlnorm ( const RV &rv0, const RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu ( epdf._mu() ) {
00744 ep =&epdf;
00745 }
00746
00747 template<class sq_T>
00748 void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 ) {
00749 epdf.set_parameters ( zeros ( rv.count() ),R0 );
00750 A = A0;
00751 mu_const = mu0;
00752 }
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 template<class sq_T>
00780 void mlnorm<sq_T>::condition ( const vec &cond ) {
00781 _mu = A*cond + mu_const;
00782
00783 }
00784
00785 template<class sq_T>
00786 epdf* enorm<sq_T>::marginal ( const RV &rvn ) const {
00787 ivec irvn = rvn.dataind ( rv );
00788
00789 sq_T Rn ( R,irvn );
00790 enorm<sq_T>* tmp = new enorm<sq_T> ( rvn );
00791 tmp->set_parameters ( mu ( irvn ), Rn );
00792 return tmp;
00793 }
00794
00795 template<class sq_T>
00796 mpdf* enorm<sq_T>::condition ( const RV &rvn ) const {
00797
00798 RV rvc = rv.subt ( rvn );
00799 it_assert_debug ( ( rvc.count() +rvn.count() ==rv.count() ),"wrong rvn" );
00800
00801 ivec irvn = rvn.dataind ( rv );
00802 ivec irvc = rvc.dataind ( rv );
00803 ivec perm=concat ( irvn , irvc );
00804 sq_T Rn ( R,perm );
00805
00806
00807 mat S=Rn.to_mat();
00808
00809 int n=rvn.count()-1;
00810 int end=R.rows()-1;
00811 mat S11 = S.get ( 0,n, 0, n );
00812 mat S12 = S.get ( 0, n , rvn.count(), end );
00813 mat S22 = S.get ( rvn.count(), end, rvn.count(), end );
00814
00815 vec mu1 = mu ( irvn );
00816 vec mu2 = mu ( irvc );
00817 mat A=S12*inv ( S22 );
00818 sq_T R_n ( S11 - A *S12.T() );
00819
00820 mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( rvn,rvc );
00821
00822 tmp->set_parameters ( A,mu1-A*mu2,R_n );
00823 return tmp;
00824 }
00825
00827
00828 template<class sq_T>
00829 std::ostream &operator<< ( std::ostream &os, mlnorm<sq_T> &ml ) {
00830 os << "A:"<< ml.A<<endl;
00831 os << "mu:"<< ml.mu_const<<endl;
00832 os << "R:" << ml.epdf._R().to_mat() <<endl;
00833 return os;
00834 };
00835
00836 }
00837 #endif //EF_H