indii/ml/filter/FixableStateModel.hpp

00001 #ifndef INDII_ML_FILTER_FIXABLESTATEMODEL_HPP
00002 #define INDII_ML_FILTER_FIXABLESTATEMODEL_HPP
00003 
00004 #include "../aux/vector.hpp"
00005 #include "../aux/matrix.hpp"
00006 #include "../aux/DiracMixturePdf.hpp"
00007 
00008 namespace indii {
00009   namespace ml {
00010     namespace filter {
00011 /**
00012  * Model with fixable state variables.
00013  *
00014  * @author Lawrence Murray <lawrence@indii.org>
00015  * @version $Version$
00016  * @date $Date: 2008-08-16 16:59:47 +0100 (Sat, 16 Aug 2008) $
00017  *
00018  * Allows one or more state variables to be fixed. Fixing a variable removes
00019  * it from the state, reducing the state size by one. The state may then be
00020  * projected up into the full space of both state and fixed variables using
00021  * the fromState() method, and back again using the toState() method.
00022  *
00023  * The main purpose of this class is to allow the fixing of parameters, which
00024  * is useful for diagnostics and model testing, with minimal changes to a
00025  * model. For example, the transition() method of a ParticleFilterModel
00026  * derived class can apply fromState() to the particle @c s passed to it to
00027  * standardise its representation regardless of which variables are fixed,
00028  * transition the standardised particle, then apply toState() before
00029  * returning the result.
00030  */
00031 class FixableStateModel {
00032 public:
00033   /**
00034    * Default constructor for restoring from serialization.
00035    */
00036   FixableStateModel();
00037 
00038   /**
00039    * Constructor.
00040    * 
00041    * @param N Initial state size. One or more components of the state may
00042    * subsequently be fixed and the state size will be reduced.
00043    */
00044   FixableStateModel(const unsigned int N);
00045 
00046   /**
00047    * Destructor.
00048    */
00049   virtual ~FixableStateModel();
00050 
00051   /**
00052    * Get number of non-fixed variables.
00053    */
00054   virtual unsigned int getVariableSize() const;
00055 
00056   /**
00057    * Get number of fixed variables.
00058    */
00059   virtual unsigned int getFixedSize() const;
00060 
00061   /**
00062    * Fix the value of a variable. If the variable is already fixed, its value
00063    * is updated to the new value given.
00064    *
00065    * @param i The index of the variable amongst both the fixed and state
00066    * variables.
00067    * @param value Value to which to fix the variable.
00068    *
00069    * @deprecated Use fix()
00070    */
00071   void fix(const unsigned int i, const double value);
00072 
00073   /**
00074    * Is the value of a particular variable fixed?
00075    *
00076    * @param i The index of the variable amongst both the fixed and state
00077    * variables.
00078    *
00079    * @return True if the value @p i is fixed, false otherwise.
00080    */
00081   bool isFixed(const unsigned int i) const;
00082   
00083   /**
00084    * Get the value to which a particular variable is fixed.
00085    *
00086    * @param i The index of the variable amongst both the fixed and state
00087    * variables.
00088    *
00089    * @return The value of the variable if fixed, undefined if not fixed.
00090    */
00091   double getFixedValue(const unsigned int i) const;
00092 
00093   /**
00094    * Project vector of both fixed and state variables to state variables
00095    * only.
00096    *
00097    * @param x Vector of both fixed and state variables.
00098    *
00099    * @return Vector of state variables only.
00100    */
00101   indii::ml::aux::vector condense(const indii::ml::aux::vector& x) const;
00102 
00103   /**
00104    * Project vector of state variables into state and fixed variables.
00105    *
00106    * @param x Vector of state variables only.
00107    *
00108    * @return Vector of both fixed and state variables.
00109    */
00110   indii::ml::aux::vector expand(const indii::ml::aux::vector& x) const;
00111 
00112   /**
00113    * Project vector of both fixed and state variables to state variables
00114    * only.
00115    *
00116    * @param x Vector of both fixed and state variables.
00117    *
00118    * @return Vector of state variables only.
00119    */
00120   indii::ml::aux::DiracPdf condense(const indii::ml::aux::DiracPdf& x) const;
00121 
00122   /**
00123    * Project vector of state variables into state and fixed variables.
00124    *
00125    * @param x Vector of state variables only.
00126    *
00127    * @return Vector of both fixed and state variables.
00128    */
00129   indii::ml::aux::DiracPdf expand(const indii::ml::aux::DiracPdf& x) const;
00130 
00131   /**
00132    * Project matrix (e.g. covariance matrix) of both fixed and
00133    * state variables to state variables only.
00134    *
00135    * @param x Matrix of both fixed and state variables.
00136    *
00137    * @return Matrix of state variables only.
00138    */
00139   template <class M>
00140   M condense(const M& x) const;
00141 
00142   /**
00143    * Project matrix (e.g. covariance matrix) of state variables
00144    * only to both fixed and state variables.
00145    *
00146    * @param x Matrix of state variables only.
00147    *
00148    * @return Matrix of both fixed and state variables.
00149    */
00150   template <class M>
00151   M expand(const M& x) const;
00152 
00153 private:
00154   /**
00155    * Size of state.
00156    */
00157   unsigned int N;
00158   
00159   /**
00160    * Number of fixed variables.
00161    */
00162   unsigned int F;
00163   
00164   /**
00165    * Fixed variable values. Zero for all others.
00166    */
00167   indii::ml::aux::sparse_vector fixed;
00168 
00169   /**
00170    * Projection of fixed and state variables to state variables only.
00171    */
00172   indii::ml::aux::projection_matrix projectCondense;
00173 
00174   /**
00175    * Serialize, or restore from serialization.
00176    */
00177   template<class Archive>
00178   void serialize(Archive& ar, const unsigned int version);
00179 
00180   /*
00181    * Boost.Serialization requirements.
00182    */
00183   friend class boost::serialization::access;
00184   
00185 };
00186 
00187     }
00188   }
00189 }
00190 
00191 #include "boost/numeric/ublas/operation.hpp"
00192 #include "boost/numeric/ublas/operation_sparse.hpp"
00193 
00194 inline bool indii::ml::filter::FixableStateModel::isFixed(
00195     const unsigned int i) const {
00196   bool result = true;
00197   unsigned int row;
00198   
00199   for (row = 0; row < projectCondense.size1(); row++) {
00200     if (projectCondense(row,i) == 1) {
00201       result = false;
00202       break;
00203     }
00204   }
00205 
00206   return result;
00207 }
00208 
00209 inline double indii::ml::filter::FixableStateModel::getFixedValue(
00210     const unsigned int i) const {
00211   /* pre-condition */
00212   assert (i < N + F);
00213     
00214   return fixed(i);
00215 }
00216 
00217 inline indii::ml::aux::vector indii::ml::filter::FixableStateModel::condense(
00218     const aux::vector& x) const {
00219   /* pre-condition */
00220   assert (x.size() == N + F);
00221 
00222   namespace ublas = boost::numeric::ublas;
00223 
00224   if (F == 0) {
00225     return x;
00226   } else {
00227     aux::vector result(N);
00228     ublas::axpy_prod(projectCondense, x, result, true);
00229     return result;
00230   }
00231 }
00232 
00233 inline indii::ml::aux::vector indii::ml::filter::FixableStateModel::expand(
00234     const aux::vector& x) const {
00235   /* pre-condition */
00236   assert (x.size() == N);
00237 
00238   namespace ublas = boost::numeric::ublas;
00239 
00240   if (F == 0) {
00241     return x;
00242   } else {
00243     aux::vector result(fixed);
00244     ublas::axpy_prod(x, projectCondense, result, false);
00245     return result;
00246   }
00247 }
00248 
00249 inline indii::ml::aux::DiracPdf
00250     indii::ml::filter::FixableStateModel::condense(const aux::DiracPdf& x)
00251      const {
00252   /* pre-condition */
00253   assert (x.size() == N + F);
00254 
00255   namespace ublas = boost::numeric::ublas;
00256 
00257   if (F == 0) {
00258     return x;
00259   } else {
00260     aux::DiracPdf result(N);
00261     ublas::axpy_prod(projectCondense, x, result, true);
00262     return result;
00263   }
00264 }
00265 
00266 inline indii::ml::aux::DiracPdf indii::ml::filter::FixableStateModel::expand(
00267     const aux::DiracPdf& x) const {
00268   /* pre-condition */
00269   assert (x.size() == N);
00270 
00271   namespace ublas = boost::numeric::ublas;
00272 
00273   if (F == 0) {
00274     return x;
00275   } else {
00276     aux::DiracPdf result(fixed);
00277     ublas::axpy_prod(x, projectCondense, result, false);
00278     return result;
00279   }
00280 }
00281 
00282 template <class M>
00283 inline M indii::ml::filter::FixableStateModel::condense(const M& x) const {
00284   /* pre-condition */
00285   assert (x.size1() == N + F);
00286 
00287   namespace aux = indii::ml::aux;
00288   namespace ublas = boost::numeric::ublas;
00289 
00290   if (F == 0) {
00291     return x;
00292   } else {
00293     aux::matrix tmp(prod(projectCondense, x));
00294     M result(prod(tmp, trans(projectCondense)));
00295     return result;
00296   }
00297 }
00298 
00299 template <class M>
00300 inline M indii::ml::filter::FixableStateModel::expand(const M& x) const {
00301   /* pre-condition */
00302   assert (x.size1() == N);
00303 
00304   namespace aux = indii::ml::aux;
00305   namespace ublas = boost::numeric::ublas;
00306 
00307   if (F == 0) {
00308     return x;
00309   } else {
00310     aux::matrix tmp(prod(trans(projectCondense), x));
00311     M result(prod(tmp, projectCondense));
00312     return result;
00313   }
00314 }
00315 
00316 template<class Archive>
00317 void indii::ml::filter::FixableStateModel::serialize(Archive& ar,
00318     const unsigned int version) {
00319   ar & N;
00320   ar & F;
00321   ar & fixed;
00322   ar & projectCondense;
00323 }
00324 
00325 #endif
00326 

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