source: pacpusframework/trunk/include/Pacpus/PacpusTools/filtering/particle_filtering.hpp@ 64

Last change on this file since 64 was 64, checked in by Marek Kurdej, 11 years ago

Modified property: added svn:keywords=Id.

  • Property svn:keywords set to Id
File size: 17.7 KB
Line 
1#ifndef __PARTICLE_FILTERING_BASE__
2#define __PARTICLE_FILTERING_BASE__
3
4#include "bayes_filtering.hpp"
5#include "../math/ublas.hpp"
6#include "../math/rng.hpp"
7#include "../math/distributions.hpp"
8
9
10namespace filter{
11namespace particle {
12
13 using namespace math;
14 using namespace ublas;
15 using namespace rng;
16 using namespace distributions;
17
18
19 /*!
20 * \class Particle
21 * \brief This class describe a particle \n
22 * A particle is constituted by : 1) a state vector and 2) importance weight \n
23 */
24 class Particle {
25 public :
26 /*!
27 * \brief Constructor
28 * \param state_size : the size of the state vector
29 * \param weight_ : the initial weight of the particle
30 */
31 Particle(const size_t state_size, const double & weight_){
32 X=ZeroVector(state_size);
33 weight=weight_;
34 }
35
36 Vector X; /*!< state vector */
37
38 double weight; /*!< particle weight */
39
40 };
41
42 /*! \class ParticleSet
43 * \brief This class describe a set of particles \n
44 * A set of particle is reprented by a vector of particles \n
45 * somes methods can be applied to the set of particles like : \n
46 * estimate computation, resampling scheme or normalization method \n
47 */
48
49 template<class P=Particle> class ParticleSet {
50 public :
51
52 std::vector<P> particles; /*!< vector of particles */
53
54
55 std::vector<P> particles_; /*!< temporary vector of particles used in resample scheme */
56
57
58 /*!
59 * \brief Allocate the set of paticles
60 * \param nparticle : number of particles
61 */
62 void Allocator(const size_t &nparticle);
63
64 /*!
65 * \brief Resample the set of particles \n
66 * \param threshold : threshold parameter \n
67 * The resampling scheme is the reasmpling scheme proposed by Kitawaga \n
68 * This can be overloaded to use an another resampling scheme \n
69 */
70 virtual void Resample(const double & threshold=1.0);
71
72 /*!
73 * \brief Compute the number of effective samples in the particle set
74 * \return number of effective samples
75 */
76 double Ness();
77
78 /*!
79 * \brief Get the number of particles
80 * \return number of particles
81 */
82 size_t ParticlesNo(){ return particles.size(); }
83
84 /*!
85 * \brief Compute the estimate
86 * \return a vector double describing the estimate
87 */
88 Vector Estimate ();
89
90 /*!
91 * \brief Normalize the weights of each particles
92 */
93 void NormalizeWeights();
94
95 /*!
96 * \brief Destructor
97 */
98 virtual ~ParticleSet(){};
99
100 protected :
101
102 /*!
103 * \brief Compute the cumulative sum of the weight of each particles
104 * \return a vector of double describing this cumulative sum
105 */
106 std::vector<double> WeightCumSum();
107
108 /*!
109 * \brief Create the a random cumulative sum
110 * \return a vector of double describing this cumulative sum
111 */
112 std::vector<double> RandomCumSum();
113
114 };
115
116
117 //Particle set memeber functions
118 template<class P> void ParticleSet<P>::Allocator(const size_t &nparticles){
119 particles.resize(nparticles);
120 particles_.resize(nparticles);
121 }
122
123 template<class P> double ParticleSet<P>::Ness(){
124 double ness =0;
125 for(typename std::vector<P>::iterator I=particles.begin();I!=particles.end();I++)
126 ness+=(*I).weight*(*I).weight;
127
128 if(ness==0)throw filter_error("In particle filter :: number effective sample computation -> ness is equal to infinity");
129
130 return 1/ness;
131 }
132
133
134 template<class P> std::vector<double> ParticleSet<P>::WeightCumSum(){
135 double sum=0;
136 std::vector<double> cumsum(particles.size());
137 for(size_t i=0;i<particles.size();i++){
138 sum+=particles[i].weight;
139 cumsum[i]=sum;
140 }
141 return cumsum;
142 }
143
144 template<class P> void ParticleSet<P>::NormalizeWeights(){
145
146 double sum=0;
147 for(typename std::vector<P>::iterator I=particles.begin();I!=particles.end();I++)
148 sum+=(*I).weight;
149
150
151 if(sum==0) throw filter_error("In particle filter :: normalization of weight -> weight sum is equal to 0");
152
153 for(typename std::vector<P>::iterator I=particles.begin();I!=particles.end();I++)
154 (*I).weight=(*I).weight/sum;
155
156 }
157
158 template<class P> std::vector<double> ParticleSet<P>::RandomCumSum(){
159 double sum=0;
160 std::vector<double> cumsum(particles.size());
161 uniform_rng UD;
162 for(size_t i=0;i<particles.size();i++){
163 sum+=UD();
164 cumsum[i]=sum;
165 }
166
167 //normalization
168 for(size_t i=0;i<particles.size();i++)cumsum[i]=cumsum[i]/sum;
169
170 return cumsum;
171 }
172
173
174 template<class P> void ParticleSet<P>::Resample(const double & threshold){
175 size_t N=ParticlesNo();
176 if(Ness()<=N*threshold){
177 // resample method by Carpenter
178 std::vector<double> Q=WeightCumSum();
179 std::vector<double> T=RandomCumSum();
180
181 // select the best particle
182 std::vector <size_t> ind(N);
183 unsigned int j=0;
184 for(unsigned int i=0; i <N; i++){
185 do{
186 if(T[i] < Q[j]){ind[i] = j;break;}
187 j++;
188 }while(j<N);
189 }
190
191 // build the new particle set
192 for(unsigned int i=0; i <N; i++){
193 particles_[i]=particles[ind[i]];
194 particles_[i].weight=1.0/static_cast<double>(N);
195 }
196
197 // swap the particle set
198 particles.swap(particles_);
199 }
200 }
201
202
203
204 template<class P> Vector ParticleSet<P>::Estimate(){
205 Vector estimate = ZeroVector(particles[0]->X.size());
206 for(typename std::vector<P>::iterator I=particles.begin();I!=particles.end();I++)
207 estimate+=(*I).X*(*I).weight;
208 return estimate;
209 }
210
211
212 /*!
213 * \class DynamicEquation
214 * \brief This class describe a basic dynamic equation for particle filtering \n
215 * where : class S is a set particle \n
216 * : class I is a particle \n
217 * : class D is a random generator used to draw input data \n
218 */
219 template <class D, template <class> class S=ParticleSet, class P=Particle> class DynamicEquation:public BayesDynamicEquation< S<P>, P >{
220 public :
221
222 /*!
223 * \brief virtual method where matrices of state system must be allocated
224 * \param state_size : the size of the state vector of each particle
225 * \param data_size : the size of the input vector
226 */
227 virtual void Allocator(const size_t &state_size,const size_t &data_size)=0;
228
229 /*!
230 * \brief virtual method where parameters of the dynamic equation must be evaluated
231 * \param s : set of particles at time k-1
232 *
233 */
234 virtual void EvaluateParameters( P *s)=0;
235
236 /*!
237 * \brief virtual method where the a priori state vector must be computed
238 * \param in : the set of particles at time k-1
239 * \param out : the set of particles at time k
240 */
241 virtual void Predict(S<P> *in, S<P> *out)=0;
242
243
244 /*!
245 * \brief Destructor
246 */
247 virtual ~DynamicEquation(){}
248
249 /*!
250 * \brief Get/Set random generator used to draw input random U
251 */
252 D & URNG(){return _URNG;}
253
254 protected :
255
256 D _URNG; /*!< Random generator used to drawing input data*/
257
258 Vector _Urand; /*!< Vector where random input data are stored */
259
260 };
261
262
263
264
265 /*!
266 * \class LinearDynamicEquation
267 * \brief This class describe a linear dynamic equation \n
268 * X(k+1)(i) =A*X(k)(i)+B*U(k)(i) \n
269 * X(.)(i) = the state of the particle i \n
270 * A = state matrix \n
271 * B = entrie matrix \n
272 * U = input random vector \n
273 */
274 template <class D,template <class> class S=ParticleSet, class P=Particle> class LinearDynamicEquation : public DynamicEquation<D,S,P>{
275 public :
276 /*!
277 * \brief virtual method where matrices of state system must be allocated
278 * \param state_size : the size of the state vector of each particle
279 * \param data_size : the size of the input vector
280 */
281 void Allocator(const size_t &state_size,const size_t &data_size);
282
283 /*!
284 * \brief virtual method where parameters of the dynamic equation must be evaluated
285 * \param s : set of particles at time k-1
286 */
287 virtual void EvaluateParameters(P *s)=0;
288
289 /*!
290 * \brief virtual method where the a priori state vector must be computed
291 * \param in : the set of particles at time k-1
292 * \param out : the set of particles at time k
293 */
294 virtual void Predict(S<P> *in,S<P> *out);
295
296 /*!
297 * \brief Destructor
298 */
299 virtual ~LinearDynamicEquation(){}
300
301 /*!
302 * \brief Get/Set a constant data in A matrix
303 */
304 double & A(const int &row, const int &column){return _A(row,column);}
305
306 /*!
307 * \brief Get/Set a constant data in B matrix
308 */
309 double & B(const int &row, const int &column){return _B(row,column);}
310
311 protected :
312
313 Matrix _A; /*!< A matrix */
314
315 Matrix _B; /*!< A matrix */
316
317 };
318
319
320 // Particle linear dynamic equation member functions
321 template <class D, template <class> class S,class P> void LinearDynamicEquation<D,S,P>::Allocator(const size_t &state_size,const size_t &data_size){
322 DynamicEquation<D,S,P>::_Urand=ZeroVector(data_size);
323 _A=ZeroMatrix(state_size,state_size);
324 _B=ZeroMatrix(state_size,data_size);
325 }
326
327
328 template <class D, template <class> class S,class P> void LinearDynamicEquation<D,S,P>::Predict(S<P> *in,S<P> *out){
329
330 for(size_t i=0;i<in->particles.size();i++){
331 EvaluateParameters(&in->particles[i]);
332
333 out->particles[i]->X=_A*in->particles[i]->X+_B*DynamicEquation<D,S,P>::_Urand;
334 out->particles[i]->weight=in->particles[i]->weight;
335 }
336 }
337
338
339 /*!
340 * \class NonLinearDynamicEquation
341 * \brief This class describe a linear dynamic equation
342 * \n
343 * X(k+1)(i) =f(X(k)(i)+U(k)(i)) \n
344 * X(.)(i) = the state of the particle i \n
345 * A = state matrix \n
346 * B = entrie matrix \n
347 * U = input random vector \n
348 */
349 template <class D, template <class> class S,class P> class NonLinearDynamicEquation : public DynamicEquation<D,S,P>{
350 public :
351 /*!
352 * \brief virtual method where matrices of state system must be allocated
353 * \param state_size : the size of the state vector of each particle
354 * \param data_size : the size of the input vector
355 */
356 void Allocator(const size_t &state_size,const size_t &data_size);
357
358 /*!
359 * \brief virtual method where parameters of the dynamic equation must be evaluated
360 * \param s : set of particles at time k-1
361 * f=
362 */
363 virtual void EvaluateParameters(P *s)=0;
364
365 /*!
366 * \brief virtual method where the a priori state vector must be computed
367 * \param in : the set of particles at time k-1
368 * \param out : the set of particles at time k
369 */
370 virtual void Predict(S<P> *in,S<P> *out);
371
372 /*!
373 * \brief Destructor
374 */
375 virtual ~NonLinearDynamicEquation(){}
376
377
378 protected:
379
380 Vector _f; /*!< Matrix f where result of (f(X,U)) is stored */
381
382 };
383
384 // Particle non linear dynamic equation member functions
385 template <class D,template <class> class S,class P> void NonLinearDynamicEquation<D,S,P>::Allocator(const size_t &state_size,const size_t &data_size){
386 DynamicEquation<D,S,P>::_Urand=ZeroVector(data_size);
387 _f=ZeroVector(state_size);
388 }
389
390
391
392 template <class D,template <class> class S,class P> void NonLinearDynamicEquation<D,S,P>::Predict(S<P> *in,S<P> *out){
393 for(size_t i=0;i<in->particles.size();i++){
394 EvaluateParameters(&in->particles[i]);
395
396 out->particles[i].X=_f;
397 out->particles[i].weight=in->particles[i].weight;
398
399 }
400 }
401
402 /*!
403 * \class MeasureEquation
404 * \brief This clas describe a basic measure equation particle filtering
405 * \n
406 * where : class S is a set particle \n
407 * : class I is a particle \n
408 * : class D is the distribution of probability of observation data \n
409 */
410 template <class D , template <class> class S=ParticleSet, class P=Particle> class MeasureEquation: public BayesMeasureEquation< S<P>, P >{
411 public :
412
413 /*!
414 * \brief virtual method where matrices of state system must be allocated
415 * \param state_size : the size of the state vector of each particle
416 * \param data_size : the size of the input vector
417 */
418 virtual void Allocator(const size_t &state_size,const size_t &data_size)=0;
419
420
421 /*!
422 * \brief virtual method where parameters of the measure equation must be evaluated
423 * \param s : set of particles at time k
424 */
425 virtual void EvaluateParameters(P *s)=0;
426
427 /*!
428 * \brief virtual method where the a posteriori state vector must be computed
429 * \param in : the a priori set of particles at time k
430 * \param out : the a posteriori set of particles at time k
431 */
432 virtual void Update(S<P> *in,S<P> *out)=0;
433
434 /*!
435 * \brief Destructor
436 */
437 virtual ~MeasureEquation(){};
438
439 /*!
440 * \brief Get/Set the distribution of probability of data observation Z
441 */
442 D & ZDistribution(){return _ZDistribution;}
443
444 protected :
445
446 D _ZDistribution; /*!< The distribution of probability of observation data Z*/
447 };
448
449
450
451 /*!
452 * \class LinearMeasureEquation
453 * \brief This class describe a linear measure equation
454 * \n
455 * X(k)(i)=H*Z(k) \n
456 * Z(k) = observation data \n
457 * => weigth update \n
458 * w(k+1)(i)=p(Z|HX(i))w(k)(i) \n
459 * w(.)(i)= weight of particle i \n
460 */
461 template <class D, template <class> class S=ParticleSet, class P=Particle> class LinearMeasureEquation : public MeasureEquation< D,S,P >{
462 public :
463 /*!
464 * \brief virtual method where matrices of state system must be allocated
465 * \param state_size : the size of the state vector of each particle
466 * \param data_size : the size of the input vector
467 */
468 void Allocator(const size_t &state_size,const size_t &data_size);
469
470
471 /*!
472 * \brief virtual method where parameters of the measure equation must be evaluated
473 * \param s : set of particles at time k
474 */
475 virtual void EvaluateParameters(P *s)=0;
476
477 /*!
478 * \brief virtual method where the a posteriori state vector must be computed
479 * \param in : the a priori set of particles at time k
480 * \param out : the a posteriori set of particles at time k
481 */
482 virtual void Update(S<P> *in,S<P> *out);
483
484 /*!
485 * \brief Destructor
486 */
487 virtual ~LinearMeasureEquation(){}
488
489 /*!
490 * \brief Get/Set a constant data in observation matrix H
491 */
492 double & H(int row, int column){return _H(row,column);}
493
494 protected:
495
496 Matrix _H; /*!< Observation matrix */
497 };
498
499
500 // Particle linear measure equation member functions
501 template <class D,template <class> class S, class P> void LinearMeasureEquation<D,S,P>::Allocator(const size_t &state_size,const size_t &data_size){
502 _H=ZeroMatrix(data_size,state_size);
503 }
504
505 template <class D,template <class> class S, class P> void LinearMeasureEquation<D,S,P>::Update(S<P> *in,S<P> *out){
506 for(size_t i=0;i<in->particles.size();i++){
507 EvaluateParameters(&in->particles[i]);
508
509 out->particles[i].weight=pdf(MeasureEquation<D,S,P>::_ZDistribution, _H*in->particles[i].X)*in->particles[i].weight;
510
511 }
512 out->NormalizeWeights();
513 }
514
515
516
517 /*!
518 * \class NonLinearMeasureEquation
519 * \brief This class describe a non linear measure equation
520 * \n
521 * Z(k)=h(X)(i) \n
522 * Z = observation data \n
523 * => weigth update \n
524 * w(k+1)(i)=p(Z|h(X(k)(i)))w(k)(i) \n
525 * w(.)(i)= weight of particle i \n
526 */
527 template <class D,template <class> class S=ParticleSet, class P=Particle> class NonLinearMeasureEquation : public MeasureEquation<D,S,P>{
528 public :
529 /*!
530 * \brief virtual method where matrices of state system must be allocated
531 * \param state_size : the size of the state vector of each particle
532 * \param data_size : the size of the input vector
533 */
534 void Allocator(const size_t &state_size,const size_t &data_size);
535
536 /*!
537 * \brief virtual method where parameters of the measure equation must be evaluated
538 * \param s : set of particles at time k
539 * h=
540 * H=
541 */
542 virtual void EvaluateParameters(P *s )=0;
543
544 /*!
545 * \brief virtual method where the a posteriori state vector must be computed
546 * \param in : the a priori set of particles at time k
547 * \param out : the a posteriori set of particles at time k
548 */
549 virtual void Update(S<P> *in,S<P> *out);
550
551 /*!
552 * \brief Destructor
553 */
554 virtual ~NonLinearMeasureEquation(){}
555
556 protected :
557
558 Vector _h; /*!< vector where h(X) is stored */
559
560 };
561
562 // Particle non linear measure equation member functions
563 template <class D,template <class> class S, class P> void NonLinearMeasureEquation<D,S,P>::Allocator(const size_t &state_size,const size_t &data_size){
564 _h=ZeroVector(data_size);
565 }
566
567
568 template <class D,template <class> class S, class P> void NonLinearMeasureEquation<D,S,P>::Update(S<P> *in,S<P> *out){
569
570 for(size_t i=0;i<in->particles.size();i++){
571 EvaluateParameters(&in->particles[i]);
572
573 out->particles[i].weight=pdf(MeasureEquation<D,S,P>::_ZDistribution,_h)*in->particles[i].weight;
574
575 }
576
577 out->NormalizeWeights();
578 }
579
580
581};
582};
583#endif
Note: See TracBrowser for help on using the repository browser.