indii/ml/aux/WienerProcess.hpp

00001 #ifndef INDII_ML_AUX_WIENERPROCESS_HPP
00002 #define INDII_ML_AUX_WIENERPROCESS_HPP
00003 
00004 #include "StochasticProcess.hpp"
00005 
00006 namespace indii {
00007   namespace ml {
00008     namespace aux {
00009 
00010 /**
00011  * Multivariate Wiener process.
00012  *
00013  * @author Lawrence Murray <lawrence@indii.org>
00014  * @version $Rev: 565 $
00015  * @date $Date: 2008-09-13 22:25:02 +0100 (Sat, 13 Sep 2008) $
00016  *
00017  * This class supports serialization through the Boost.Serialization
00018  * library.
00019  */
00020 template <class T = unsigned int>
00021 class WienerProcess : public StochasticProcess<T> {
00022 public:
00023   /**
00024    * Default constructor.
00025    *
00026    * Initialises the Wiener process with zero dimensions. This should
00027    * generally only be used when the object is to be restored from a
00028    * serialization.
00029    */
00030   WienerProcess();
00031 
00032   /**
00033    * Construct Wiener process of given dimensionality.
00034    *
00035    * @param N \f$N\f$; number of dimensions in the process.
00036    *
00037    * The drift is initialised to zero and the diffusion to the
00038    * identity matrix, giving the standard Wiener process.
00039    */
00040   WienerProcess(unsigned int N);
00041 
00042   /**
00043    * Destructor.
00044    */
00045   virtual ~WienerProcess();
00046 
00047   virtual void setDimensions(const unsigned int N,
00048       const bool preserve = false);
00049 
00050   /**
00051    * Get the drift of the process.
00052    *
00053    * @return The drift of the process.
00054    */
00055   virtual const vector& getDrift() const;
00056 
00057   /**
00058    * Get the diffusion of the process.
00059    *
00060    * @return The diffusion of the process.
00061    */
00062   virtual const symmetric_matrix& getDiffusion() const;
00063 
00064   virtual const vector& getDrift();
00065 
00066   virtual const symmetric_matrix& getDiffusion();
00067 
00068   virtual vector getExpectation(const T delta);
00069 
00070   virtual symmetric_matrix getCovariance(const T delta);
00071 
00072   /**
00073    * Get the expected value of the process after a given time has
00074    * elapsed.
00075    *
00076    * @param delta \f$\Delta t\f$; elapsed time.
00077    *
00078    * @return \f$\mathbf{\mu}(\Delta t)\f$; expected value of the process
00079    * after time \f$\Delta t\f$.
00080    */
00081   virtual vector getExpectation(const T delta) const;
00082 
00083   /**
00084    * Get the covariance of the process after a given time has elapsed.
00085    *
00086    * @param delta \f$\Delta t\f$; elapsed time.
00087    *
00088    * @return \f$\Sigma(\Delta t)\f$; covariance of the process after
00089    * time \f$\Delta t\f$.
00090    */
00091   virtual symmetric_matrix getCovariance(const T delta) const;
00092 
00093   /**
00094    * Sample from the process after a given time has elapsed.
00095    *
00096    * @param delta \f$\Delta t\f$; elapsed time.
00097    *
00098    * This is performed using the following process:
00099    *
00100    * @li Let \f$\mathbf{z}\f$ be a vector of \f$N\f$ independent
00101    * normal variates with mean zero and variance \f$\Delta t\f$.
00102    *
00103    * @li Then the sample is \f$\mathbf{x} = \Delta t \mathbf{\mu} +
00104    * L\mathbf{z}\f$, where \f$L\f$ is the Cholesky decomposition of
00105    * the diffusion.
00106    *
00107    * @return The sample \f$\mathbf{x}\f$
00108    */
00109   virtual vector sample(const T delta);
00110 
00111   /**
00112    * Calculate the density of the distribution at a given point after
00113    * a given time has elapsed:
00114    *
00115    * \f[p(\mathbf{x},\Delta t) =
00116    *   \frac{1}{\sqrt{(2\pi\Delta t)^N|\Sigma|}}
00117    *   \exp\big({-\frac{1}{2\Delta t}(\mathbf{x}-\mathbf{\mu})^T \Sigma^{-1} 
00118    *   (\mathbf{x}-\mathbf{\mu})\big)}
00119    * \f]
00120    *
00121    * @param delta \f$\Delta t\f$; elapsed time.
00122    * @param x \f$\mathbf{x}\f$; the point at which to calculate the
00123    * density.
00124    *
00125    * @return The density of the distribution at \f$\mathbf{x}\f$ after
00126    * time \f$\Delta t\f$.
00127    */
00128   virtual double densityAt(const T delta, const vector& x);
00129 
00130 private:
00131   /**
00132    * Drift.
00133    */
00134   vector mu;
00135   
00136   /**
00137    * Diffusion.
00138    */
00139   symmetric_matrix sigma;
00140 
00141   /**
00142    * Serialize.
00143    */
00144   template<class Archive>
00145   void save(Archive& ar, const unsigned int version) const;
00146 
00147   /**
00148    * Restore from serialization.
00149    */
00150   template<class Archive>
00151   void load(Archive& ar, const unsigned int version);
00152 
00153   /*
00154    * Boost.Serialization requirements.
00155    */
00156   BOOST_SERIALIZATION_SPLIT_MEMBER()
00157   friend class boost::serialization::access;
00158 
00159 };
00160 
00161     }
00162   }
00163 }
00164 
00165 #include "Random.hpp"
00166 
00167 #include "boost/serialization/base_object.hpp"
00168 
00169 #include <assert.h>
00170 
00171 using namespace indii::ml::aux;
00172 
00173 namespace ublas = boost::numeric::ublas;
00174 
00175 template <class T>
00176 WienerProcess<T>::WienerProcess() : mu(0), sigma(0) {
00177   //
00178 }
00179 
00180 template <class T>
00181 WienerProcess<T>::WienerProcess(unsigned int N) : StochasticProcess<T>(N),
00182     mu(N), sigma(N) {
00183   noalias(mu) = zero_vector(N);
00184   noalias(sigma) = identity_matrix(N,N);
00185 }
00186 
00187 template <class T>
00188 WienerProcess<T>::~WienerProcess() {
00189   //
00190 }
00191 
00192 template <class T>
00193 void WienerProcess<T>::setDimensions(const unsigned int N,
00194     const bool preserve) {
00195   this->N = N;
00196   mu.resize(N, true); // force preservation, or object will be invalid
00197   sigma.resize(N, true);
00198 }
00199 
00200 template <class T>
00201 vector WienerProcess<T>::getExpectation(const T delta) const {
00202   return mu;
00203 }  
00204 
00205 template <class T>
00206 symmetric_matrix WienerProcess<T>::getCovariance(const T delta) const {
00207   return delta * sigma;
00208 }
00209 
00210 template <class T>
00211 vector WienerProcess<T>::getExpectation(const T delta) {
00212   return mu;
00213 }  
00214 
00215 template <class T>
00216 symmetric_matrix WienerProcess<T>::getCovariance(const T delta) {
00217   return delta * sigma;
00218 }
00219 
00220 template <class T>
00221 const vector& WienerProcess<T>::getDrift() {
00222   return mu;
00223 }  
00224 
00225 template <class T>
00226 const symmetric_matrix& WienerProcess<T>::getDiffusion() {
00227   return sigma;
00228 }
00229 
00230 template <class T>
00231 const vector& WienerProcess<T>::getDrift() const {
00232   return mu;
00233 }  
00234 
00235 template <class T>
00236 const symmetric_matrix& WienerProcess<T>::getDiffusion() const {
00237   return sigma;
00238 }
00239 
00240 template <class T>
00241 vector WienerProcess<T>::sample(const T delta) {
00242   vector z(this->N);
00243   unsigned int i;
00244 
00245   for (i = 0; i < this->N; i++) {
00246     z(i) = Random::gaussian(0.0, sqrt(delta));
00247   }
00248 
00249   return z;
00250 }
00251 
00252 template <class T>
00253 double WienerProcess<T>::densityAt(const T delta, const vector& x) {
00254   double deltaI = 1.0 / delta;
00255   double exponent = inner_prod(x,x);
00256   double z = sqrt(std::pow(2.0*M_PI*deltaI, static_cast<int>(this->N)));
00257   
00258   return z * exp(-0.5 * deltaI * exponent);
00259 }
00260 
00261 template <class T>
00262 template <class Archive>
00263 void indii::ml::aux::WienerProcess<T>::save(Archive& ar,
00264     const unsigned int version) const {
00265   ar & boost::serialization::base_object<StochasticProcess<T> >(*this);
00266   ar & mu;
00267   
00268   /* serialization of symmetric_matrix not yet supported in ublas */
00269   const aux::matrix tmp(sigma);
00270   ar & tmp;
00271 }
00272 
00273 template <class T>
00274 template <class Archive>
00275 void indii::ml::aux::WienerProcess<T>::load(Archive& ar,
00276     const unsigned int version) {
00277   ar & boost::serialization::base_object<StochasticProcess<T> >(*this);
00278   ar & mu;
00279   
00280   /* serialization of symmetric_matrix not yet supported in ublas */
00281   aux::matrix tmp(this->N,this->N);
00282   ar & tmp;
00283   noalias(sigma) = boost::numeric::ublas::symmetric_adaptor<aux::matrix>(tmp);
00284 }
00285 
00286 #endif
00287 

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