00001
00002
00008
00010
00011
00012 #ifndef RUNGEKUTTA_H
00013 #define RUNGEKUTTA_H
00014
00015 #include <Matrix.h>
00016
00018 typedef Vector(*ptr2RKFunc)(const double &_time, const Vector &_states, const Matrix &_params);
00019
00044 inline Matrix RungeKuttaSolve(Vector (*odeFunc)(const double &timeInput, const Vector &stateInput, const Matrix &constantsInput), const Vector &_initialConditions, const Matrix &_constants, const double &_timeInitial, const double &_timeFinal, const int &_numSteps)
00045 {
00046 double h = (_timeFinal - _timeInitial) / _numSteps;
00047 double t = _timeInitial;
00048 int numEqs = _initialConditions.getIndexCount();
00049 Vector inputs(numEqs); inputs = _initialConditions;
00050 Vector K1(numEqs);
00051 Vector K2(numEqs);
00052 Vector K3(numEqs);
00053 Vector K4(numEqs);
00054
00055 Matrix output(_numSteps + 1, numEqs + 1);
00056
00057 output(MatrixIndexBase,MatrixIndexBase) = _timeInitial;
00058 output(MatrixIndexBase,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~_initialConditions;
00059
00060 Vector temp(numEqs);
00061 for (int ii = 1; ii <= _numSteps; ++ii)
00062 {
00063 K1 = h * odeFunc(t, inputs, _constants);
00064 temp = inputs + K1 / 2.0;
00065 K2 = h * odeFunc(t + h/2, temp, _constants);
00066 temp = inputs + K2 / 2.0;
00067 K3 = h * odeFunc(t + h/2, temp, _constants);
00068 temp = inputs + K3;
00069 K4 = h * odeFunc(t + h, temp, _constants);
00070 for (int jj = MatrixIndexBase; jj < MatrixIndexBase + numEqs; ++jj)
00071 {
00072 inputs(jj) += (K1(jj)
00073 + 2.0 * K2(jj)
00074 + 2.0 * K3(jj)
00075 + K4(jj)) / 6.0;
00076 }
00077 t = _timeInitial + ii * h;
00078 output(MatrixIndexBase + ii,MatrixIndexBase) = t;
00079 output(MatrixIndexBase + ii,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~inputs;
00080 }
00081 return output;
00082 }
00083
00084
00085 #endif RungeKutta
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100