SIRFlt.hpp

Go to the documentation of this file.
00001 #ifndef _BAYES_FILTER_SIR
00002 #define _BAYES_FILTER_SIR
00003 
00004 /*
00005  * Bayes++ the Bayesian Filtering Library
00006  * Copyright (c) 2002 Michael Stevens
00007  * See accompanying Bayes++.htm for terms and conditions of use.
00008  *
00009  * $Id: SIRFlt.hpp 562 2006-04-05 20:46:23 +0200 (Wed, 05 Apr 2006) mistevens $
00010  */
00011 
00012 /*
00013  * Sampling Importance Resampleing Filter Scheme.
00014  *  Also know as a weighted Booststrap
00015  *
00016  * References
00017  *  [1] "Novel approach to nonlinear-non-Guassian Bayesian state estimation"
00018  *   NJ Gordon, DJ Salmond, AFM Smith IEE Proceeding-F Vol.140 No.2 April 1993
00019  *  [2] Building Robust Simulation-based Filter for Evolving Data Sets"
00020  *   J Carpenter, P Clifford, P Fearnhead Technical Report Unversity of Oxford
00021  *
00022  *  A variety of reampling algorithms can be used for the SIR filter.
00023  *  There are implementations for two algorihtms:
00024  *   standard_resample: Standard resample algorithm from [1]
00025  *   systematic_resample: A Simple stratified resampler from [2]
00026  *  A virtual 'weighted_resample' provides an standard interface to these and defaults
00027  *  to the standard_resample.
00028  *
00029  * NOTES:
00030  *  SIR algorithm is sensative to random generator
00031  *  In particular random uniform must be [0..1) NOT [0..1]
00032  *  Quantisation in the random number generator must not approach the sample size.
00033  *  This will result in quantisation of the resampling.
00034  *  For example if random identically equal to 0 becomes highly probable due to quantisation
00035  *  this will result in the first sample being selectively draw whatever its likelihood.
00036  *
00037  *  Numerics
00038  *   Resampling requires comparisons of normalised weights. These may
00039  *   become insignificant if Likelihoods have a large range. Resampling becomes ill conditioned
00040  *   for these samples.
00041  */
00042 #include "bayesFlt.hpp"
00043 
00044 /* Filter namespace */
00045 namespace Bayesian_filter
00046 {
00047 
00048 struct SIR_random
00049 /*
00050  * Random number generators interface
00051  *  Helper to allow polymorthic use of random number generators
00052  */
00053 {
00054     virtual void normal(FM::DenseVec& v) = 0;
00055     virtual void uniform_01(FM::DenseVec& v) = 0;
00056     virtual ~SIR_random () {}
00057 };
00058 
00059 
00060 class Importance_resampler : public Bayes_base
00061 /*
00062  * Importance resampler
00063  *  Represents a function that computes the posterior resampling from importance weights
00064  *  Polymorphic function object used to parameterise the resampling operation
00065  */
00066 {
00067 public:
00068     typedef std::vector<std::size_t> Resamples_t;   // resampling counts
00069 
00070     virtual Float resample (Resamples_t& presamples, std::size_t& uresamples, FM::DenseVec& w, SIR_random& r) const = 0;
00071     /*
00072      * The resampling function
00073      *  Weights w are proportional to the posterior Likelihood of a state
00074      * Sideeffect
00075      *  w becomes a normalised cumulative sum
00076      *  Random draws can be made from 'r'
00077      *
00078      * Exceptions:
00079      *  bayes_filter_exception for numerical problems with weights including
00080      *   any w < 0, all w == 0
00081      * Return
00082      *  lcond, smallest normalised weight, represents conditioning of resampling solution
00083      *  presamples: posterior resample, the number of times each sample should appear posterior baes on it weight
00084      *  uresample: the number of unique resamples in the posterior == number of non zero elements in presamples
00085      * Preconditions
00086      *  wresample,w must have same size
00087      */
00088 };
00089 
00090 class Standard_resampler : public Importance_resampler
00091 // Standard resample algorithm from [1]
00092 {
00093 public:
00094     Float resample (Resamples_t& presamples, std::size_t& uresamples, FM::DenseVec& w, SIR_random& r) const;
00095 };
00096 
00097 class Systematic_resampler : public Importance_resampler
00098 // Systematic resample algorithm from [2]
00099 {
00100 public:
00101     Float resample (Resamples_t& presamples, std::size_t& uresamples, FM::DenseVec& w, SIR_random& r) const;
00102 };
00103 
00104 
00105 template <class Predict_model>
00106 class Sampled_general_predict_model: public Predict_model, public Sampled_predict_model
00107 /*
00108  * Generalise a predict model to sampled predict model using and SIR random
00109  *  To instantiate template std::sqrt is required
00110  */
00111 {
00112 public:
00113     Sampled_general_predict_model (std::size_t x_size, std::size_t q_size, SIR_random& random_helper) :
00114         Predict_model(x_size, q_size),
00115         Sampled_predict_model(),
00116         genn(random_helper),
00117         xp(x_size),
00118         n(q_size), rootq(q_size)
00119     {
00120         first_init = true;
00121     }
00122 
00123     virtual const FM::Vec& fw(const FM::Vec& x) const
00124     /*
00125      * Definition of sampler for addative noise model given state x
00126      *  Generate Gaussian correlated samples
00127      * Precond: init_GqG, automatic on first use
00128      */
00129     {
00130         if (first_init)
00131             init_GqG();
00132                             // Predict state using supplied functional predict model
00133         xp = Predict_model::f(x);
00134                             // Additive random noise
00135         genn.normal(n);             // independant zero mean normal
00136                                     // multiply elements by std dev
00137         for (FM::DenseVec::iterator ni = n.begin(); ni != n.end(); ++ni) {
00138             *ni *= rootq[ni.index()];
00139         }
00140         FM::noalias(xp) += FM::prod(this->G,n);         // add correlated noise
00141         return xp;
00142     }
00143 
00144     void init_GqG() const
00145     /* initialise predict given a change to q,G
00146      *  Implementation: Update rootq
00147      */
00148     {
00149         first_init = false;
00150         for (FM::Vec::const_iterator qi = this->q.begin(); qi != this->q.end(); ++qi) {
00151             if (*qi < 0)
00152                 error (Numeric_exception("Negative q in init_GqG"));
00153             rootq[qi.index()] = std::sqrt(*qi);
00154         }
00155     }
00156 private:
00157     SIR_random& genn;
00158     mutable FM::Vec xp;
00159     mutable FM::DenseVec n;
00160     mutable FM::Vec rootq;      // Optimisation of sqrt(q) calculation, automatic on first use
00161     mutable bool first_init;    
00162 };
00163 
00164 typedef Sampled_general_predict_model<Linear_predict_model> Sampled_LiAd_predict_model;
00165 typedef Sampled_general_predict_model<Linear_invertable_predict_model> Sampled_LiInAd_predict_model;
00166 // Sampled predict model generalisations
00167 //  Names a shortened to first two letters of their model properties
00168 
00169 
00170 
00171 class SIR_scheme : public Sample_filter
00172 /*
00173  * Sampling Importance Resampleing Filter Scheme.
00174  *  Implement a general form of SIR filter
00175  *  Importance resampling is delayed until an update is required. The sampler used
00176  *  is a parameter of update to allow a wide variety of usage.
00177  *  A stochastic sample is defined as a sample with a unqiue stochastic history other then roughening
00178  */
00179 {
00180     friend class SIR_kalman_scheme;
00181 public:
00182     std::size_t stochastic_samples; // Number of stochastic samples in S
00183 
00184     SIR_scheme (std::size_t x_size, std::size_t s_size, SIR_random& random_helper);
00185     SIR_scheme& operator= (const SIR_scheme&);
00186     // Optimise copy assignment to only copy filter state
00187 
00188     /* Specialisations for filter algorithm */
00189     void init_S ();
00190 
00191     Float update_resample ()
00192     // Default resampling update
00193     {   return update_resample (Standard_resampler());
00194     }
00195 
00196     virtual Float update_resample (const Importance_resampler& resampler);
00197     /* Update: resample particles using weights and then roughen
00198      *  Return: lcond
00199      */
00200 
00201     void predict (Functional_predict_model& f)
00202     // Predict samples without noise
00203     {   Sample_filter::predict (f);
00204     }
00205     void predict (Sampled_predict_model& f);
00206     // Predict samples with noise model
00207 
00208     void observe (Likelihood_observe_model& h, const FM::Vec& z);
00209     // Weight particles using likelihood model h and z
00210 
00211     void observe_likelihood (const FM::Vec& lw);
00212     // Observation fusion directly from likelihood weights
00213 
00214     Float rougheningK;          // Current roughening value (0 implies no roughening)
00215     virtual void roughen()
00216     // Generalised roughening:  Default to roughen_minmax
00217     {
00218         if (rougheningK != 0)
00219             roughen_minmax (S, rougheningK);
00220     }
00221 
00222     static void copy_resamples (FM::ColMatrix& P, const Importance_resampler::Resamples_t& presamples);
00223     // Update P by selectively copying based on presamples 
00224 
00225     SIR_random& random;         // Reference random number generator helper
00226 
00227 protected:
00228     void roughen_minmax (FM::ColMatrix& P, Float K) const;  // roughening using minmax of P distribution
00229     Importance_resampler::Resamples_t resamples;        // resampling counts
00230     FM::DenseVec wir;           // resamping weights
00231     bool wir_update;            // weights have been updated requring a resampling on update
00232 private:
00233     static const Float rougheningKinit;
00234     std::size_t x_size;
00235 };
00236 
00237 
00238 class SIR_kalman_scheme : public SIR_scheme, virtual public Kalman_state_filter
00239 /*
00240  * SIR implementation of a Kalman filter
00241  *  Updates Kalman statistics of SIR_filter
00242  *  These statistics are use to provide a specialised correlated roughening procedure
00243  */
00244 {
00245 public:
00246     SIR_kalman_scheme (std::size_t x_size, std::size_t s_size, SIR_random& random_helper);
00247 
00248     /* Specialisations for filter algorithm */
00249 
00250     void init ();
00251 
00252     void update ()
00253     // Implement Kalman_filter::update identically to SIR_scheme
00254     {   (void)SIR_scheme::update_resample();
00255     }
00256 
00257     Float update_resample ()
00258     // Implement identically to SIR_scheme
00259     {   return SIR_scheme::update_resample();
00260     }
00261 
00262     Float update_resample (const Importance_resampler& resampler);
00263     // Modified SIR_filter update implementation: update mean and covariance of sampled distribution
00264 
00265     void update_statistics ();
00266     // Update kalman statistics without resampling
00267 
00268     void roughen()
00269     {   // Specialised correlated roughening
00270         if (rougheningK != 0)
00271             roughen_correlated (S, rougheningK);
00272     }
00273 
00274 protected:
00275     void roughen_correlated (FM::ColMatrix& P, Float K);    // Roughening using covariance of P distribution
00276     Sampled_LiAd_predict_model roughen_model;       // roughening predict
00277 private:
00278     static Float scaled_vector_square(const FM::Vec& v, const FM::SymMatrix& S);
00279     void mean();
00280 };
00281 
00282 
00283 }//namespace
00284 #endif

Generated on Wed Oct 4 22:57:23 2006 for Bayes++ Bayesian Filtering Classes by  doxygen 1.4.6