indii/ml/ode/FunctionCollection.hpp

00001 #ifndef INDII_ML_ODE_FUNCTIONCOLLECTION_HPP
00002 #define INDII_ML_ODE_FUNCTIONCOLLECTION_HPP
00003 
00004 #include "FunctionModel.hpp"
00005 #include "FunctionStatic.hpp"
00006 
00007 #include "boost/serialization/split_member.hpp"
00008 
00009 #include <vector>
00010 
00011 namespace indii {
00012   namespace ml {
00013     namespace ode {
00014 
00015 /**
00016  * Collection of functions.
00017  *
00018  * @author Lawrence Murray <lawrence@indii.org>
00019  * @version $Rev: 355 $
00020  * @date $Date: 2007-11-26 00:19:09 +0000 (Mon, 26 Nov 2007) $
00021  */
00022 class FunctionCollection {
00023 public:
00024   /**
00025    * Default constructor for restoration from serialization.
00026    */
00027   FunctionCollection();
00028 
00029   /**
00030    * Construct new collection of functions.
00031    *
00032    * @param N Number of functions.
00033    */
00034   FunctionCollection(const unsigned int N);
00035 
00036   /**
00037    * Destructor.
00038    */
00039   virtual ~FunctionCollection();
00040 
00041   /**
00042    * Get the value of a function.
00043    *
00044    * @param index Index of the function.
00045    *
00046    * @return The value of the function the last time it was evaluated
00047    * by a call to evaluate().
00048    */
00049   virtual double getFunction(const unsigned int index) const;
00050 
00051   /**
00052    * Set a function in the collection.
00053    *
00054    * @param index Index of the function to set.
00055    * @param value The function.
00056    */
00057   virtual void setFunction(const unsigned int index, f_t value);
00058 
00059   /**
00060    * Set a function in the collection using an object rather than a
00061    * static function.
00062    *
00063    * @param index Index of the function to set.
00064    * @param value Object encapsulating the function. The caller
00065    * retains ownership.
00066    */
00067   virtual void setFunction(const unsigned int index, FunctionModel* value);
00068 
00069   /**
00070    * Is a function static?
00071    *
00072    * @param index Index of the function to check.
00073    *
00074    * @return True if the given function is static, false otherwise.
00075    */
00076   bool isStatic(const unsigned int index);
00077 
00078   /**
00079    * Set the object passed as an argument to all static functions when
00080    * called.
00081    *
00082    * @param object The object. The caller retains ownership.
00083    */
00084   virtual void setObject(void* object);
00085 
00086   /**
00087    * Evaluate all functions in the collection for a given time and
00088    * state, and store the results for subsequent calls to
00089    * getFunction().
00090    *
00091    * @param t The time.
00092    * @param y Array holding values of state variables at time t.
00093    */
00094   void evaluateAll(const double t, const double y[]);
00095 
00096 private:
00097   /**
00098    * Number of functions.
00099    */
00100   unsigned int N;
00101 
00102   /**
00103    * Static functions.
00104    */
00105   std::vector<f_t*> fs;
00106 
00107   /**
00108    * Function models.
00109    */
00110   std::vector<FunctionModel*> fms;
00111 
00112   /**
00113    * Function cached values.
00114    */
00115   std::vector<double> fvs;
00116 
00117   /**
00118    * Record of static functions.
00119    */
00120   std::vector<bool> statics;
00121 
00122   /**
00123    * Object passed as argument to all calls to static functions.
00124    */
00125   void* object;
00126 
00127   /**
00128    * Serialize. Note that serialization of a FunctionCollection object
00129    * does not include static functions stored in it, only the
00130    * structure in which the functions are stored. This is due to
00131    * difficulties in serializing function pointers. After restoration,
00132    * the functions should be restored with calls to setFunction() and
00133    * setObject().
00134    */
00135   template<class Archive>
00136   void save(Archive& ar, const unsigned int version) const;
00137 
00138   /**
00139    * Restore from serialization.
00140    */
00141   template<class Archive>
00142   void load(Archive& ar, const unsigned int version);
00143 
00144   /*
00145    * Boost.Serialization requirements.
00146    */
00147   BOOST_SERIALIZATION_SPLIT_MEMBER()
00148   friend class boost::serialization::access;
00149 
00150 };
00151 
00152     }
00153   }
00154 }
00155 
00156 #include "boost/serialization/vector.hpp"
00157 
00158 #include <assert.h>
00159 
00160 inline
00161 double indii::ml::ode::FunctionCollection::getFunction(
00162     const unsigned int index) const {
00163   /* pre-condition */
00164   assert (index < N);
00165 
00166   return fvs[index];
00167 }
00168 
00169 template<class Archive>
00170 void indii::ml::ode::FunctionCollection::save(Archive& ar,
00171     const unsigned int version) const {
00172   unsigned int i;
00173 
00174   ar & N;
00175   ar & fvs;
00176   ar & fms;
00177 
00178   /**
00179    * @todo Segfault when serializing statics directly, so do this way...
00180    */
00181   for (i = 0; i < N; i++) {
00182     const bool b = statics[i];
00183     ar & b;
00184   }
00185 }
00186 
00187 template<class Archive>
00188 void indii::ml::ode::FunctionCollection::load(Archive& ar,
00189     const unsigned int version) {
00190   unsigned int i;
00191   bool b;
00192 
00193   ar & N;
00194   ar & fvs;
00195   ar & fms;
00196 
00197   fs.resize(N);
00198   statics.resize(N);
00199 
00200   for (i = 0; i < N; i++) {
00201     ar & b;
00202     statics[i] = b;
00203   }
00204 
00205   for (i = 0; i < N; i++) {
00206     fs[i] = NULL;
00207     if (statics[i]) {
00208       fms[i] = NULL;
00209     }
00210   }
00211 
00212   object = this;
00213 }
00214 
00215 #endif

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