00001 #ifndef INDII_ML_FILTER_PARTICLEFILTER_HPP
00002 #define INDII_ML_FILTER_PARTICLEFILTER_HPP
00003
00004 #include "../aux/DiracMixturePdf.hpp"
00005 #include "../aux/parallel.hpp"
00006
00007 #include "Filter.hpp"
00008 #include "ParticleResampler.hpp"
00009 #include "ParticleFilterModel.hpp"
00010 #include "StratifiedParticleResampler.hpp"
00011
00012 namespace indii {
00013 namespace ml {
00014 namespace filter {
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 template<class T = unsigned int>
00032 class ParticleFilter : public Filter<T,indii::ml::aux::DiracMixturePdf> {
00033 public:
00034
00035
00036
00037
00038
00039
00040
00041 ParticleFilter(ParticleFilterModel<T>* model,
00042 indii::ml::aux::DiracMixturePdf& p_x0);
00043
00044
00045
00046
00047 virtual ~ParticleFilter();
00048
00049
00050
00051
00052
00053
00054 virtual ParticleFilterModel<T>* getModel();
00055
00056
00057
00058
00059
00060
00061
00062 virtual void filter(const T tnp1);
00063
00064
00065
00066
00067
00068
00069 virtual void filter(const indii::ml::aux::vector& ytn);
00070
00071 virtual void filter(const T tnp1, const indii::ml::aux::vector& ytnp1);
00072
00073 virtual indii::ml::aux::DiracMixturePdf measure();
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 void resample(ParticleResampler* resampler);
00090
00091 private:
00092
00093
00094
00095 ParticleFilterModel<T>* model;
00096
00097 };
00098
00099 }
00100 }
00101 }
00102
00103 #include <assert.h>
00104 #include <vector>
00105
00106 template <class T>
00107 indii::ml::filter::ParticleFilter<T>::ParticleFilter(
00108 ParticleFilterModel<T>* model,
00109 indii::ml::aux::DiracMixturePdf& p_x0) :
00110 Filter<T,indii::ml::aux::DiracMixturePdf>(p_x0), model(model) {
00111
00112 }
00113
00114 template <class T>
00115 indii::ml::filter::ParticleFilter<T>::~ParticleFilter() {
00116
00117 }
00118
00119 template <class T>
00120 indii::ml::filter::ParticleFilterModel<T>*
00121 indii::ml::filter::ParticleFilter<T>::getModel() {
00122 return model;
00123 }
00124
00125 template <class T>
00126 void indii::ml::filter::ParticleFilter<T>::filter(const T tnp1) {
00127 namespace aux = indii::ml::aux;
00128
00129
00130 assert (tnp1 >= this->tn);
00131
00132 aux::DiracMixturePdf p_xtnp1_ytnp1(model->getStateSize());
00133 aux::vector x(model->getStateSize());
00134 double w;
00135 T delta = tnp1 - this->tn;
00136 unsigned int i;
00137
00138
00139 for (i = 0; i < this->p_xtn_ytn.getSize(); i++) {
00140 noalias(x) = model->transition(this->p_xtn_ytn.get(i), this->tn, delta);
00141 w = this->p_xtn_ytn.getWeight(i);
00142
00143 p_xtnp1_ytnp1.add(x, w);
00144 }
00145
00146
00147 this->tn = tnp1;
00148 this->p_xtn_ytn = p_xtnp1_ytnp1;
00149 }
00150
00151 template <class T>
00152 void indii::ml::filter::ParticleFilter<T>::filter(const aux::vector& ytn) {
00153 aux::vector x(model->getStateSize());
00154 aux::vector ws(this->p_xtn_ytn.getSize());
00155 unsigned int i;
00156
00157
00158 for (i = 0; i < this->p_xtn_ytn.getSize(); i++) {
00159 noalias(x) = this->p_xtn_ytn.get(i);
00160 ws(i) = this->p_xtn_ytn.getWeight(i) * model->weight(x, ytn);
00161 }
00162
00163
00164 this->p_xtn_ytn.setWeights(ws);
00165 }
00166
00167 template <class T>
00168 void indii::ml::filter::ParticleFilter<T>::filter(const T tnp1,
00169 const aux::vector& ytnp1) {
00170 namespace aux = indii::ml::aux;
00171
00172
00173 assert (tnp1 >= this->tn);
00174
00175 aux::DiracMixturePdf p_xtnp1_ytnp1(model->getStateSize());
00176 aux::vector x(model->getStateSize());
00177 double w;
00178 T delta = tnp1 - this->tn;
00179 unsigned int i;
00180
00181
00182 for (i = 0; i < this->p_xtn_ytn.getSize(); i++) {
00183 noalias(x) = model->transition(this->p_xtn_ytn.get(i), this->tn, delta);
00184 w = this->p_xtn_ytn.getWeight(i) * model->weight(x, ytnp1);
00185
00186 p_xtnp1_ytnp1.add(x, w);
00187 }
00188
00189
00190 this->tn = tnp1;
00191 this->p_xtn_ytn = p_xtnp1_ytnp1;
00192 }
00193
00194 template <class T>
00195 indii::ml::aux::DiracMixturePdf
00196 indii::ml::filter::ParticleFilter<T>::measure() {
00197 namespace aux = indii::ml::aux;
00198
00199 unsigned int i;
00200 StratifiedParticleResampler resampler;
00201 aux::DiracMixturePdf resampled(resampler.resample(
00202 this->getFilteredState()));
00203
00204 aux::DiracMixturePdf p_ytn_xtn(model->getMeasurementSize());
00205 for (i = 0; i < resampled.getSize(); i++) {
00206 p_ytn_xtn.add(model->measure(resampled.get(i)));
00207 }
00208
00209 return p_ytn_xtn;
00210 }
00211
00212 template <class T>
00213 void indii::ml::filter::ParticleFilter<T>::resample(
00214 ParticleResampler* resampler) {
00215 indii::ml::aux::DiracMixturePdf resampled(resampler->resample(
00216 this->getFilteredState()));
00217 this->setFilteredState(resampled);
00218 }
00219
00220 #endif
00221