root/bdm/estim/libPF.h @ 262

Revision 262, 5.0 kB (checked in by smidl, 15 years ago)

cleanup of include files

  • Property svn:eol-style set to native
Line 
1/*!
2  \file
3  \brief Bayesian Filtering using stochastic sampling (Particle Filters)
4  \author Vaclav Smidl.
5
6  -----------------------------------
7  BDM++ - C++ library for Bayesian Decision Making under Uncertainty
8
9  Using IT++ for numerical operations
10  -----------------------------------
11*/
12
13#ifndef PF_H
14#define PF_H
15
16
17#include "../stat/libEF.h"
18
19namespace bdm{
20
21/*!
22* \brief Trivial particle filter with proposal density equal to parameter evolution model.
23
24Posterior density is represented by a weighted empirical density (\c eEmp ).
25*/
26
27class PF : public BM {
28protected:
29        //!number of particles;
30        int n;
31        //!posterior density
32        eEmp est;
33        //! pointer into \c eEmp
34        vec &_w;
35        //! pointer into \c eEmp
36        Array<vec> &_samples;
37        //! Parameter evolution model
38        mpdf &par;
39        //! Observation model
40        mpdf &obs;
41public:
42        //! Default constructor
43        PF ( const RV &rv0, mpdf &par0,  mpdf &obs0, int n0 ) :BM ( rv0 ),
44                        n ( n0 ),est ( rv0,n ),_w ( est._w() ),_samples ( est._samples() ),
45                        par ( par0 ), obs ( obs0 ) {};
46
47        //! Set posterior density by sampling from epdf0
48        void set_est ( const epdf &epdf0 );
49        void bayes ( const vec &dt );
50        //!access function
51        vec* __w(){return &_w;}
52};
53
54/*!
55\brief Marginalized Particle filter
56
57Trivial version: proposal = parameter evolution, observation model is not used. (it is assumed to be part of BM).
58*/
59
60template<class BM_T>
61
62class MPF : public PF {
63        BM_T* Bms[10000];
64
65        //! internal class for MPDF providing composition of eEmp with external components
66
67class mpfepdf : public epdf  {
68        protected:
69                eEmp &E;
70                vec &_w;
71                Array<const epdf*> Coms;
72        public:
73                mpfepdf ( eEmp &E0, const RV &rvc ) :
74                                epdf ( RV( ) ), E ( E0 ),  _w ( E._w() ),
75                                Coms ( _w.length() ) {
76                        rv.add ( E._rv() );
77                        rv.add ( rvc );
78                };
79
80                void set_elements ( int &i, double wi, const epdf* ep )
81                {_w ( i ) =wi; Coms ( i ) =ep;};
82
83                vec mean() const {
84                        // ugly
85                        vec pom=zeros ( ( Coms ( 0 )->_rv() ).count() );
86                        for ( int i=0; i<_w.length(); i++ ) {pom += Coms ( i )->mean() * _w ( i );}
87                        return concat ( E.mean(),pom );
88                }
89                vec variance() const {
90                        // ugly
91                        vec pom=zeros ( ( Coms ( 0 )->_rv() ).count() );
92                        vec pom2=zeros ( ( Coms ( 0 )->_rv() ).count() );
93                        for ( int i=0; i<_w.length(); i++ ) {
94                                pom += Coms ( i )->mean() * _w ( i );
95                                pom2 += (Coms ( i )->variance() + pow(Coms(i)->mean(),2)) * _w ( i );}
96                        return concat ( E.variance(),pom2-pow(pom,2) );
97                }
98
99                vec sample() const {it_error ( "Not implemented" );return 0;}
100
101                double evallog ( const vec &val ) const {it_error ( "not implemented" ); return 0.0;}
102        };
103
104        //! estimate joining PF.est with conditional
105        mpfepdf jest;
106
107public:
108        //! Default constructor.
109        MPF ( const RV &rvlin, const RV &rvpf, mpdf &par0, mpdf &obs0, int n, const BM_T &BMcond0 ) : PF ( rvpf ,par0,obs0,n ),jest ( est,rvlin ) {
110                //
111                //TODO test if rv and BMcond.rv are compatible.
112                rv.add ( rvlin );
113                //
114
115                if ( n>10000 ) {it_error ( "increase 10000 here!" );}
116
117                for ( int i=0;i<n;i++ ) {
118                        Bms[i] = new BM_T ( BMcond0 ); //copy constructor
119                        const epdf& pom=Bms[i]->_epdf();
120                        jest.set_elements ( i,1.0/n,&pom );
121                }
122        };
123
124        ~MPF() {
125        }
126
127        void bayes ( const vec &dt );
128        const epdf& _epdf() const {return jest;}
129        const epdf* _e() const {return &jest;} //Fixme: is it useful?
130        //! Set postrior of \c rvc to samples from epdf0. Statistics of Bms are not re-computed! Use only for initialization!
131        void set_est ( const epdf& epdf0 ) {
132                PF::set_est ( epdf0 );  // sample params in condition
133                // copy conditions to BMs
134
135                for ( int i=0;i<n;i++ ) {Bms[i]->condition ( _samples ( i ) );}
136        }
137
138        //!Access function
139        BM* _BM(int i){return Bms[i];}
140};
141
142template<class BM_T>
143void MPF<BM_T>::bayes ( const vec &dt ) {
144        int i;
145        vec lls ( n );
146        vec llsP ( n );
147        ivec ind;
148        double mlls=-std::numeric_limits<double>::infinity();
149
150        #pragma omp parallel for
151        for ( i=0;i<n;i++ ) {   
152                //generate new samples from paramater evolution model;
153                _samples ( i ) = par.samplecond ( _samples ( i ), llsP ( i ) );
154                Bms[i]->condition ( _samples ( i ) );
155                Bms[i]->bayes ( dt );
156                lls ( i ) = Bms[i]->_ll(); // lls above is also in proposal her must be lls(i) =, not +=!!
157                if ( lls ( i ) >mlls ) mlls=lls ( i ); //find maximum likelihood (for numerical stability)
158        }
159
160        double sum_w=0.0;
161        // compute weights
162        #pragma omp parallel for
163        for ( i=0;i<n;i++ ) {
164                _w ( i ) *= exp ( lls ( i ) - mlls ); // multiply w by likelihood
165                sum_w+=_w(i);
166        }
167
168        if ( sum_w  >0.0 ) {
169                _w /=sum_w; //?
170        } else {
171                cout<<"sum(w)==0"<<endl;
172        }
173
174
175        double eff = 1.0/ ( _w*_w );
176        if ( eff < ( 0.3*n ) ) {
177                ind = est.resample();
178                // Resample Bms!
179
180                #pragma omp parallel for
181                for ( i=0;i<n;i++ ) {
182                        if ( ind ( i ) !=i ) {//replace the current Bm by a new one
183                                //fixme this would require new assignment operator
184                                // *Bms[i] = *Bms[ind ( i ) ];
185
186                                // poor-man's solution: replicate constructor here
187                                // copied from MPF::MPF
188                                delete Bms[i];
189                                Bms[i] = new BM_T ( *Bms[ind ( i ) ] ); //copy constructor
190                                const epdf& pom=Bms[i]->_epdf();
191                                jest.set_elements ( i,1.0/n,&pom );
192                        }
193                };
194                cout << '.';
195        }
196}
197
198}
199#endif // KF_H
200
Note: See TracBrowser for help on using the browser.