00001 #ifndef INDII_ML_FILTER_PARTICLESMOOTHER_HPP
00002 #define INDII_ML_FILTER_PARTICLESMOOTHER_HPP
00003
00004 #include "Smoother.hpp"
00005 #include "ParticleResampler.hpp"
00006 #include "ParticleSmootherModel.hpp"
00007
00008 namespace indii {
00009 namespace ml {
00010 namespace filter {
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 template <class T = unsigned int>
00078 class ParticleSmoother : public Smoother<T,indii::ml::aux::DiracMixturePdf> {
00079 public:
00080
00081
00082
00083
00084
00085
00086
00087
00088 ParticleSmoother(ParticleSmootherModel<T>* model,
00089 const T tT, const indii::ml::aux::DiracMixturePdf& p_xT);
00090
00091
00092
00093
00094 virtual ~ParticleSmoother();
00095
00096
00097
00098
00099
00100
00101 virtual ParticleSmootherModel<T>* getModel();
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 virtual void smooth(const T tn,
00113 const indii::ml::aux::DiracMixturePdf& p_xtn_ytn);
00114
00115 virtual indii::ml::aux::DiracMixturePdf smoothedMeasure();
00116
00117
00118
00119
00120
00121
00122 void smoothedResample(ParticleResampler* resampler);
00123
00124 private:
00125
00126
00127
00128 ParticleSmootherModel<T>* model;
00129
00130 };
00131
00132 }
00133 }
00134 }
00135
00136 #include "StratifiedParticleResampler.hpp"
00137
00138 #include <assert.h>
00139 #include <vector>
00140
00141 #include "boost/numeric/ublas/operation.hpp"
00142 #include "boost/numeric/ublas/operation_sparse.hpp"
00143
00144 template <class T>
00145 indii::ml::filter::ParticleSmoother<T>::ParticleSmoother(
00146 ParticleSmootherModel<T>* model, const T tT,
00147 const indii::ml::aux::DiracMixturePdf& p_xT) :
00148 Smoother<T,indii::ml::aux::DiracMixturePdf>(tT, p_xT), model(model) {
00149
00150 }
00151
00152 template <class T>
00153 indii::ml::filter::ParticleSmoother<T>::~ParticleSmoother() {
00154
00155 }
00156
00157 template <class T>
00158 indii::ml::filter::ParticleSmootherModel<T>*
00159 indii::ml::filter::ParticleSmoother<T>::getModel() {
00160 return model;
00161 }
00162
00163 template <class T>
00164 void indii::ml::filter::ParticleSmoother<T>::smooth(const T tn,
00165 const indii::ml::aux::DiracMixturePdf& p_xtn_ytn) {
00166 namespace aux = indii::ml::aux;
00167 namespace ublas = boost::numeric::ublas;
00168
00169
00170 assert (tn < this->tn);
00171
00172 const T tnp1 = this->tn;
00173 aux::DiracMixturePdf& p_xtnp1_ytT = this->p_xtn_ytT;
00174
00175 const unsigned int N = p_xtn_ytn.getDimensions();
00176 const unsigned int P1 = p_xtn_ytn.getSize();
00177 const unsigned int P2 = p_xtnp1_ytT.getSize();
00178 const T del = tnp1 - tn;
00179 unsigned int i;
00180
00181 boost::mpi::communicator world;
00182 const unsigned int rank = world.rank();
00183 const unsigned int size = world.size();
00184 unsigned int k;
00185
00186 const aux::vector& pi = p_xtn_ytn.getWeights();
00187 aux::vector psi(p_xtnp1_ytT.getWeights());
00188 aux::vector gamma(P2);
00189 aux::vector delta(P1);
00190 std::vector<aux::sparse_matrix> alphas;
00191
00192
00193 model->alphaPrecalculate(p_xtn_ytn, tn, del);
00194 for (k = 0; k < size; k++) {
00195 alphas.push_back(model->alpha(p_xtn_ytn, p_xtnp1_ytT, tn, del));
00196 indii::ml::aux::rotate(p_xtnp1_ytT);
00197 }
00198
00199
00200 gamma.clear();
00201 for (k = 0; k < size; k++) {
00202 ublas::axpy_prod(alphas[k], pi, gamma, false);
00203 indii::ml::aux::rotate(gamma);
00204 }
00205
00206
00207 delta.clear();
00208 psi = element_div(psi, gamma);
00209 for (k = 0; k < size; k++) {
00210 ublas::axpy_prod(psi, alphas[k], delta, false);
00211 indii::ml::aux::rotate(psi);
00212 }
00213
00214
00215 psi.resize(P1, false);
00216 noalias(psi) = element_prod(pi, delta);
00217
00218
00219 this->p_xtn_ytT = p_xtn_ytn;
00220 this->p_xtn_ytT.setWeights(psi);
00221
00222
00223 this->tn = tn;
00224 }
00225
00226 template <class T>
00227 indii::ml::aux::DiracMixturePdf
00228 indii::ml::filter::ParticleSmoother<T>::smoothedMeasure() {
00229 namespace aux = indii::ml::aux;
00230
00231 unsigned int i;
00232 StratifiedParticleResampler resampler;
00233 aux::DiracMixturePdf resampled(resampler.resample(
00234 Smoother<T,aux::DiracMixturePdf>::getSmoothedState()));
00235 aux::DiracMixturePdf p_ytn_xtT(model->getMeasurementSize());
00236
00237 for (i = 0; i < resampled.getSize(); i++) {
00238 p_ytn_xtT.add(model->measure(resampled.get(i)));
00239 }
00240
00241 return p_ytn_xtT;
00242 }
00243
00244 template <class T>
00245 void indii::ml::filter::ParticleSmoother<T>::smoothedResample(
00246 ParticleResampler* resampler) {
00247 indii::ml::aux::DiracMixturePdf resampled(resampler->resample(
00248 Smoother<T,aux::DiracMixturePdf>::getSmoothedState()));
00249 Smoother<T,aux::DiracMixturePdf>::setSmoothedState(resampled);
00250 }
00251
00252 #endif
00253