00001 #ifndef INDII_ML_FILTER_KERNELTWOFILTERSMOOTHER_HPP
00002 #define INDII_ML_FILTER_KERNELTWOFILTERSMOOTHER_HPP
00003
00004 #include "Smoother.hpp"
00005 #include "ParticleResampler.hpp"
00006 #include "KernelTwoFilterSmootherModel.hpp"
00007 #include "flags.hpp"
00008 #include "../aux/Almost2Norm.hpp"
00009 #include "../aux/AlmostGaussianKernel.hpp"
00010 #include "../aux/MedianPartitioner.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
00032
00033
00034
00035
00036
00037 template <class T = unsigned int,
00038 class NT = indii::ml::aux::Almost2Norm,
00039 class KT = indii::ml::aux::AlmostGaussianKernel,
00040 class ST = indii::ml::aux::MedianPartitioner>
00041 class KernelTwoFilterSmoother :
00042 public Smoother<T,indii::ml::aux::DiracMixturePdf> {
00043 public:
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 KernelTwoFilterSmoother(KernelTwoFilterSmootherModel<T>* model,
00058 const NT& N, const KT& K, const T tT,
00059 const indii::ml::aux::DiracMixturePdf& p_xT,
00060 const indii::ml::aux::vector& ytT,
00061 const unsigned int flags = 0);
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 KernelTwoFilterSmoother(KernelTwoFilterSmootherModel<T>* model,
00076 const NT& N, const KT& K, const T tT,
00077 const indii::ml::aux::DiracMixturePdf& p_xT,
00078 const unsigned int flags = 0);
00079
00080
00081
00082
00083 virtual ~KernelTwoFilterSmoother();
00084
00085
00086
00087
00088
00089
00090 virtual KernelTwoFilterSmootherModel<T>* getModel();
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 void smooth(const T tn,
00105 const indii::ml::aux::vector& ytn,
00106 indii::ml::aux::DiracMixturePdf& p_xtn_ytnm1,
00107 indii::ml::aux::Pdf& q_xtn,
00108 const unsigned int flags = 0);
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 void smooth(const T tn,
00122 indii::ml::aux::DiracMixturePdf& p_xtn_ytnm1,
00123 indii::ml::aux::Pdf& q_xtn,
00124 const unsigned int flags = 0);
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 void smooth(const T tn,
00138 const indii::ml::aux::vector& ytn,
00139 indii::ml::aux::DiracMixturePdf& p_xtn_ytnm1,
00140 const unsigned int flags = 0);
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 void smooth(const T tn,
00153 indii::ml::aux::DiracMixturePdf& p_xtn_ytnm1,
00154 const unsigned int flags = 0);
00155
00156 virtual indii::ml::aux::DiracMixturePdf smoothedMeasure();
00157
00158
00159
00160
00161
00162
00163 void smoothedResample(ParticleResampler* resampler);
00164
00165 private:
00166
00167
00168
00169 KernelTwoFilterSmootherModel<T>* model;
00170
00171
00172
00173
00174 NT N;
00175
00176
00177
00178
00179 KT K;
00180
00181
00182
00183
00184 unsigned int P;
00185
00186
00187
00188
00189 indii::ml::aux::DiracMixturePdf q_xtns;
00190
00191
00192
00193
00194 indii::ml::aux::vector q_ptns;
00195
00196
00197
00198
00199 indii::ml::aux::DiracMixturePdf q_xtnp1s;
00200
00201
00202
00203
00204 T q_delta;
00205
00206
00207
00208
00209 DiracMixturePdf p_ytn_xtn;
00210
00211 };
00212
00213 }
00214 }
00215 }
00216
00217 #include "StratifiedParticleResampler.hpp"
00218 #include "../aux/kde.hpp"
00219
00220 #include <assert.h>
00221
00222 template <class T, class NT, class KT, class ST>
00223 indii::ml::filter::KernelTwoFilterSmoother<T,NT,KT,ST>::KernelTwoFilterSmoother(
00224 KernelTwoFilterSmootherModel<T>* model, const NT& N, const KT& K,
00225 const T tT, const indii::ml::aux::DiracMixturePdf& p_xT,
00226 const indii::ml::aux::vector& ytT, const unsigned int flags) :
00227 Smoother<T,indii::ml::aux::DiracMixturePdf>(tT, p_xT),
00228 model(model),
00229 N(N),
00230 K(K),
00231 q_xtns(model->getStateSize()),
00232 q_xtnp1s(model->getStateSize()),
00233 p_ytn_xtn(p_xT) {
00234 namespace aux = indii::ml::aux;
00235
00236 unsigned int i;
00237
00238 P = p_xT.getDistributedSize();
00239
00240
00241 aux::vector ws(p_ytn_xtn.getSize());
00242 if (flags & NO_STANDARDISATION) {
00243 aux::KDTree<ST> tree(&p_ytn_xtn);
00244 noalias(ws) = aux::distributedSelfTreeDensity(tree,
00245 p_ytn_xtn.getWeights(), N, K);
00246 } else {
00247 aux::DiracMixturePdf q(p_ytn_xtn);
00248 q.distributedStandardise();
00249
00250 aux::KDTree<ST> tree(&q);
00251 noalias(ws) = aux::distributedSelfTreeDensity(tree,
00252 q.getWeights(), N, K);
00253 }
00254 for (i = 0; i < p_ytn_xtn.getSize(); i++) {
00255 ws(i) /= model->weight(p_ytn_xtn.get(i), ytT);
00256 }
00257
00258 p_ytn_xtn.setWeights(element_div(p_ytn_xtn.getWeights(), ws));
00259 }
00260
00261 template <class T, class NT, class KT, class ST>
00262 indii::ml::filter::KernelTwoFilterSmoother<T,NT,KT,ST>::KernelTwoFilterSmoother(
00263 KernelTwoFilterSmootherModel<T>* model, const NT& N, const KT& K,
00264 const T tT, const indii::ml::aux::DiracMixturePdf& p_xT,
00265 const unsigned int flags) :
00266 Smoother<T,indii::ml::aux::DiracMixturePdf>(tT, p_xT),
00267 model(model),
00268 N(N),
00269 K(K),
00270 q_xtns(model->getStateSize()),
00271 q_xtnp1s(model->getStateSize()),
00272 p_ytn_xtn(p_xT) {
00273 namespace aux = indii::ml::aux;
00274
00275 unsigned int i;
00276
00277 P = p_xT.getDistributedSize();
00278
00279
00280 aux::vector ws(p_ytn_xtn.getSize());
00281 if (flags & NO_STANDARDISATION) {
00282 aux::KDTree<ST> tree(&p_ytn_xtn);
00283 noalias(ws) = aux::distributedSelfTreeDensity(tree,
00284 p_ytn_xtn.getWeights(), N, K);
00285 } else {
00286 aux::DiracMixturePdf q(p_ytn_xtn);
00287 q.distributedStandardise();
00288
00289 aux::KDTree<ST> tree(&q);
00290 noalias(ws) = aux::distributedSelfTreeDensity(tree,
00291 q.getWeights(), N, K);
00292 }
00293
00294 p_ytn_xtn.setWeights(element_div(p_ytn_xtn.getWeights(), ws));
00295 }
00296
00297 template <class T, class NT, class KT, class ST>
00298 indii::ml::filter::KernelTwoFilterSmoother<T,NT,KT,ST>::~KernelTwoFilterSmoother() {
00299
00300 }
00301
00302 template <class T, class NT, class KT, class ST>
00303 indii::ml::filter::KernelTwoFilterSmootherModel<T>*
00304 indii::ml::filter::KernelTwoFilterSmoother<T,NT,KT,ST>::getModel() {
00305 return model;
00306 }
00307
00308 template <class T, class NT, class KT, class ST>
00309 void indii::ml::filter::KernelTwoFilterSmoother<T,NT,KT,ST>::smooth(
00310 const T tn,
00311 const indii::ml::aux::vector& ytn,
00312 indii::ml::aux::DiracMixturePdf& p_xtn_ytnm1,
00313 indii::ml::aux::Pdf& q_xtn,
00314 const unsigned int flags) {
00315
00316 assert (q_xtn.getDimensions() == p_xtn_ytnm1.getDimensions());
00317
00318 const unsigned int D = model->getStateSize();
00319 vector x(D);
00320 const T del = this->tn - tn;
00321 DiracMixturePdf& p_ytnp1_xtnp1 = this->p_ytn_xtn;
00322 unsigned int P_local = aux::shareOf(P);
00323 unsigned int i;
00324
00325
00326 bool sameProposal = flags & SAME_PROPOSAL;
00327 bool samePropagations = flags & SAME_PROPAGATIONS;
00328 bool noResampling = flags & NO_RESAMPLING;
00329 bool noStandardisation = flags & NO_STANDARDISATION;
00330
00331
00332 if (!sameProposal || q_xtns.getSize() == 0) {
00333 q_xtns.clear();
00334 q_ptns.resize(P_local);
00335 for (i = 0; i < P_local; i++) {
00336 noalias(x) = q_xtn.sample();
00337 q_xtns.add(x);
00338 q_ptns(i) = q_xtn.densityAt(x);
00339 }
00340 }
00341
00342
00343 if (!samePropagations || !sameProposal || this->q_delta != del ||
00344 q_xtns.getSize() != q_xtnp1s.getSize()) {
00345 this->q_delta = del;
00346 q_xtnp1s.clear();
00347 for (i = 0; i < q_xtns.getSize(); i++) {
00348 noalias(x) = model->transition(q_xtns.get(i), tn, del);
00349 q_xtnp1s.add(x, q_xtns.getWeight(i));
00350 }
00351 }
00352
00353
00354 aux::vector l(P_local);
00355 if (ytn.size() > 0) {
00356 for (i = 0; i < P_local; i++) {
00357 l(i) = model->weight(q_xtns.get(i), ytn);
00358 }
00359 } else {
00360 l = aux::scalar_vector(P_local, 1.0);
00361 }
00362
00363 aux::vector a(P_local), b(P_local), beta(P_local), psi(P_local);
00364 if (noStandardisation) {
00365
00366 {
00367 p_xtn_ytnm1.redistributeBySpace();
00368 aux::KDTree<ST> queryTree(&q_xtns);
00369 aux::KDTree<ST> targetTree(&p_xtn_ytnm1);
00370
00371 noalias(a) = aux::distributedDualTreeDensity(queryTree, targetTree,
00372 p_xtn_ytnm1.getWeights(), N, K);
00373 }
00374
00375
00376 {
00377 p_ytnp1_xtnp1.redistributeBySpace();
00378 aux::KDTree<ST> queryTree(&q_xtnp1s);
00379 aux::KDTree<ST> targetTree(&p_ytnp1_xtnp1);
00380
00381 noalias(b) = aux::distributedDualTreeDensity(queryTree, targetTree,
00382 p_ytnp1_xtnp1.getWeights(), N, K);
00383 }
00384 } else {
00385
00386 {
00387 aux::vector mu(D);
00388 aux::lower_triangular_matrix L(D,D);
00389
00390 noalias(mu) = p_xtn_ytnm1.getDistributedExpectation();
00391 noalias(L) = p_xtn_ytnm1.getDistributedStandardDeviation();
00392
00393 DiracMixturePdf q(q_xtns);
00394 q.standardise(mu, L);
00395 p_xtn_ytnm1.standardise(mu, L);
00396
00397 p_xtn_ytnm1.redistributeBySpace();
00398 aux::KDTree<ST> queryTree(&q);
00399 aux::KDTree<ST> targetTree(&p_xtn_ytnm1);
00400
00401 noalias(a) = aux::distributedDualTreeDensity(queryTree, targetTree,
00402 p_xtn_ytnm1.getWeights(), N, K);
00403 }
00404
00405
00406 {
00407 aux::vector mu(D);
00408 aux::lower_triangular_matrix L(D,D);
00409
00410 noalias(mu) = p_ytnp1_xtnp1.getDistributedExpectation();
00411 noalias(L) = p_ytnp1_xtnp1.getDistributedStandardDeviation();
00412
00413 DiracMixturePdf q(q_xtnp1s);
00414 q.standardise(mu, L);
00415 p_ytnp1_xtnp1.standardise(mu, L);
00416
00417 p_ytnp1_xtnp1.redistributeBySpace();
00418 aux::KDTree<ST> queryTree(&q);
00419 aux::KDTree<ST> targetTree(&p_ytnp1_xtnp1);
00420
00421 noalias(b) = aux::distributedDualTreeDensity(queryTree, targetTree,
00422 p_ytnp1_xtnp1.getWeights(), N, K);
00423 }
00424 }
00425
00426 noalias(beta) = element_div(element_prod(l,b), q_ptns);
00427 beta = element_prod(beta, q_xtns.getWeights());
00428 noalias(psi) = element_prod(beta, a);
00429
00430
00431 this->p_ytn_xtn = q_xtns;
00432 this->p_ytn_xtn.setWeights(beta);
00433
00434 this->p_xtn_ytT = q_xtns;
00435 this->p_xtn_ytT.setWeights(psi);
00436
00437
00438 this->tn = tn;
00439 }
00440
00441 template <class T, class NT, class KT, class ST>
00442 void indii::ml::filter::KernelTwoFilterSmoother<T,NT,KT,ST>::smooth(
00443 const T tn,
00444 indii::ml::aux::DiracMixturePdf& p_xtn_ytnm1,
00445 indii::ml::aux::Pdf& q_xtn,
00446 const unsigned int flags) {
00447 aux::vector ytn;
00448 smooth(tn, ytn, p_xtn_ytnm1, q_xtn, flags);
00449 }
00450
00451 template <class T, class NT, class KT, class ST>
00452 void indii::ml::filter::KernelTwoFilterSmoother<T,NT,KT,ST>::smooth(
00453 const T tn,
00454 const indii::ml::aux::vector& ytn,
00455 indii::ml::aux::DiracMixturePdf& p_xtn_ytnm1,
00456 const unsigned int flags) {
00457 const unsigned int D = model->getStateSize();
00458 vector x(D);
00459 const T del = this->tn - tn;
00460 DiracMixturePdf& p_ytnp1_xtnp1 = this->p_ytn_xtn;
00461 unsigned int P_local = p_xtn_ytnm1.getSize();
00462 unsigned int i;
00463
00464
00465 bool noResampling = flags & NO_RESAMPLING;
00466 bool noStandardisation = flags & NO_STANDARDISATION;
00467
00468
00469 if (!noResampling) {
00470 this->q_delta = del;
00471 q_xtnp1s.clear();
00472 for (i = 0; i < p_xtn_ytnm1.getSize(); i++) {
00473 noalias(x) = model->transition(p_xtn_ytnm1.get(i), tn, del);
00474 q_xtnp1s.add(x, p_xtn_ytnm1.getWeight(i));
00475 }
00476 } else {
00477 assert (p_xtn_ytnm1.getSize() == p_ytnp1_xtnp1.getSize());
00478 }
00479
00480
00481 aux::vector l(P_local);
00482 if (ytn.size() > 0) {
00483 for (i = 0; i < P_local; i++) {
00484 l(i) = model->weight(p_xtn_ytnm1.get(i), ytn);
00485 }
00486 } else {
00487 l = aux::scalar_vector(P_local, 1.0);
00488 }
00489
00490 aux::vector a(P_local), b(P_local), beta(P_local), psi(P_local);
00491 const aux::vector& pi = p_xtn_ytnm1.getWeights();
00492 if (noStandardisation) {
00493
00494 {
00495 aux::KDTree<ST> tree(&p_xtn_ytnm1);
00496
00497 noalias(a) = aux::distributedSelfTreeDensity(tree,
00498 p_xtn_ytnm1.getWeights(), N, K);
00499 }
00500
00501
00502 {
00503 if (noResampling) {
00504 aux::KDTree<ST> tree(&p_ytnp1_xtnp1);
00505
00506 noalias(b) = aux::distributedSelfTreeDensity(tree,
00507 p_ytnp1_xtnp1.getWeights(), N, K);
00508 } else {
00509 p_ytnp1_xtnp1.redistributeBySpace();
00510 aux::KDTree<ST> queryTree(&q_xtnp1s);
00511 aux::KDTree<ST> targetTree(&p_ytnp1_xtnp1);
00512
00513 noalias(b) = aux::distributedDualTreeDensity(queryTree, targetTree,
00514 p_ytnp1_xtnp1.getWeights(), N, K);
00515 }
00516 }
00517 } else {
00518
00519 {
00520 DiracMixturePdf q(p_xtn_ytnm1);
00521 q.distributedStandardise();
00522 aux::KDTree<ST> tree(&q);
00523
00524 noalias(a) = aux::distributedSelfTreeDensity(tree, q.getWeights(),
00525 N, K);
00526 }
00527
00528
00529 {
00530 aux::vector mu(D);
00531 aux::lower_triangular_matrix L(D,D);
00532
00533 noalias(mu) = p_ytnp1_xtnp1.getDistributedExpectation();
00534 noalias(L) = p_ytnp1_xtnp1.getDistributedStandardDeviation();
00535 p_ytnp1_xtnp1.standardise(mu, L);
00536
00537 if (noResampling) {
00538 aux::KDTree<ST> tree(&p_ytnp1_xtnp1);
00539
00540 noalias(b) = aux::distributedSelfTreeDensity(tree,
00541 p_ytnp1_xtnp1.getWeights(), N, K);
00542 } else {
00543 DiracMixturePdf q(q_xtnp1s);
00544 q.standardise(mu, L);
00545
00546 p_ytnp1_xtnp1.redistributeBySpace();
00547 aux::KDTree<ST> queryTree(&q);
00548 aux::KDTree<ST> targetTree(&p_ytnp1_xtnp1);
00549
00550 noalias(b) = aux::distributedDualTreeDensity(queryTree, targetTree,
00551 p_ytnp1_xtnp1.getWeights(), N, K);
00552 }
00553 }
00554 }
00555
00556 noalias(psi) = element_prod(element_prod(l, b), pi);
00557 noalias(beta) = element_div(psi, a);
00558
00559
00560 this->p_ytn_xtn = p_xtn_ytnm1;
00561 this->p_ytn_xtn.setWeights(beta);
00562
00563 this->p_xtn_ytT = p_xtn_ytnm1;
00564 this->p_xtn_ytT.setWeights(psi);
00565
00566
00567 this->tn = tn;
00568 }
00569
00570 template <class T, class NT, class KT, class ST>
00571 void indii::ml::filter::KernelTwoFilterSmoother<T,NT,KT,ST>::smooth(
00572 const T tn,
00573 indii::ml::aux::DiracMixturePdf& p_xtn_ytnm1,
00574 const unsigned int flags) {
00575 aux::vector ytn;
00576 smooth(tn, ytn, p_xtn_ytnm1, flags);
00577 }
00578
00579 template <class T, class NT, class KT, class ST>
00580 indii::ml::aux::DiracMixturePdf
00581 indii::ml::filter::KernelTwoFilterSmoother<T,NT,KT,ST>::smoothedMeasure() {
00582 namespace aux = indii::ml::aux;
00583
00584 unsigned int i;
00585 StratifiedParticleResampler resampler;
00586 aux::DiracMixturePdf resampled(resampler.resample(
00587 this->getSmoothedState()));
00588 indii::ml::aux::DiracMixturePdf p_ytn_xtT(model->getMeasurementSize());
00589
00590 for (i = 0; i < resampled.getSize(); i++) {
00591 p_ytn_xtT.add(model->measure(resampled.get(i)));
00592 }
00593
00594 return p_ytn_xtT;
00595 }
00596
00597 template <class T, class NT, class KT, class ST>
00598 void indii::ml::filter::KernelTwoFilterSmoother<T,NT,KT,ST>::smoothedResample(
00599 ParticleResampler* resampler) {
00600 indii::ml::aux::DiracMixturePdf resampled(resampler->resample(
00601 this->getSmoothedState()));
00602 this->setSmoothedState(resampled);
00603 }
00604
00605 #endif
00606