indii/ml/ode/AdaptiveRungeKutta.hpp

00001 #ifndef INDII_ML_ODE_ADAPTIVERUNGEKUTTA_HPP
00002 #define INDII_ML_ODE_ADAPTIVERUNGEKUTTA_HPP
00003 
00004 #include "NumericalSolver.hpp"
00005 #include "DifferentialModel.hpp"
00006 #include "../aux/vector.hpp"
00007 
00008 #include <gsl/gsl_odeiv.h>
00009 
00010 namespace indii {
00011   namespace ml {
00012     namespace ode {
00013 
00014 /**
00015  * Adaptive Runge-Kutta method for solving a system of ordinary
00016  * differential equations.
00017  *
00018  * @author Lawrence Murray <lawrence@indii.org>
00019  * @version $Rev: 448 $
00020  * @date $Date: 2008-05-01 17:11:33 +0100 (Thu, 01 May 2008) $
00021  *
00022  * This class numerically solves DifferentialModel models defining a
00023  * system of ordinary differential equations using an adaptive time
00024  * step 4th/5th order Runge--Kutta--Fehlberg method as implemented in
00025  * the @ref GSL "GSL".
00026  *
00027  * The general usage idiom is as follows. First begin by writing your
00028  * own class deriving from DifferentialModel to describe your model,
00029  * and instantiating an object of this class:
00030  *
00031  * @code
00032  * MyDifferentialModel model;
00033  * @endcode
00034  *
00035  * Construct the initial state of the system:
00036  *
00037  * @code
00038  * indii::ml::aux::vector y0(4);
00039  * y0(0) = 1.0;
00040  * y0(1) = 0.0;
00041  * y0(2) = 0.0;
00042  * y0(3) = 2.0;
00043  * @endcode
00044  * 
00045  * Create an AdaptiveRungeKutta object, passing in the model to solve
00046  * and the initial state:
00047  *
00048  * @code
00049  * AdaptiveRungeKutta solver(&model, y0);
00050  * @endcode
00051  *
00052  * At this stage setErrorBounds() and setStepSize() may be used to
00053  * manipulate the Runge-Kutta to be appropriate for the model,
00054  * balancing speed versus accuracy. The defaults are often sufficient,
00055  * however.
00056  *
00057  * Now use step() to step through the system. The time step will vary
00058  * to maintain error bounds, so it is necessary to keep track of the
00059  * time after each step.
00060  *
00061  * @code
00062  * double end = 60.0;
00063  * double t = 0.0;
00064  * while (t < end) {
00065  *   t = solver.step(end);
00066  *   std::cout << solver.getState() << std::endl;
00067  * }
00068  * @endcode
00069  *
00070  * @c t is guaranteed to reach @c end at some point, although the
00071  * number of steps that this will take depends on the model, initial
00072  * state and error bounds.
00073  * 
00074  * If you are only interested in the state of the system at a given
00075  * time, or wish to use fixed time steps, use stepTo() to jump
00076  * straight to the required time. Internally, stepTo() essentially
00077  * just performs the above loop for you, but its use can be more
00078  * convenient.
00079  *
00080  * For known discontinuities, it is usual to estimate the function
00081  * piecewise, stepping from start to finish through a continuous
00082  * piece, then calling setDiscontinuity() before proceeding onto the
00083  * next.
00084  *
00085  * @section AdaptiveRungeKutta_references References
00086  *
00087  * @anchor GSL
00088  * The GNU Scientific Library (GSL). http://www.gnu.org/software/gsl/.
00089  */
00090 class AdaptiveRungeKutta : public NumericalSolver {
00091 public:
00092   /**
00093    * Constructor.
00094    *
00095    * @param model Model to estimate.
00096    *
00097    * The time is initialised to zero, but the state is uninitialised
00098    * and should be set with setVariable() or setState().
00099    */
00100   AdaptiveRungeKutta(DifferentialModel* model);
00101 
00102   /**
00103    * Constructor.
00104    *
00105    * @param model Model to estimate.
00106    * @param y0 Initial state.
00107    *
00108    * The time is initialised to zero and the state to that given.
00109    */
00110   AdaptiveRungeKutta(DifferentialModel* model,
00111       const indii::ml::aux::vector& y0);
00112 
00113   /**
00114    * Destructor.
00115    */
00116   virtual ~AdaptiveRungeKutta();
00117 
00118   virtual int calculateDerivativesForward(double t, const double y[],
00119       double dydt[]);
00120 
00121   virtual int calculateDerivativesBackward(double t, const double y[],
00122       double dydt[]);
00123 
00124 private:
00125   /**
00126    * Model.
00127    */
00128   DifferentialModel* model;
00129 
00130   /**
00131    * GSL ordinary differential equations step type.
00132    */
00133   static const gsl_odeiv_step_type* gslStepType;
00134 
00135 };
00136 
00137     }
00138   }
00139 }
00140 
00141 #endif
00142 

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