root/bdm/estim/libPF.h @ 283

Revision 283, 7.0 kB (checked in by smidl, 15 years ago)

get rid of BMcond + adaptation in doprava/

  • 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;
41
42        //! which resampling method will be used
43        RESAMPLING_METHOD resmethod;
44
45        //! \name Options
46        //!@{
47
48        //! Log all samples
49        bool opt_L_smp;
50        //! Log all samples
51        bool opt_L_wei;
52        //!@}
53
54public:
55        //! \name Constructors
56        //!@{
57        PF ( ) :est(), _w ( est._w() ),_samples ( est._samples() ), opt_L_smp ( false ), opt_L_wei ( false ) {LIDs.set_size ( 5 );};
58        /*      PF ( mpdf *par0, mpdf *obs0, epdf *epdf0, int n0 ) :
59                                est ( ),_w ( est._w() ),_samples ( est._samples() ),opt_L_smp(false), opt_L_wei(false)
60                { set_parameters ( par0,obs0,n0 ); set_statistics ( ones ( n0 ),epdf0 ); };*/
61        void set_parameters ( mpdf *par0, mpdf *obs0, int n0, RESAMPLING_METHOD rm=SYSTEMATIC )
62        { par = par0; obs=obs0; n=n0; resmethod= rm;};
63        void set_statistics ( const vec w0, epdf *epdf0 ) {est.set_statistics ( w0,epdf0 );};
64        //!@}
65        //! Set posterior density by sampling from epdf0
66//      void set_est ( const epdf &epdf0 );
67        void set_options ( const string &opt ) {
68                BM::set_options(opt);
69                opt_L_wei= ( opt.find ( "logweights" ) !=string::npos );
70                opt_L_smp= ( opt.find ( "logsamples" ) !=string::npos );
71        }
72        void bayes ( const vec &dt );
73        //!access function
74        vec* __w() {return &_w;}
75};
76
77/*!
78\brief Marginalized Particle filter
79
80Trivial version: proposal = parameter evolution, observation model is not used. (it is assumed to be part of BM).
81*/
82
83template<class BM_T>
84class MPF : public PF {
85        Array<BM_T*> BMs;
86
87        //! internal class for MPDF providing composition of eEmp with external components
88
89class mpfepdf : public epdf  {
90        protected:
91                eEmp &E;
92                vec &_w;
93                Array<const epdf*> Coms;
94        public:
95                mpfepdf ( eEmp &E0 ) :
96                                epdf ( ), E ( E0 ),  _w ( E._w() ),
97                                Coms ( _w.length() ) {
98                };
99                //! read statistics from MPF
100                void read_statistics ( Array<BM_T*> &A ) {
101                        dim = E.dimension() +A ( 0 )->posterior().dimension();
102                        for ( int i=0; i<_w.length() ;i++ ) {Coms ( i ) = A ( i )->_e();}
103                }
104                //! needed in resampling
105                void set_elements ( int &i, double wi, const epdf* ep )
106                {_w ( i ) =wi; Coms ( i ) =ep;};
107
108                void set_parameters ( int n ) {
109                        E.set_parameters ( n, false );
110                        Coms.set_length ( n );
111                }
112                vec mean() const {
113                        // ugly
114                        vec pom=zeros ( Coms ( 0 )->dimension() );
115                        for ( int i=0; i<_w.length(); i++ ) {pom += Coms ( i )->mean() * _w ( i );}
116                        return concat ( E.mean(),pom );
117                }
118                vec variance() const {
119                        // ugly
120                        vec pom=zeros ( Coms ( 0 )->dimension() );
121                        vec pom2=zeros ( Coms ( 0 )->dimension() );
122                        for ( int i=0; i<_w.length(); i++ ) {
123                                pom += Coms ( i )->mean() * _w ( i );
124                                pom2 += ( Coms ( i )->variance() + pow ( Coms ( i )->mean(),2 ) ) * _w ( i );
125                        }
126                        return concat ( E.variance(),pom2-pow ( pom,2 ) );
127                }
128                void qbounds ( vec &lb, vec &ub, double perc=0.95 ) const {
129                        //bounds on particles
130                        vec lbp;
131                        vec ubp;
132                        E.qbounds ( lbp,ubp );
133
134                        //bounds on Components
135                        int dimC=Coms ( 0 )->dimension();
136                        int j;
137                        // temporary
138                        vec lbc(dimC);
139                        vec ubc(dimC);
140                        // minima and maxima
141                        vec Lbc(dimC);
142                        vec Ubc(dimC);
143                        Lbc = std::numeric_limits<double>::infinity();
144                        Ubc = -std::numeric_limits<double>::infinity();
145
146                        for ( int i=0;i<_w.length();i++ ) {
147                                // check Coms
148                                Coms ( i )->qbounds ( lbc,ubc );
149                                for ( j=0;j<dimC; j++ ) {
150                                        if ( lbc ( j ) <Lbc ( j ) ) {Lbc ( j ) =lbc ( j );}
151                                        if ( ubc ( j ) >Ubc ( j ) ) {Ubc ( j ) =ubc ( j );}
152                                }
153                        }
154                        lb=concat(lbp,Lbc);
155                        ub=concat(ubp,Ubc);
156                }
157
158                vec sample() const {it_error ( "Not implemented" );return 0;}
159
160                double evallog ( const vec &val ) const {it_error ( "not implemented" ); return 0.0;}
161        };
162
163        //! Density joining PF.est with conditional parts
164        mpfepdf jest;
165
166        //! Log means of BMs
167        bool opt_L_mea;
168
169public:
170        //! Default constructor.
171        MPF () : PF (), jest ( est ) {};
172        void set_parameters ( mpdf *par0, mpdf *obs0, int n0, RESAMPLING_METHOD rm=SYSTEMATIC ) {
173                PF::set_parameters ( par0, obs0, n0, rm );
174                jest.set_parameters ( n0 );//duplication of rm
175                BMs.set_length ( n0 );
176        }
177        void set_statistics ( epdf *epdf0, const BM_T* BMcond0 ) {
178
179                PF::set_statistics ( ones ( n ) /n, epdf0 );
180                // copy
181                for ( int i=0;i<n;i++ ) { BMs ( i ) = new BM_T ( *BMcond0 ); BMs ( i )->condition ( _samples ( i ) );}
182
183                jest.read_statistics ( BMs );
184                //options
185        };
186
187        void bayes ( const vec &dt );
188        const epdf& posterior() const {return jest;}
189        const epdf* _e() const {return &jest;} //Fixme: is it useful?
190        //! Set postrior of \c rvc to samples from epdf0. Statistics of BMs are not re-computed! Use only for initialization!
191        /*      void set_est ( const epdf& epdf0 ) {
192                        PF::set_est ( epdf0 );  // sample params in condition
193                        // copy conditions to BMs
194
195                        for ( int i=0;i<n;i++ ) {BMs(i)->condition ( _samples ( i ) );}
196                }*/
197        void set_options ( const string &opt ) {
198                PF::set_options ( opt );
199                opt_L_mea = ( opt.find ( "logmeans" ) !=string::npos );
200        }
201
202        //!Access function
203        BM* _BM ( int i ) {return BMs ( i );}
204};
205
206template<class BM_T>
207void MPF<BM_T>::bayes ( const vec &dt ) {
208        int i;
209        vec lls ( n );
210        vec llsP ( n );
211        ivec ind;
212        double mlls=-std::numeric_limits<double>::infinity();
213
214#pragma omp parallel for
215        for ( i=0;i<n;i++ ) {
216                //generate new samples from paramater evolution model;
217                _samples ( i ) = par->samplecond ( _samples ( i ) );
218                llsP ( i ) = par->_e()->evallog ( _samples ( i ) );
219                BMs ( i )->condition ( _samples ( i ) );
220                BMs ( i )->bayes ( dt );
221                lls ( i ) = BMs ( i )->_ll(); // lls above is also in proposal her must be lls(i) =, not +=!!
222                if ( lls ( i ) >mlls ) mlls=lls ( i ); //find maximum likelihood (for numerical stability)
223        }
224
225        double sum_w=0.0;
226        // compute weights
227#pragma omp parallel for
228        for ( i=0;i<n;i++ ) {
229                _w ( i ) *= exp ( lls ( i ) - mlls ); // multiply w by likelihood
230                sum_w+=_w ( i );
231        }
232
233        if ( sum_w  >0.0 ) {
234                _w /=sum_w; //?
235        }
236        else {
237                cout<<"sum(w)==0"<<endl;
238        }
239
240
241        double eff = 1.0/ ( _w*_w );
242        if ( eff < ( 0.3*n ) ) {
243                ind = est.resample ( resmethod );
244                // Resample Bms!
245
246#pragma omp parallel for
247                for ( i=0;i<n;i++ ) {
248                        if ( ind ( i ) !=i ) {//replace the current Bm by a new one
249                                //fixme this would require new assignment operator
250                                // *Bms[i] = *Bms[ind ( i ) ];
251
252                                // poor-man's solution: replicate constructor here
253                                // copied from MPF::MPF
254                                delete BMs ( i );
255                                BMs ( i ) = new BM_T ( *BMs ( ind ( i ) ) ); //copy constructor
256                                const epdf& pom=BMs ( i )->posterior();
257                                jest.set_elements ( i,1.0/n,&pom );
258                        }
259                };
260                cout << '.';
261        }
262}
263
264}
265#endif // KF_H
266
Note: See TracBrowser for help on using the browser.