Changeset 178

Show
Ignore:
Timestamp:
10/15/08 19:04:09 (16 years ago)
Author:
smidl
Message:

Changes in basic structures! new methods

Location:
bdm/stat
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • bdm/stat/emix.cpp

    r175 r178  
    33using namespace itpp; 
    44 
    5 void emix::set_parameters ( const vec &w0, const Array<epdf*> &Coms0 ) { 
    6         w = w0/sum(w0); 
     5void emix::set_parameters ( const vec &w0, const Array<epdf*> &Coms0, bool copy ) { 
     6        w = w0/sum ( w0 ); 
    77        int i; 
    88        for ( i=0;i<w.length();i++ ) { 
    99                it_assert_debug ( rv.equal ( Coms0 ( i )->_rv() ),"RVs do not match!" ); 
    1010        } 
    11         Coms = Coms0; 
     11        if ( copy ) { 
     12                Coms.set_length(Coms0.length()); 
     13                for ( i=0;i<w.length();i++ ) {*Coms ( i ) =*Coms0 ( i );} 
     14                destroyComs=true; 
     15        } 
     16        else { 
     17                Coms = Coms0; 
     18                destroyComs=false; 
     19        } 
    1220} 
    1321 
     
    3745//                      rvc.add ( mpdfs ( i )->_rvc().subt ( rv ) ); //add rv to common rvs. 
    3846//              }; 
    39 //               
     47// 
    4048// //           independent = true; 
    4149//              //test rvc of mpdfs and fill rvinds 
  • bdm/stat/emix.h

    r176 r178  
    3636        //! Component (epdfs) 
    3737        Array<epdf*> Coms; 
     38        //!Flag if owning Coms 
     39        bool destroyComs; 
    3840public: 
    3941        //!Default constructor 
    40         emix ( RV &rv ) : epdf ( rv ) {}; 
    41         //! Set weights \c w and components \c R 
    42         void set_parameters ( const vec &w, const Array<epdf*> &Coms ); 
     42        emix (const RV &rv ) : epdf ( rv ) {}; 
     43        //! Set weights \c w and components \c Coms , Coms are not copied! 
     44        void set_parameters ( const vec &w, const Array<epdf*> &Coms, bool copy=true ); 
    4345 
    4446        vec sample() const; 
     
    5860        //! returns a pointer to the internal mean value. Use with Care! 
    5961        vec& _w() {return w;} 
     62        virtual ~emix(){if (destroyComs){for(int i=0;i<Coms.length();i++){delete Coms(i);}}} 
     63        //! Auxiliary function for taking ownership of the Coms() 
     64        void ownComs(){destroyComs=true;} 
    6065}; 
    6166 
     
    102107                ll = 0; 
    103108                for ( int i = ( n - 1 );i >= 0;i-- ) { 
    104                         if ( rvcinds ( i ).length() > 0 ) { 
    105                                 condi = zeros ( rvcsinrv.length() + rvcinds.length() ); 
     109                        if (( rvcinds ( i ).length() > 0 )||( rvcsinrv ( i ).length() > 0 )) { 
     110                                condi = zeros ( rvcsinrv(i).length() + rvcinds(i).length() ); 
    106111                                // copy data in condition 
    107112                                set_subvector ( condi,rvcinds ( i ), cond ); 
    108113                                // copy data in already generated sample 
    109                                 set_subvector ( condi,rvcsinrv ( i ), smp ); 
     114                                set_subvector ( condi,rvinrvcs ( i ), get_vec(smp,rvcsinrv(i)) ); 
    110115 
    111116                                mpdfs ( i )->condition ( condi ); 
  • bdm/stat/libBM.cpp

    r176 r178  
    157157RV RV::subt ( const RV &rv2 ) const { 
    158158        ivec res = this->findself ( rv2 ); // nonzeros 
    159         ivec valid = itpp::find ( res == -1 ); //-1 => value not found => it remains 
     159        ivec valid; 
     160        if (tsize>0) {valid= itpp::find ( res == -1 );} //-1 => value not found => it remains 
    160161        return ( *this ) ( valid ); //keep those that were not found in rv2 
    161162} 
     
    196197void compositepdf::setrvc(const RV &rv, RV &rvc){ 
    197198        for (int i = 0;i < n;i++ ) { 
    198                 rvc.add ( mpdfs ( i )->_rvc().subt ( rv ) ); //add rv to common rvc 
     199                RV rvx = mpdfs ( i )->_rvc().subt ( rv ); 
     200                rvc.add ( rvx ); //add rv to common rvc 
    199201        }; 
    200202} 
     
    202204void compositepdf::setindices(const RV &rv){ 
    203205        for (int i = 0;i < n;i++ ) { 
    204                         // find ith rv in common rv 
     206                // find ith rv in common rv 
    205207                rvsinrv ( i ) = mpdfs ( i )->_rv().dataind ( rv ); 
    206208                rvcsinrv ( i ) = mpdfs ( i )->_rvc().dataind ( rv ); 
     209                rvinrvcs ( i ) = rv.dataind(mpdfs ( i )->_rvc()); 
     210                //rvcsinrv and rvinrvcs must be 1-to-1 
     211                it_assert_debug(rvcsinrv ( i ).length()==rvinrvcs(i).length(),"" ); 
    207212        } 
    208213} 
  • bdm/stat/libBM.h

    r176 r178  
    140140}; 
    141141 
     142class mpdf; 
    142143 
    143144//! Probability density function with numerical statistics, e.g. posterior density. 
     
    173174                return x; 
    174175        } 
     176        //! Return conditional density on the given RV, the remaining rvs will be in conditioning 
     177        mpdf* condition(const RV &rv){it_warning("Not implemented"); return NULL;} 
     178        //! Return marginal density on the given RV, the remainig rvs are intergrated out 
     179        epdf* marginal(const RV &rv){it_warning("Not implemented"); return NULL;} 
    175180 
    176181        //! return expected value 
     
    183188        //! modifier function - useful when copying epdfs 
    184189        void _renewrv(const RV &in_rv){rv=in_rv;} 
     190        //! 
    185191}; 
    186192 
     
    213219        }; 
    214220        //! Update \c ep so that it represents this mpdf conditioned on \c rvc = cond 
    215         virtual void condition ( const vec &cond ) {}; 
     221        virtual void condition ( const vec &cond ) {it_error("Not implemented");}; 
    216222 
    217223        //! Shortcut for conditioning and evaluation of the internal epdf. In some cases,  this operation can be implemented efficiently. 
     
    252258                //! Indeces of rvc in common rv 
    253259                Array<ivec> rvcsinrv; 
     260                //! Indeces of common rv in rvc 
     261                Array<ivec> rvinrvcs; 
    254262        public: 
    255                 compositepdf(Array<mpdf*> A0): n(A0.length()), mpdfs(A0), rvsinrv(n), rvcsinrv(n){}; 
     263                compositepdf(Array<mpdf*> A0): n(A0.length()), mpdfs(A0), rvsinrv(n), rvcsinrv(n),rvinrvcs(n){}; 
    256264                RV getrv(bool checkoverlap=false); 
    257265                void setrvc(const RV &rv, RV &rvc); 
     
    329337        vec logpred_m(const mat &dt)const{vec tmp(dt.cols());for(int i=0;i<dt.cols();i++){tmp(i)=logpred(dt.get_col(i));}return tmp;} 
    330338         
     339        //!Constructs a predictive density (marginal density on data) 
     340        virtual epdf* predictor(const RV &rv){it_error("Not implemented");return NULL;}; 
     341         
    331342        //! Destructor for future use; 
    332343        virtual ~BM() {}; 
  • bdm/stat/libEF.cpp

    r170 r178  
    4949#define logpi 1.144729885849400163877476189 
    5050#define log2pi 1.83787706640935 
     51#define Inf std::numeric_limits<double>::infinity() 
    5152 
    5253        double nkG = 0.5* xdim* ( -nPsi *log2pi + sum ( log ( D ( xdim,D.length()-1 ) ) ) ); 
     
    5859                     - 0.5*xdim* ( m*log2 + 0.5* ( xdim-1 ) *log2pi )  - lg; 
    5960 
     61        it_assert_debug(((-nkG-nkW)>-Inf) && ((-nkG-nkW)<Inf), "ARX improper"); 
    6062        return -nkG-nkW; 
    6163} 
     
    244246} 
    245247 
    246 void eEmp::set_parameters ( const vec &w0, epdf* epdf0 ) { 
     248void eEmp::set_parameters ( const vec &w0, const epdf* epdf0 ) { 
    247249        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0"); 
    248250        w=w0; 
     
    253255        for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();} 
    254256} 
     257 
     258void eEmp::set_samples (  const epdf* epdf0 ) { 
     259        //it_assert_debug(rv==epdf0->rv(),"Wrong epdf0"); 
     260        w=1; 
     261        w/=sum ( w );//renormalize 
     262 
     263        for ( int i=0;i<n;i++ ) {samples ( i ) =epdf0->sample();} 
     264} 
     265 
  • bdm/stat/libEF.h

    r176 r178  
    4444        virtual double lognc() const =0; 
    4545        //!TODO decide if it is really needed 
    46         virtual void dupdate ( mat &v ) {it_error ( "Not implemneted" );}; 
     46        virtual void dupdate ( mat &v ) {it_error ( "Not implemented" );}; 
    4747        //!Evaluate normalized log-probability 
    48         virtual double evalpdflog_nn ( const vec &val ) const{it_error ( "Not implemneted" );return 0.0;}; 
     48        virtual double evalpdflog_nn ( const vec &val ) const{it_error ( "Not implemented" );return 0.0;}; 
    4949        //!Evaluate normalized log-probability 
    5050        virtual double evalpdflog ( const vec &val ) const {return evalpdflog_nn ( val )-lognc();} 
     
    9090        //original Bayes 
    9191        void bayes ( const vec &dt ); 
    92         //!Flatten the posterior 
    93         virtual void flatten ( BMEF * B ) {it_error ( "Not implemented" );} 
    94 }; 
     92        //!Flatten the posterior according to the given BMEF (of the same type!) 
     93        virtual void flatten ( const BMEF * B ) {it_error ( "Not implemented" );} 
     94        //!Flatten the posterior as if to keep nu0 data 
     95        virtual void flatten ( double nu0 ) {it_error ( "Not implemented" );} 
     96}; 
     97 
     98template<class sq_T> 
     99class mlnorm; 
    95100 
    96101/*! 
     
    100105*/ 
    101106template<class sq_T> 
    102  
    103107class enorm : public eEF { 
    104108protected: 
     
    110114        int dim; 
    111115public: 
    112 //      enorm() :eEF() {}; 
    113116        //!Default constructor 
    114         enorm ( RV &rv ); 
     117        enorm ( const RV &rv ); 
    115118        //! Set mean value \c mu and covariance \c R 
    116119        void set_parameters ( const vec &mu,const sq_T &R ); 
    117         //! tupdate in exponential form (not really handy) 
    118         void tupdate ( double phi, mat &vbar, double nubar ); 
     120        ////! tupdate in exponential form (not really handy) 
     121        //void tupdate ( double phi, mat &vbar, double nubar ); 
    119122        //! dupdate in exponential form (not really handy) 
    120123        void dupdate ( mat &v,double nu=1.0 ); 
     
    124127        mat sample ( int N ) const; 
    125128        double eval ( const vec &val ) const ; 
    126         double evalpdflog ( const vec &val ) const; 
     129        double evalpdflog_nn ( const vec &val ) const; 
    127130        double lognc () const; 
    128131        vec mean() const {return mu;} 
    129  
     132        mlnorm<sq_T>* condition ( const RV &rvn ); 
     133        enorm<sq_T>* marginal ( const RV &rv ); 
    130134//Access methods 
    131135        //! returns a pointer to the internal mean value. Use with Care! 
     
    139143 
    140144        //! access method 
    141         mat getR () {return R.to_mat();} 
     145//      mat getR () {return R.to_mat();} 
    142146}; 
    143147 
     
    215219        }; 
    216220        //!access function 
    217         vec& _beta() {return beta;} 
     221        vec& _beta()  {return beta;} 
    218222        //!Set internal parameters 
    219         void set_parameters(const vec &beta0){ 
    220                 if(beta0.length()!=beta.length()){ 
    221                         it_assert_debug(rv.length()==1,"Undefined"); 
    222                         rv.set_size(0,beta0.length()); 
     223        void set_parameters ( const vec &beta0 ) { 
     224                if ( beta0.length() !=beta.length() ) { 
     225                        it_assert_debug ( rv.length() ==1,"Undefined" ); 
     226                        rv.set_size ( 0,beta0.length() ); 
    223227                } 
    224228                beta= beta0; 
     
    258262                return pred.lognc()-lll; 
    259263        } 
    260         void flatten ( BMEF* B ) { 
    261                 eDirich* E=dynamic_cast<eDirich*> ( B ); 
     264        void flatten ( const BMEF* B ) { 
     265                const eDirich* E=dynamic_cast<const eDirich*> ( B ); 
    262266                // sum(beta) should be equal to sum(B.beta) 
    263                 const vec &Eb=E->_beta(); 
     267                const vec &Eb=const_cast<eDirich*> ( E )->_beta(); 
    264268                est.pow ( sum ( beta ) /sum ( Eb ) ); 
    265269                if ( evalll ) {last_lognc=est.lognc();} 
     
    267271        const epdf& _epdf() const {return est;}; 
    268272        void set_parameters ( const vec &beta0 ) { 
    269                 est.set_parameters(beta0); 
     273                est.set_parameters ( beta0 ); 
    270274                rv = est._rv(); 
    271                 if(evalll){last_lognc=est.lognc();} 
     275                if ( evalll ) {last_lognc=est.lognc();} 
    272276        } 
    273277}; 
     
    359363 \brief Normal distributed linear function with linear function of mean value; 
    360364 
    361  Mean value \f$mu=A*rvc\f$. 
     365 Mean value \f$mu=A*rvc+mu_0\f$. 
    362366*/ 
    363367template<class sq_T> 
     
    366370        enorm<sq_T> epdf; 
    367371        mat A; 
     372        vec mu_const; 
    368373        vec& _mu; //cached epdf.mu; 
    369374public: 
    370375        //! Constructor 
    371         mlnorm ( RV &rv,RV &rvc ); 
     376        mlnorm (const RV &rv, const RV &rvc ); 
    372377        //! Set \c A and \c R 
    373         void set_parameters ( const  mat &A, const sq_T &R ); 
     378        void set_parameters ( const  mat &A, const vec &mu0, const sq_T &R ); 
    374379        //!Generate one sample of the posterior 
    375         vec samplecond ( vec &cond, double &lik ); 
     380        vec samplecond (const vec &cond, double &lik ); 
    376381        //!Generate matrix of samples of the posterior 
    377         mat samplecond ( vec &cond, vec &lik, int n ); 
     382        mat samplecond (const vec &cond, vec &lik, int n ); 
    378383        //! Set value of \c rvc . Result of this operation is stored in \c epdf use function \c _ep to access it. 
    379         void condition ( vec &cond ); 
     384        void condition (const vec &cond ); 
    380385}; 
    381386 
     
    453458        //! Default constructor 
    454459        eEmp ( const RV &rv0 ,int n0 ) :epdf ( rv0 ),n ( n0 ),w ( n ),samples ( n ) {}; 
     460        //! Set samples and weights 
     461        void set_parameters ( const vec &w0, const epdf* pdf0 ); 
    455462        //! Set sample 
    456         void set_parameters ( const vec &w0, epdf* pdf0 ); 
     463        void set_samples ( const epdf* pdf0 ); 
    457464        //! Potentially dangerous, use with care. 
    458465        vec& _w()  {return w;}; 
     
    476483 
    477484template<class sq_T> 
    478 enorm<sq_T>::enorm ( RV &rv ) :eEF ( rv ), mu ( rv.count() ),R ( rv.count() ),dim ( rv.count() ) {}; 
     485enorm<sq_T>::enorm ( const RV &rv ) :eEF ( rv ), mu ( rv.count() ),R ( rv.count() ),dim ( rv.count() ) {}; 
    479486 
    480487template<class sq_T> 
     
    490497}; 
    491498 
    492 template<class sq_T> 
    493 void enorm<sq_T>::tupdate ( double phi, mat &vbar, double nubar ) { 
    494         // 
    495 }; 
     499// template<class sq_T> 
     500// void enorm<sq_T>::tupdate ( double phi, mat &vbar, double nubar ) { 
     501//      // 
     502// }; 
    496503 
    497504template<class sq_T> 
     
    531538 
    532539template<class sq_T> 
    533 double enorm<sq_T>::evalpdflog ( const vec &val ) const { 
     540double enorm<sq_T>::evalpdflog_nn ( const vec &val ) const { 
    534541        // 1.83787706640935 = log(2pi) 
    535         return  -0.5* ( +R.invqform ( mu-val ) ) - lognc(); 
     542        return  -0.5* ( R.invqform ( mu-val ) );// - lognc(); 
    536543}; 
    537544 
     
    539546inline double enorm<sq_T>::lognc () const { 
    540547        // 1.83787706640935 = log(2pi) 
    541         return -0.5* ( R.cols() * 1.83787706640935 +R.logdet() ); 
    542 }; 
    543  
    544 template<class sq_T> 
    545 mlnorm<sq_T>::mlnorm ( RV &rv0,RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu ( epdf._mu() ) { 
     548        return 0.5* ( R.cols() * 1.83787706640935 +R.logdet() ); 
     549}; 
     550 
     551template<class sq_T> 
     552mlnorm<sq_T>::mlnorm ( const RV &rv0, const RV &rvc0 ) :mEF ( rv0,rvc0 ),epdf ( rv0 ),A ( rv0.count(),rv0.count() ),_mu ( epdf._mu() ) { 
    546553        ep =&epdf; 
    547554} 
    548555 
    549556template<class sq_T> 
    550 void mlnorm<sq_T>::set_parameters ( const mat &A0, const sq_T &R0 ) { 
     557void mlnorm<sq_T>::set_parameters ( const mat &A0, const vec &mu0, const sq_T &R0 ) { 
    551558        epdf.set_parameters ( zeros ( rv.count() ),R0 ); 
    552559        A = A0; 
     560        mu_const = mu0; 
    553561} 
    554562 
    555563template<class sq_T> 
    556 vec mlnorm<sq_T>::samplecond ( vec &cond, double &lik ) { 
     564vec mlnorm<sq_T>::samplecond (const vec &cond, double &lik ) { 
    557565        this->condition ( cond ); 
    558566        vec smp = epdf.sample(); 
     
    562570 
    563571template<class sq_T> 
    564 mat mlnorm<sq_T>::samplecond ( vec &cond, vec &lik, int n ) { 
     572mat mlnorm<sq_T>::samplecond (const vec &cond, vec &lik, int n ) { 
    565573        int i; 
    566574        int dim = rv.count(); 
     
    579587 
    580588template<class sq_T> 
    581 void mlnorm<sq_T>::condition ( vec &cond ) { 
    582         _mu = A*cond; 
     589void mlnorm<sq_T>::condition (const vec &cond ) { 
     590        _mu = A*cond + mu_const; 
    583591//R is already assigned; 
    584592} 
    585593 
     594template<class sq_T> 
     595enorm<sq_T>* enorm<sq_T>::marginal ( const RV &rvn ) { 
     596        ivec irvn = rvn.dataind ( rv ); 
     597 
     598        sq_T Rn ( R,irvn ); 
     599        enorm<sq_T>* tmp = new enorm<sq_T>( rvn ); 
     600        tmp->set_parameters ( mu ( irvn ), Rn ); 
     601        return tmp; 
     602} 
     603 
     604template<class sq_T> 
     605mlnorm<sq_T>* enorm<sq_T>::condition ( const RV &rvn ) { 
     606 
     607        RV rvc = rv.subt ( rvn ); 
     608        it_assert_debug ( ( rvc.count() +rvn.count() ==rv.count() ),"wrong rvn" ); 
     609        //Permutation vector of the new R 
     610        ivec irvn = rvn.dataind ( rv ); 
     611        ivec irvc = rvc.dataind ( rv ); 
     612        ivec perm=concat ( irvn , irvc ); 
     613        sq_T Rn ( R,perm ); 
     614 
     615        //fixme - could this be done in general for all sq_T? 
     616        mat S=R.to_mat(); 
     617        //fixme 
     618        int n=rvn.count()-1; 
     619        int end=R.rows()-1; 
     620        mat S11 = S.get ( 0,n, 0, n ); 
     621        mat S12 = S.get ( rvn.count(), end, 0, n ); 
     622        mat S22 = S.get ( rvn.count(), end, rvn.count(), end ); 
     623 
     624        vec mu1 = mu ( irvn ); 
     625        vec mu2 = mu ( irvc ); 
     626        mat A=S12*inv ( S22 ); 
     627        sq_T R_n ( S11 - A *S12.T() ); 
     628 
     629        mlnorm<sq_T>* tmp=new mlnorm<sq_T> ( rvn,rvc ); 
     630 
     631        tmp->set_parameters ( A,mu1-A*mu2,R_n ); 
     632        return tmp; 
     633} 
     634 
    586635/////////// 
    587636