indii/ml/filter/KernelTwoFilterSmoother.hpp

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  * Kernel two-filter smoother.
00017  *
00018  * @author Lawrence Murray <lawrence@indii.org>
00019  * @version $Rev: 584 $
00020  * @date $Date: 2008-12-15 17:26:36 +0000 (Mon, 15 Dec 2008) $
00021  *
00022  * @param T The type of time.
00023  * @param NT Norm type.
00024  * @param KT Kernel type.
00025  * @param ST Partitioner type.
00026  *
00027  * @see KernelForwardBackwardSmoother for further information, and 
00028  * indii::ml::filter for general usage guidelines.
00029  *
00030  * @section KernelTwoFilterSmoother_references References
00031  *
00032  * @anchor Murray2009
00033  * Murray, L. Bayesian Learning of Continuous Time Dynamical Systems (with
00034  * applications in Functional Magnetic Resonance Imaging). PhD thesis.
00035  * Online at http://www.indii.org/research/.
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    * Constructor, with measurement at starting time.
00046    * 
00047    * @param model Model to estimate.
00048    * @param N The kernel density norm.
00049    * @param K The kernel density kernel.
00050    * @param tT \f$t_T\f$; starting time.
00051    * @param p_xT \f$p(\mathbf{x}_T)\f$; prior over the state at time
00052    * \f$t_T\f$.
00053    * @param ytT \f$\mathbf{y}_T\f$; measurement at time \f$t_T\f$.
00054    * @param flags Optimisation flags for calculation of the initial
00055    * backward likelihood. Only NO_STANDARDISATION is relevant here.
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    * Constructor, without measurement at starting time.
00065    * 
00066    * @param model Model to estimate.
00067    * @param N The kernel density norm.
00068    * @param K The kernel density kernel.
00069    * @param tT \f$t_T\f$; starting time.
00070    * @param p_xT \f$p(\mathbf{x}_T)\f$; prior over the state at time
00071    * \f$t_T\f$.
00072    * @param flags Optimisation flags for calculation of the initial
00073    * backward likelihood. Only NO_STANDARDISATION is relevant here.
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    * Destructor.
00082    */
00083   virtual ~KernelTwoFilterSmoother();
00084 
00085   /**
00086    * Get the model.
00087    *
00088    * @return The model.
00089    */
00090   virtual KernelTwoFilterSmootherModel<T>* getModel();
00091 
00092   /**
00093    * Step back in time and smooth, with measurement.
00094    *
00095    * @param tn \f$t_n\f$; the time to which to rewind the system. This must
00096    * be less than the current time \f$t_{n+1}\f$.
00097    * @param ytn \f$\mathbf{y}_n\f$; the measurement at time \f$t_n\f$.
00098    * @param p_xtn_ytnm1 \f$p(\mathbf{x}_n\,|\,\mathbf{y}_{1:n-1})\f$;
00099    * the uncorrected %filter density at time \f$t_n\f$.
00100    * @param q_xtn \f$q(\mathbf{x}_n)\f$; proposal distribution for
00101    * importance sampling of the smooth density at time \f$t_n\f$.
00102    * @param flags Optimisation flags.
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    * Step back in time and smooth, without measurement.
00112    *
00113    * @param tn \f$t_n\f$; the time to which to rewind the system. This must
00114    * be less than the current time \f$t_{n+1}\f$.
00115    * @param p_xtn_ytnm1 \f$p(\mathbf{x}_n\,|\,\mathbf{y}_{1:n-1})\f$;
00116    * the uncorrected %filter density at time \f$t_n\f$.
00117    * @param q_xtn \f$q(\mathbf{x}_n)\f$; proposal distribution for
00118    * importance sampling of the smooth density at time \f$t_n\f$.
00119    * @param flags Optimisation flags.
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    * Step back in time and smooth, with measurement, and uncorrected
00128    * filter density as proposal distribution.
00129    *
00130    * @param tn \f$t_n\f$; the time to which to rewind the system. This must
00131    * be less than the current time \f$t_{n+1}\f$.
00132    * @param ytn \f$\mathbf{y}_n\f$; the measurement at time \f$t_n\f$.
00133    * @param p_xtn_ytnm1 \f$p(\mathbf{x}_n\,|\,\mathbf{y}_{1:n-1})\f$;
00134    * the uncorrected %filter density at time \f$t_n\f$.
00135    * @param flags Optimisation flags.
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    * Step back in time and smooth, without measurement, and uncorrected
00144    * filter density as proposal distribution.
00145    *
00146    * @param tn \f$t_n\f$; the time to which to rewind the system. This must
00147    * be less than the current time \f$t_{n+1}\f$.
00148    * @param p_xtn_ytnm1 \f$p(\mathbf{x}_n\,|\,\mathbf{y}_{1:n-1})\f$;
00149    * the uncorrected %filter density at time \f$t_n\f$.
00150    * @param flags Optimisation flags.
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    * Resample the smoothed state.
00160    *
00161    * @see ParticleFilter::resample()
00162    */
00163   void smoothedResample(ParticleResampler* resampler);
00164 
00165 private:
00166   /**
00167    * Model.
00168    */
00169   KernelTwoFilterSmootherModel<T>* model;
00170 
00171   /**
00172    * \f$\|\mathbf{x}\|_p\f$; the norm.
00173    */
00174   NT N;
00175   
00176   /**
00177    * \f$K(\|\mathbf{x}\|_p) \f$; the density kernel.
00178    */
00179   KT K;
00180 
00181   /**
00182    * Number of samples to use.
00183    */
00184   unsigned int P;
00185 
00186   /**
00187    * Proposal distribution samples.
00188    */
00189   indii::ml::aux::DiracMixturePdf q_xtns;
00190   
00191   /**
00192    * Proposal distribution sample densities.
00193    */
00194   indii::ml::aux::vector q_ptns;
00195   
00196   /**
00197    * Proposal distribution sample propagations.
00198    */
00199   indii::ml::aux::DiracMixturePdf q_xtnp1s;
00200   
00201   /**
00202    * Time difference for last proposal sample propagations.
00203    */
00204   T q_delta;
00205 
00206   /**
00207    * \f$p(\mathbf{y}_{n:T}\,|\,\mathbf{x}_n)\f$; backward likelihood.
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   /* initialise backward likelihood */
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   /* initialise backward likelihood */
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   /* pre-condition */
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   /* pick apart flags */
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   /* sample particles from proposal */
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   /* propagate sample particles */
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   /* likelihood evaluation */
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     /* uncorrected filter density evaluation */
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     /* likelihood evaluation */
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     /* uncorrected filter density evaluation */
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     /* likelihood evaluation */
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   /* rebuild densities/likelihoods */
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   /* update state */
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   /* pick apart flags */
00465   bool noResampling = flags & NO_RESAMPLING;
00466   bool noStandardisation = flags & NO_STANDARDISATION;
00467 
00468   /* propagate sample particles */
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   /* likelihood evaluation */
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     /* uncorrected filter density evaluation */
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     /* likelihood evaluation */
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     /* uncorrected filter density evaluation */
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     /* likelihood evaluation */
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   /* rebuild densities/likelihoods */
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   /* update state */
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 

Generated on Wed Dec 17 15:11:57 2008 for dysii Dynamical Systems Library by  doxygen 1.5.3