root/bdm/estim/libPF.h @ 254

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

create namespace bdm

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