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 evalpdflog_nn ( const vec &val ) const{it_error ( "Not implemented" );return 0.0;};
00050         virtual double evalpdflog ( const vec &val ) const {double tmp;tmp= evalpdflog_nn ( val )-lognc();it_assert_debug(std::isfinite(tmp),"why?"); return tmp;}
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 ( 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         double eval ( const vec &val ) const ;
00131         double evalpdflog_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 
00149 
00150 };
00151 
00158 class egiw : public eEF {
00159 protected:
00161         ldmat V;
00163         double nu;
00165         int xdim;
00167         int nPsi;
00168 public:
00170         egiw ( RV rv, mat V0, double nu0=-1.0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) {
00171                 xdim = rv.count() /V.rows();
00172                 it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." );
00173                 nPsi = V.rows()-xdim;
00174                 
00175                 if (nu0<0){
00176                         nu = 0.1 +nPsi +2*xdim +2; 
00177                         
00178                 }
00179         }
00181         egiw ( RV rv, ldmat V0, double nu0=-1.0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) {
00182                 xdim = rv.count() /V.rows();
00183                 it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." );
00184                 nPsi = V.rows()-xdim;
00185                 if (nu0<0){
00186                         nu = 0.1 +nPsi +2*xdim +2; 
00187                         
00188                 }
00189         }
00190 
00191         vec sample() const;
00192         vec mean() const;
00193         void mean_mat ( mat &M, mat&R ) const;
00195         double evalpdflog_nn ( const vec &val ) const;
00196         double lognc () const;
00197 
00198         
00200         ldmat& _V() {return V;}
00202         const ldmat& _V() const {return V;}
00204         double& _nu()  {return nu;}
00205         const double& _nu() const {return nu;}
00206         void pow ( double p ) {V*=p;nu*=p;};
00207 };
00208 
00217 class eDirich: public eEF {
00218 protected:
00220         vec beta;
00221 public:
00223         eDirich ( const RV &rv, const vec &beta0 ) : eEF ( rv ),beta ( beta0 ) {it_assert_debug ( rv.count() ==beta.length(),"Incompatible statistics" ); };
00225         eDirich ( const eDirich &D0 ) : eEF ( D0.rv ),beta ( D0.beta ) {};
00226         vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );};
00227         vec mean() const {return beta/sum ( beta );};
00229         double evalpdflog_nn ( const vec &val ) const {return ( beta-1 ) *log ( val );};
00230         double lognc () const {
00231                 double gam=sum ( beta );
00232                 double lgb=0.0;
00233                 for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );}
00234                 return lgb-lgamma ( gam );
00235         };
00237         vec& _beta()  {return beta;}
00239         void set_parameters ( const vec &beta0 ) {
00240                 if ( beta0.length() !=beta.length() ) {
00241                         it_assert_debug ( rv.length() ==1,"Undefined" );
00242                         rv.set_size ( 0,beta0.length() );
00243                 }
00244                 beta= beta0;
00245         }
00246 };
00247 
00249 class multiBM : public BMEF {
00250 protected:
00252         eDirich est;
00254         vec β
00255 public:
00257         multiBM ( const RV &rv, const vec beta0 ) : BMEF ( rv ),est ( rv,beta0 ),beta ( est._beta() ) {last_lognc=est.lognc();}
00259         multiBM ( const multiBM &B ) : BMEF ( B ),est ( rv,B.beta ),beta ( est._beta() ) {}
00261         void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;}
00262         void bayes ( const vec &dt ) {
00263                 if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();}
00264                 beta+=dt;
00265                 if ( evalll ) {ll=est.lognc()-last_lognc;}
00266         }
00267         double logpred ( const vec &dt ) const {
00268                 eDirich pred ( est );
00269                 vec &beta = pred._beta();
00270 
00271                 double lll;
00272                 if ( frg<1.0 )
00273                         {beta*=frg;lll=pred.lognc();}
00274                 else
00275                         if ( evalll ) {lll=last_lognc;}
00276                         else{lll=pred.lognc();}
00277 
00278                 beta+=dt;
00279                 return pred.lognc()-lll;
00280         }
00281         void flatten ( const BMEF* B ) {
00282                 const multiBM* E=dynamic_cast<const multiBM*> ( B );
00283                 
00284                 const vec &Eb=E->beta;
00285                 beta*= ( sum ( Eb ) /sum ( beta ) );
00286                 if ( evalll ) {last_lognc=est.lognc();}
00287         }
00288         const epdf& _epdf() const {return est;};
00289         const eDirich* _e() const {return &est;};
00290         void set_parameters ( const vec &beta0 ) {
00291                 est.set_parameters ( beta0 );
00292                 rv = est._rv();
00293                 if ( evalll ) {last_lognc=est.lognc();}
00294         }
00295 };
00296 
00306 class egamma : public eEF {
00307 protected:
00309         vec alpha;
00311         vec beta;
00312 public :
00314         egamma ( const RV &rv ) :eEF ( rv ) {};
00316         void set_parameters ( const vec &a, const vec &b ) {alpha=a,beta=b;};
00317         vec sample() const;
00319 
00320         double evalpdflog ( const vec &val ) const;
00321         double lognc () const;
00323         void _param ( vec* &a, vec* &b ) {a=αb=β};
00324         vec mean() const {vec pom ( alpha ); pom/=beta; return pom;}
00325 };
00326 
00328 
00329 
00330 
00331 
00332 
00333 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00343 
00344 class euni: public epdf {
00345 protected:
00347         vec low;
00349         vec high;
00351         vec distance;
00353         double nk;
00355         double lnk;
00356 public:
00358         euni ( const RV rv ) :epdf ( rv ) {}
00359         double eval ( const vec &val ) const  {return nk;}
00360         double evalpdflog ( const vec &val ) const  {return lnk;}
00361         vec sample() const {
00362                 vec smp ( rv.count() );
00363 #pragma omp critical
00364                 UniRNG.sample_vector ( rv.count(),smp );
00365                 return low+elem_mult ( distance,smp );
00366         }
00368         void set_parameters ( const vec &low0, const vec &high0 ) {
00369                 distance = high0-low0;
00370                 it_assert_debug ( min ( distance ) >0.0,"bad support" );
00371                 low = low0;
00372                 high = high0;
00373                 nk = prod ( 1.0/distance );
00374                 lnk = log ( nk );
00375         }
00376         vec mean() const {vec pom=high; pom-=low; pom/=2.0; return pom;}
00377 };
00378 
00379 
00385 template<class sq_T>
00386 class mlnorm : public mEF {
00387 protected:
00389         enorm<sq_T> epdf;
00390         mat A;
00391         vec mu_const;
00392         vec& _mu; 
00393 public:
00395         mlnorm ( const RV &rv, const RV &rvc );
00397         void set_parameters ( const  mat &A, const vec &mu0, const sq_T &R );
00398 
00399 
00400 
00401 
00403         void condition ( const vec &cond );
00404 
00406         vec& _mu_const() {return mu_const;}
00408         mat& _A() {return A;}
00410         mat _R() {return epdf._R().to_mat();}
00411 
00412         template<class sq_M>
00413         friend std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_M> &ml );
00414 };
00415 
00418 class mlstudent : public mlnorm<ldmat> {
00419 protected:
00420         ldmat Lambda;
00421         ldmat &_R;
00422         ldmat Re;
00423 public:
00424         mlstudent ( const RV &rv0, const RV &rvc0 ) :mlnorm<ldmat> ( rv0,rvc0 ),
00425                         Lambda ( rv0.count() ),
00426                         _R ( epdf._R() ) {}
00427         void set_parameters ( const mat &A0, const vec &mu0, const ldmat &R0, const ldmat& Lambda0) {
00428                 epdf.set_parameters ( zeros ( rv.count() ),Lambda );
00429                 A = A0;
00430                 mu_const = mu0;
00431                 Re=R0;
00432                 Lambda = Lambda0;
00433         }
00434         void condition ( const vec &cond ) {
00435                 _mu = A*cond + mu_const;
00436                 double zeta;
00437                 
00438                 if ((cond.length()+1)==Lambda.rows()){
00439                         zeta = Lambda.invqform ( concat(cond, vec_1(1.0)) );
00440                 } else {
00441                         zeta = Lambda.invqform ( cond );
00442                 }
00443                 _R = Re;
00444                 _R*=( 1+zeta );
00445         };
00446 
00447 };
00457 class mgamma : public mEF {
00458 protected:
00460         egamma epdf;
00462         double k;
00464         vec* _beta;
00465 
00466 public:
00468         mgamma ( const RV &rv,const RV &rvc );
00470         void set_parameters ( double k );
00471         void condition ( const vec &val ) {*_beta=k/val;};
00472 };
00473 
00485 class mgamma_fix : public mgamma {
00486 protected:
00488         double l;
00490         vec refl;
00491 public:
00493         mgamma_fix ( const RV &rv,const RV &rvc ) : mgamma ( rv,rvc ),refl ( rv.count() ) {};
00495         void set_parameters ( double k0 , vec ref0, double l0 ) {
00496                 mgamma::set_parameters ( k0 );
00497                 refl=pow ( ref0,1.0-l0 );l=l0;
00498         };
00499 
00500         void condition ( const vec &val ) {vec mean=elem_mult ( refl,pow ( val,l ) ); *_beta=k/mean;};
00501 };
00502 
00504 enum RESAMPLING_METHOD { MULTINOMIAL = 0, STRATIFIED = 1, SYSTEMATIC = 3 };
00510 class eEmp: public epdf {
00511 protected :
00513         int n;
00515         vec w;
00517         Array<vec> samples;
00518 public:
00520         eEmp ( const RV &rv0 ,int n0 ) :epdf ( rv0 ),n ( n0 ),w ( n ),samples ( n ) {};
00522         void set_parameters ( const vec &w0, const epdf* pdf0 );
00524         void set_samples ( const epdf* pdf0 );
00526         void set_n ( int n0, bool copy=true ){w.set_size(n0,copy);samples.set_size(n0,copy);};
00528         vec& _w()  {return w;};
00530         const vec& _w() const {return w;};
00532         Array<vec>& _samples() {return samples;};
00534         const Array<vec>& _samples() const {return samples;};
00536         ivec resample ( RESAMPLING_METHOD method = SYSTEMATIC );
00538         vec sample() const {it_error ( "Not implemented" );return 0;}
00540         double evalpdflog ( const vec &val ) const {it_error ( "Not implemented" );return 0.0;}
00541         vec mean() const {
00542                 vec pom=zeros ( rv.count() );
00543                 for ( int i=0;i<n;i++ ) {pom+=samples ( i ) *w ( i );}
00544                 return pom;
00545         }
00546 };
00547 
00548 
00550 
00551 template<class sq_T>
00552 enorm<sq_T>::enorm ( const RV &rv ) :eEF ( rv ), mu ( rv.count() ),R ( rv.count() ),dim ( rv.count() ) {};
00553 
00554 template<class sq_T>
00555 void enorm<sq_T>::set_parameters ( const vec &mu0, const sq_T &R0 ) {
00556 
00557         mu = mu0;
00558         R = R0;
00559 };
00560 
00561 template<class sq_T>
00562 void enorm<sq_T>::dupdate ( mat &v, double nu ) {
00563         
00564 };
00565 
00566 
00567 
00568 
00569 
00570 
00571 template<class sq_T>
00572 vec enorm<sq_T>::sample() const {
00573         vec x ( dim );
00574         NorRNG.sample_vector ( dim,x );
00575         vec smp = R.sqrt_mult ( x );
00576 
00577         smp += mu;
00578         return smp;
00579 };
00580 
00581 template<class sq_T>
00582 mat enorm<sq_T>::sample ( int N ) const {
00583         mat X ( dim,N );
00584         vec x ( dim );
00585         vec pom;
00586         int i;
00587 
00588         for ( i=0;i<N;i++ ) {
00589                 NorRNG.sample_vector ( dim,x );
00590                 pom = R.sqrt_mult ( x );
00591                 pom +=mu;
00592                 X.set_col ( i, pom );
00593         }
00594 
00595         return X;
00596 };
00597 
00598 template<class sq_T>
00599 double enorm<sq_T>::eval ( const vec &val ) const {
00600         double pdfl,e;
00601         pdfl = evalpdflog ( val );
00602         e = exp ( pdfl );
00603         return e;
00604 };
00605 
00606 template<class sq_T>
00607 double enorm<sq_T>::evalpdflog_nn ( const vec &val ) const {
00608         
00609         double tmp=-0.5* ( R.invqform ( mu-val ) );
00610         return  tmp;
00611 };
00612 
00613 template<class sq_T>
00614 inline double enorm<sq_T>::lognc () const {
00615         
00616         double tmp=0.5* ( R.cols() * 1.83787706640935 +R.logdet() );
00617         return tmp;
00618 };
00619 
00620 template<class sq_T>
00621 mlnorm<sq_T>::mlnorm ( const RV &rv0, const RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu ( epdf._mu() ) {
00622         ep =&epdf;
00623 }
00624 
00625 template<class sq_T>
00626 void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 ) {
00627         epdf.set_parameters ( zeros ( rv.count() ),R0 );
00628         A = A0;
00629         mu_const = mu0;
00630 }
00631 
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 template<class sq_T>
00658 void mlnorm<sq_T>::condition ( const vec &cond ) {
00659         _mu = A*cond + mu_const;
00660 
00661 }
00662 
00663 template<class sq_T>
00664 epdf* enorm<sq_T>::marginal ( const RV &rvn ) const {
00665         ivec irvn = rvn.dataind ( rv );
00666 
00667         sq_T Rn ( R,irvn );
00668         enorm<sq_T>* tmp = new enorm<sq_T> ( rvn );
00669         tmp->set_parameters ( mu ( irvn ), Rn );
00670         return tmp;
00671 }
00672 
00673 template<class sq_T>
00674 mpdf* enorm<sq_T>::condition ( const RV &rvn ) const {
00675 
00676         RV rvc = rv.subt ( rvn );
00677         it_assert_debug ( ( rvc.count() +rvn.count() ==rv.count() ),"wrong rvn" );
00678         
00679         ivec irvn = rvn.dataind ( rv );
00680         ivec irvc = rvc.dataind ( rv );
00681         ivec perm=concat ( irvn , irvc );
00682         sq_T Rn ( R,perm );
00683 
00684         
00685         mat S=Rn.to_mat();
00686         
00687         int n=rvn.count()-1;
00688         int end=R.rows()-1;
00689         mat S11 = S.get ( 0,n, 0, n );
00690         mat S12 = S.get ( 0, n , rvn.count(), end );
00691         mat S22 = S.get ( rvn.count(), end, rvn.count(), end );
00692 
00693         vec mu1 = mu ( irvn );
00694         vec mu2 = mu ( irvc );
00695         mat A=S12*inv ( S22 );
00696         sq_T R_n ( S11 - A *S12.T() );
00697 
00698         mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( rvn,rvc );
00699 
00700         tmp->set_parameters ( A,mu1-A*mu2,R_n );
00701         return tmp;
00702 }
00703 
00705 
00706 template<class sq_T>
00707 std::ostream &operator<< ( std::ostream &os,  mlnorm<sq_T> &ml ) {
00708         os << "A:"<< ml.A<<endl;
00709         os << "mu:"<< ml.mu_const<<endl;
00710         os << "R:" << ml.epdf._R().to_mat() <<endl;
00711         return os;
00712 };
00713 
00714 #endif //EF_H