Changeset 170 for bdm/stat

Show
Ignore:
Timestamp:
09/24/08 13:07:50 (16 years ago)
Author:
smidl
Message:

Mixtures of EF and related changes to libEF and BM

Location:
bdm/stat
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • bdm/stat/emix.h

    r168 r170  
    139139protected: 
    140140        //! Components (epdfs) 
    141         Array<epdf*> epdfs; 
     141        Array<const epdf*> epdfs; 
    142142        //! Array of indeces 
    143143        Array<ivec> rvinds; 
    144144public: 
    145         eprod ( const Array<epdf*> epdfs0 ) : epdf ( RV() ),epdfs ( epdfs0 ),rvinds ( epdfs.length() ) { 
     145        eprod ( const Array<const epdf*> epdfs0 ) : epdf ( RV() ),epdfs ( epdfs0 ),rvinds ( epdfs.length() ) { 
    146146                bool independent=true; 
    147147                for ( int i=0;i<epdfs.length();i++ ) { 
     
    175175                return tmp; 
    176176        } 
     177        //!access function 
     178        const epdf* operator () (int i) const {it_assert_debug(i<epdfs.length(),"wrong index");return epdfs(i);} 
    177179}; 
    178180 
  • bdm/stat/libBM.cpp

    r168 r170  
    180180        return pom; 
    181181} 
     182 
     183void RV::newids(){ids=linspace ( RVcounter+1, RVcounter+len ),RVcounter+=len;} 
     184 
     185void BM::bayesB(const mat &Data){ 
     186        for(int t=0;t<Data.cols();t++){bayes(Data.get_col(t));} 
     187} 
  • bdm/stat/libBM.h

    r168 r170  
    103103        //!access function 
    104104        std::string name ( int at ) {return names ( at );}; 
     105        //!Assign unused ids to this rv  
     106        void newids(); 
    105107}; 
    106108 
     
    144146        epdf ( const RV &rv0 ) :rv ( rv0 ) {}; 
    145147 
    146         //! Returns the required moment of the epdf 
     148//      //! Returns the required moment of the epdf 
    147149//      virtual vec moment ( const int order = 1 ); 
     150         
    148151        //! Returns a sample, \f$x\f$ from density \f$epdf(rv)\f$ 
    149152        virtual vec sample () const =0; 
     
    156159        virtual double evalpdflog ( const vec &val ) const =0; 
    157160 
     161        //! Compute log-probability of multiple values argument \c val 
     162        virtual vec evalpdflog ( const mat &Val ) const { 
     163                vec x ( Val.cols() ); 
     164                for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evalpdflog( Val.get_col(i) ) ;} 
     165                return x; 
     166        } 
     167 
    158168        //! return expected value 
    159169        virtual vec mean() const =0; 
     
    162172        virtual ~epdf() {}; 
    163173        //! access function, possibly dangerous! 
    164         RV& _rv() {return rv;} 
     174        const RV& _rv() const {return rv;} 
     175        //! modifier function - useful when copying epdfs 
     176        void _renewrv(const RV &in_rv){rv=in_rv;} 
    165177}; 
    166178 
     
    270282 
    271283        //!Default constructor 
    272         BM ( const RV &rv0 ) :rv ( rv0 ), ll ( 0 ),evalll ( true ) {//Fixme: test rv 
     284        BM ( const RV &rv0, double ll0=0,bool evalll0=true ) :rv ( rv0 ), ll ( ll0 ),evalll ( evalll0) {//Fixme: test rv 
    273285        }; 
     286        //!Copy constructor 
     287        BM (const BM &B) : rv(B.rv), ll(B.ll), evalll(B.evalll) {} 
    274288 
    275289        /*! \brief Incremental Bayes rule 
     
    278292        virtual void bayes ( const vec &dt ) = 0; 
    279293        //! Batch Bayes rule (columns of Dt are observations) 
    280         void bayes ( mat Dt ); 
     294        virtual void bayesB (const mat &Dt ); 
    281295        //! Returns a pointer to the epdf representing posterior density on parameters. Use with care! 
    282         virtual epdf& _epdf() =0; 
    283  
     296        virtual const epdf& _epdf() const =0; 
     297 
     298        //! Evaluates predictive log-likelihood of the given data record 
     299        //! I.e. marginal likelihood of the data with the posterior integrated out. 
     300        virtual double logpred(const vec &dt)const{it_error("Not implemented");return 0.0;} 
     301         
    284302        //! Destructor for future use; 
    285303        virtual ~BM() {}; 
     
    290308        //!access function  
    291309        void set_evalll(bool evl0){evalll=evl0;} 
     310         
     311        //! Copy function required in vectors, Arrays of BM etc. Have to be DELETED manually! 
     312        //! Prototype: BM* _copy_(){BM Tmp*=new Tmp(this*);  return Tmp; } 
     313        virtual BM* _copy_(bool changerv=false){it_error("function _copy_ not implemented for this BM"); return NULL;}; 
    292314}; 
    293315 
  • bdm/stat/libEF.cpp

    r168 r170  
    1212using std::cout; 
    1313 
     14void BMEF::bayes ( const vec &dt ) {this->bayes ( dt,1.0 );}; 
     15 
    1416vec egiw::sample() const { 
    1517        it_warning ( "Function not implemented" ); 
     
    1719} 
    1820 
    19 double egiw::evalpdflog ( const vec &val ) const { 
     21double egiw::evalpdflog_nn ( const vec &val ) const { 
     22        int vend = val.length()-1; 
    2023 
    2124        if ( xdim==1 ) { //same as the following, just quicker. 
    22                 double r = val ( val.length()-1 ); //last entry! 
     25                double r = val ( vend ); //last entry! 
    2326                vec Psi ( nPsi+xdim ); 
    2427                Psi ( 0 ) = -1.0; 
    25                 Psi.set_subvector ( 1,val ); // fill the rest 
    26  
    27                 return -0.5* ( nu*log ( r ) + V.qform ( Psi ) /r ) + lognc(); 
     28                Psi.set_subvector ( 1,val ( 0,vend-1 ) ); // fill the rest 
     29 
     30                double Vq=V.qform ( Psi ); 
     31                return -0.5* ( nu*log ( r ) + Vq /r ); 
    2832        } 
    2933        else { 
    30                 int vend = val.length()-1; 
    3134                mat Th= reshape ( val ( 0,nPsi*xdim-1 ),nPsi,xdim ); 
    3235                fsqmat R ( reshape ( val ( nPsi*xdim,vend ),xdim,xdim ) ); 
     
    3437                fsqmat iR ( xdim ); 
    3538                R.inv ( iR ); 
    36                  
    37                 return -0.5* ( nu*R.logdet() + trace ( iR.to_mat() *Tmp.T()*V.to_mat() *Tmp ) ) + lognc(); 
     39 
     40                return -0.5* ( nu*R.logdet() + trace ( iR.to_mat() *Tmp.T() *V.to_mat() *Tmp ) ); 
    3841        } 
    3942} 
     
    5558                     - 0.5*xdim* ( m*log2 + 0.5* ( xdim-1 ) *log2pi )  - lg; 
    5659 
    57         return nkG+nkW; 
     60        return -nkG-nkW; 
    5861} 
    5962 
    6063vec egiw::mean() const { 
     64 
     65        if ( xdim==1 ) { 
     66                const mat &L= V._L(); 
     67                const vec &D= V._D(); 
     68                int end = L.rows()-1; 
     69 
     70                vec m ( rv.count() ); 
     71                mat iLsub = ltuinv ( L ( xdim,end,xdim,end ) ); 
     72 
     73                vec L0 = L.get_col ( 0 ); 
     74 
     75                m.set_subvector ( 0,iLsub*L0 ( 1,end ) ); 
     76                m ( end ) = D ( 0 ) / ( nu -nPsi -2*xdim -2 ); 
     77                return m; 
     78        } else { 
     79                mat M; 
     80                mat R; 
     81                mean_mat(M,R); 
     82                return cvectorize (concat_vertical(M,R)); 
     83        } 
     84 
     85} 
     86void egiw::mean_mat(mat &M, mat&R) const { 
    6187        const mat &L= V._L(); 
    6288        const vec &D= V._D(); 
    6389        int end = L.rows()-1; 
    64  
    65         vec m(rv.count()); 
    66         mat iLsub = ltuinv ( L ( xdim,end,xdim,end ) ); 
     90                 
     91        ldmat ldR ( L ( 0,xdim-1,0,xdim-1 ), D ( 0,xdim-1 ) / ( nu -nPsi -2*xdim -2 ) ); //exp val of R 
     92        mat iLsub=ltuinv ( L ( xdim,end,xdim,end ) ); 
    6793         
    68         if ( xdim==1 ) { 
    69                 vec L0 = L.get_col ( 0 ); 
    70  
    71                 m.set_subvector ( 0,iLsub*L0 ( 1,end ) ); 
    72                 m ( end ) = D ( 0 ) / ( nu -nPsi -2*xdim -2); 
    73         } 
    74         else { 
    75                 ldmat ldR(L(0,xdim,0,xdim), D(0,xdim)/( nu -nPsi -2*xdim -2)); //exp val of R 
    76                 mat iLsub=ltuinv ( L ( xdim,end,xdim,end ) ); 
    77                 mat M = iLsub*L(xdim,end,0,xdim); 
    78                  
    79                 m = cvectorize(concat_vertical(M,ldR.to_mat())); 
    80         } 
    81         return m; 
    82 } 
     94        // set mean value 
     95        M= iLsub*L ( xdim,end,0,xdim-1 ); 
     96        R= ldR.to_mat()  ; 
     97} 
     98 
     99void egiw::pow(double p){V*=p;nu*=p;} 
    83100 
    84101vec egamma::sample() const { 
  • bdm/stat/libEF.h

    r168 r170  
    4141        //! default constructor 
    4242        eEF ( const RV &rv ) :epdf ( rv ) {}; 
    43         //! logarithm of the normalizing constant, \f$\mathcal{I}\f$  
    44         virtual double lognc()const =0; 
     43        //! logarithm of the normalizing constant, \f$\mathcal{I}\f$ 
     44        virtual double lognc() const =0; 
    4545        //!TODO decide if it is really needed 
    46         virtual void tupdate ( double phi, mat &vbar, double nubar ) {}; 
    47         //!TODO decide if it is really needed 
    48         virtual void dupdate ( mat &v,double nu=1.0 ) {}; 
     46        virtual void dupdate ( mat &v ) {it_error ( "Not implemneted" );}; 
     47        //!Evaluate normalized log-probability 
     48        virtual double evalpdflog_nn ( const vec &val ) const{it_error ( "Not implemneted" );return 0.0;}; 
     49        //!Evaluate normalized log-probability 
     50        virtual double evalpdflog ( const vec &val ) const {return evalpdflog_nn ( val )-lognc();} 
     51        //!Evaluate normalized log-probability for many samples 
     52        virtual vec evalpdflog ( const mat &Val ) const { 
     53                vec x ( Val.cols() ); 
     54                for ( int i=0;i<Val.cols();i++ ) {x ( i ) =evalpdflog_nn ( Val.get_col ( i ) ) ;} 
     55                return x-lognc(); 
     56        } 
     57        //!Power of the density, used e.g. to flatten the density 
     58        virtual void pow ( double p ) {it_error ( "Not implemented" );}; 
    4959}; 
    5060 
     
    6070        //! Default constructor 
    6171        mEF ( const RV &rv0, const RV &rvc0 ) :mpdf ( rv0,rvc0 ) {}; 
     72}; 
     73 
     74//! Estimator for Exponential family 
     75class BMEF : public BM { 
     76protected: 
     77        //! forgetting factor 
     78        double frg; 
     79        //! cached value of lognc() in the previous step (used in evaluation of \c ll ) 
     80        double last_lognc; 
     81public: 
     82        //! Default constructor 
     83        BMEF ( const RV &rv, double frg0=1.0 ) :BM ( rv ), frg ( frg0 ) {} 
     84        //! Copy constructor 
     85        BMEF ( const BMEF &B ) :BM ( B ), frg ( B.frg ), last_lognc ( B.last_lognc ) {} 
     86        //!get statistics from another model 
     87        virtual void set_statistics ( const BMEF* BM0 ) {it_error ( "Not implemented" );}; 
     88        //! Weighted update of sufficient statistics (Bayes rule) 
     89        virtual void bayes ( const vec &data, const double w ) {}; 
     90        //original Bayes 
     91        void bayes ( const vec &dt ); 
     92        //!Flatten the posterior 
     93        virtual void flatten ( BMEF * B) {it_error ( "Not implemented" );} 
    6294}; 
    6395 
     
    99131        //! returns a pointer to the internal mean value. Use with Care! 
    100132        vec& _mu() {return mu;} 
    101          
     133 
    102134        //! access function 
    103         void set_mu(const vec mu0) { mu=mu0;} 
     135        void set_mu ( const vec mu0 ) { mu=mu0;} 
    104136 
    105137        //! returns pointers to the internal variance and its inverse. Use with Care! 
     
    128160public: 
    129161        //!Default constructor, assuming 
    130         egiw(RV rv, mat V0, double nu0): eEF(rv), V(V0), nu(nu0) { 
    131                 xdim = rv.count()/V.rows(); 
    132                 it_assert_debug(rv.count()==xdim*V.rows(),"Incompatible V0."); 
     162        egiw ( RV rv, mat V0, double nu0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) { 
     163                xdim = rv.count() /V.rows(); 
     164                it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." ); 
     165                nPsi = V.rows()-xdim; 
     166        } 
     167        //!Full constructor for V in ldmat form 
     168        egiw ( RV rv, ldmat V0, double nu0 ) : eEF ( rv ), V ( V0 ), nu ( nu0 ) { 
     169                xdim = rv.count() /V.rows(); 
     170                it_assert_debug ( rv.count() ==xdim*V.rows(),"Incompatible V0." ); 
    133171                nPsi = V.rows()-xdim; 
    134172        } 
     
    136174        vec sample() const; 
    137175        vec mean() const; 
     176        void mean_mat ( mat &M, mat&R ) const; 
    138177        //! In this instance, val= [theta, r]. For multivariate instances, it is stored columnwise val = [theta_1 theta_2 ... r_1 r_2 ] 
    139         double evalpdflog ( const vec &val ) const; 
     178        double evalpdflog_nn ( const vec &val ) const; 
    140179        double lognc () const; 
    141180 
     
    145184        //! returns a pointer to the internal statistics. Use with Care! 
    146185        double& _nu() {return nu;} 
    147  
     186        void pow ( double p ); 
     187}; 
     188 
     189/*! \brief Dirichlet posterior density 
     190Continuous Dirichlet density of \f$n\f$-dimensional variable \f$x\f$ 
     191\f[ 
     192f(x|\beta) = \frac{\Gamma[\gamma]}{\prod_{i=1}^{n}\Gamma(\beta_i)} \prod_{i=1}^{n]x_i^(\beta_i-1) 
     193\f] 
     194where \f$\gamma=\sum_i beta_i\f$. 
     195*/ 
     196class eDirich: public eEF { 
     197protected: 
     198        //!sufficient statistics 
     199        vec beta; 
     200public: 
     201        //!Default constructor 
     202        eDirich ( const RV &rv, const vec &beta0 ) : eEF ( rv ),beta ( beta0 ) {it_assert_debug ( rv.count() ==beta.length(),"Incompatible statistics" ); }; 
     203        //! Copy constructor 
     204        eDirich ( const eDirich &D0 ) : eEF ( D0.rv ),beta ( D0.beta ) {}; 
     205        vec sample() const {it_error ( "Not implemented" );return vec_1 ( 0.0 );}; 
     206        vec mean() const {return beta/sum ( beta );}; 
     207        //! In this instance, val= [theta, r]. For multivariate instances, it is stored columnwise val = [theta_1 theta_2 ... r_1 r_2 ] 
     208        double evalpdflog_nn ( const vec &val ) const {return ( beta-1 ) *log ( val );}; 
     209        double lognc () const { 
     210                double gam=sum ( beta ); 
     211                double lgb=0.0; 
     212                for ( int i=0;i<beta.length();i++ ) {lgb+=lgamma ( beta ( i ) );} 
     213                return lgb-lgamma ( gam ); 
     214        }; 
     215        //!access function 
     216        vec& _beta() {return beta;} 
     217}; 
     218 
     219//! Estimator for Multinomial density 
     220class multiBM : public BMEF { 
     221protected: 
     222        //! Conjugate prior and posterior 
     223        eDirich est; 
     224        vec &beta; 
     225public: 
     226        //!Default constructor 
     227        multiBM ( const RV &rv, const vec beta0 ) : BMEF ( rv ),est ( rv,beta0 ),beta ( est._beta() ) {last_lognc=est.lognc();} 
     228        //!Copy constructor 
     229        multiBM ( const multiBM &B ) : BMEF ( B ),est ( rv,B.beta ),beta ( est._beta() ) {} 
     230 
     231        void set_statistics ( const BM* mB0 ) {const multiBM* mB=dynamic_cast<const multiBM*> ( mB0 ); beta=mB->beta;} 
     232        void bayes ( const vec &dt ) { 
     233                if ( frg<1.0 ) {beta*=frg;last_lognc=est.lognc();} 
     234                beta+=dt; 
     235                if ( evalll ) {ll=est.lognc()-last_lognc;} 
     236        } 
     237        double logpred ( const vec &dt ) const { 
     238                eDirich pred ( est ); 
     239                vec &beta = pred._beta(); 
     240                 
     241                double lll; 
     242                if ( frg<1.0 ) 
     243                        {beta*=frg;lll=pred.lognc();} 
     244                else 
     245                        if ( evalll ) {lll=last_lognc;} 
     246                        else{lll=pred.lognc();} 
     247 
     248                beta+=dt; 
     249                return pred.lognc()-lll; 
     250        } 
     251        void flatten (BMEF* B ) { 
     252                eDirich* E=dynamic_cast<eDirich*>(B); 
     253                // sum(beta) should be equal to sum(B.beta) 
     254                const vec &Eb=E->_beta(); 
     255                est.pow ( sum(beta)/sum(Eb) ); 
     256                if(evalll){last_lognc=est.lognc();} 
     257        } 
     258        const epdf& _epdf() const {return est;}; 
     259        //!access funct 
    148260}; 
    149261 
     
    151263 \brief Gamma posterior density 
    152264 
    153  Multvariate Gamma density as product of independent univariate densities. 
     265 Multivariate Gamma density as product of independent univariate densities. 
    154266 \f[ 
    155267 f(x|\alpha,\beta) = \prod f(x_i|\alpha_i,\beta_i) 
     
    213325        double evalpdflog ( const vec &val ) const  {return lnk;} 
    214326        vec sample() const { 
    215                 vec smp ( rv.count() );  
    216                 #pragma omp critical 
     327                vec smp ( rv.count() ); 
     328#pragma omp critical 
    217329                UniRNG.sample_vector ( rv.count(),smp ); 
    218                 return low+elem_mult(distance,smp); 
     330                return low+elem_mult ( distance,smp ); 
    219331        } 
    220332        //! set values of \c low and \c high 
     
    408520double enorm<sq_T>::evalpdflog ( const vec &val ) const { 
    409521        // 1.83787706640935 = log(2pi) 
    410         return  -0.5* (  +R.invqform ( mu-val ) ) - lognc(); 
     522        return  -0.5* ( +R.invqform ( mu-val ) ) - lognc(); 
    411523}; 
    412524 
     
    414526inline double enorm<sq_T>::lognc () const { 
    415527        // 1.83787706640935 = log(2pi) 
    416         return -0.5* ( R.cols() * 1.83787706640935 +R.logdet()); 
    417 }; 
    418  
    419 template<class sq_T> 
    420 mlnorm<sq_T>::mlnorm ( RV &rv0,RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu(epdf._mu()) { ep =&epdf; 
     528        return -0.5* ( R.cols() * 1.83787706640935 +R.logdet() ); 
     529}; 
     530 
     531template<class sq_T> 
     532mlnorm<sq_T>::mlnorm ( RV &rv0,RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu ( epdf._mu() ) { 
     533        ep =&epdf; 
    421534} 
    422535