00001 #ifndef INDII_ML_SDE_STOCHASTICEULERMARUYAMA_HPP
00002 #define INDII_ML_SDE_STOCHASTICEULERMARUYAMA_HPP
00003
00004 #include "StochasticDifferentialModel.hpp"
00005 #include "StochasticNumericalSolver.hpp"
00006
00007 namespace indii {
00008 namespace ml {
00009 namespace sde {
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 template <class DT = indii::ml::aux::matrix,
00032 class DDT = indii::ml::aux::zero_matrix>
00033 class StochasticEulerMaruyama :
00034 public indii::ml::sde::StochasticNumericalSolver {
00035 public:
00036
00037
00038
00039
00040
00041
00042
00043
00044 StochasticEulerMaruyama(StochasticDifferentialModel<DT,DDT>* model);
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 StochasticEulerMaruyama(StochasticDifferentialModel<DT,DDT>* model,
00055 const indii::ml::aux::vector& y0);
00056
00057
00058
00059
00060 virtual ~StochasticEulerMaruyama();
00061
00062 virtual double step(double upper);
00063
00064 virtual double stepBack(double lower);
00065
00066 virtual int calculateDerivativesForward(double t, const double y[],
00067 double dydt[]);
00068
00069 virtual int calculateDerivativesBackward(double t, const double y[],
00070 double dydt[]);
00071
00072 private:
00073
00074
00075
00076 StochasticDifferentialModel<DT,DDT>* model;
00077
00078
00079
00080
00081 indii::ml::aux::vector a;
00082
00083
00084
00085
00086 DT B;
00087
00088 };
00089
00090 }
00091 }
00092 }
00093
00094 #include "boost/numeric/ublas/operation.hpp"
00095 #include "boost/numeric/ublas/operation_sparse.hpp"
00096
00097 template <class DT, class DDT>
00098 indii::ml::sde::StochasticEulerMaruyama<DT,DDT>::StochasticEulerMaruyama(
00099 StochasticDifferentialModel<DT,DDT>* model) :
00100 StochasticNumericalSolver(model->getDimensions(),
00101 model->getNoiseDimensions()), model(model), a(model->getDimensions()),
00102 B(model->getDimensions(), model->getNoiseDimensions()) {
00103 a.clear();
00104 B.clear();
00105 setStepType(gsl_odeiv_step_gear1);
00106 }
00107
00108 template <class DT, class DDT>
00109 indii::ml::sde::StochasticEulerMaruyama<DT,DDT>::StochasticEulerMaruyama(
00110 StochasticDifferentialModel<DT,DDT>* model,
00111 const indii::ml::aux::vector& y0) : StochasticNumericalSolver(y0,
00112 model->getNoiseDimensions()), model(model), a(model->getDimensions()),
00113 B(model->getDimensions(), model->getNoiseDimensions()) {
00114
00115 assert (y0.size() == model->getDimensions());
00116
00117 a.clear();
00118 B.clear();
00119 setStepType(gsl_odeiv_step_gear1);
00120 }
00121
00122 template <class DT, class DDT>
00123 indii::ml::sde::StochasticEulerMaruyama<DT,DDT>::~StochasticEulerMaruyama() {
00124
00125 }
00126
00127 template <class DT, class DDT>
00128 double indii::ml::sde::StochasticEulerMaruyama<DT,DDT>::step(
00129 double upper) {
00130
00131 assert (upper > t);
00132
00133 const unsigned int N = model->getDimensions();
00134 const unsigned int V = model->getNoiseDimensions();
00135 double ts, h;
00136
00137
00138 if (maxStepSize > 0.0 && stepSize > maxStepSize) {
00139 stepSize = maxStepSize;
00140 }
00141 ts = t + stepSize;
00142 if (ts > upper) {
00143 ts = upper;
00144 }
00145
00146
00147 aux::vector y(this->getState());
00148
00149
00150 sampleNoise(&ts);
00151 h = ts - t;
00152
00153 model->calculateDrift(t, y, a);
00154 model->calculateDiffusion(t, y, B);
00155 noalias(y) = y + h*a;
00156 ublas::axpy_prod(B, dWf.top(), y, false);
00157
00158
00159 aux::vectorToArray(y, this->y);
00160
00161
00162 t = ts;
00163
00164
00165 tf.pop();
00166 dWf.pop();
00167
00168
00169 assert (tf.empty() || t < tf.top());
00170 assert (t <= upper);
00171
00172 return t;
00173 }
00174
00175 template <class DT, class DDT>
00176 inline double indii::ml::sde::StochasticEulerMaruyama<DT,DDT>::stepBack(
00177 double lower) {
00178 double t = NumericalSolver::stepBack(lower);
00179
00180 return t;
00181 }
00182
00183 template <class DT, class DDT>
00184 inline int indii::ml::sde::StochasticEulerMaruyama<DT,DDT>::calculateDerivativesForward(
00185 double ts, const double y[], double dydt[]) {
00186
00187 assert (false);
00188
00189 return GSL_FAILURE;
00190 }
00191
00192 template <class DT, class DDT>
00193 inline int indii::ml::sde::StochasticEulerMaruyama<DT,DDT>::calculateDerivativesBackward(
00194 double t, const double y[], double dydt[]) {
00195
00196 assert (false);
00197
00198 return GSL_FAILURE;
00199 }
00200
00201 #endif
00202