double RungeKuttaSolver::SolveEquation() { double h = GetStepSize(); double t_previous = GetInitialTime(); double t1 = GetFinalTime(); double y_previous = getInitialValue(); double y_current = getInitialValue(); double k1, k2, k3, k4; while (t_previous + h < t1) { k1 = h * RightHandSide(y_previous, t_previous); k2 = h * RightHandSide(y_previous + 0.5 * k1, t_previous + 0.5 * h); k3 = h * RightHandSide(y_previous + 0.5 * k2, t_previous + 0.5 * h); k4 = h * RightHandSide(y_previous + k3, t_previous + h); y_current = y_previous + (1.0 / 6.0) * (k1 + 2 * k2 + 2 * k3 + k4); t_previous += h; y_previous = y_current; } return y_current; }
double* ForwardEulerSolver::SolveEquation(){ double* output = new double[GetIterationNumber()]; double y = GetInitialValue(); output[0] = y; for (int i = 1; i < GetIterationNumber(); ++i) { output[i] = y + GetStepSize()*RightHandSide(y, GetInitialTime() + i*GetStepSize()); y = output[i]; } return output; }
void RungeKuttaSolver::SolveEquation(std::ostream& stream) { double y = GetInitialValue(); double t = GetInitialTime(); double h = GetStepSize(); assert(h > 1e-6); std::cout << "Step size: " << h << std::endl; int n = static_cast<int>( std::floor((GetFinalTime() - GetInitialTime()) / h)); stream << t << " " << y << "\n"; for (int i = 1; i <= n; ++i) { double k1 = h * RightHandSide(y, t); double k2 = h * RightHandSide(y + 0.5 * k1, t + 0.5 * h); double k3 = h * RightHandSide(y + 0.5 * k2, t + 0.5 * h); double k4 = h * RightHandSide(y + k3, t + h); double temp = y + 1.0/6.0 * (k1 + 2 * k2 + 2 * k3 + k4); if (-1e-6 <= temp && temp <= 0.0) { y = 0.0; } else if (1.0 <= temp && temp <= (1.0 + 1e-6) ) { y = 1.0; } else if (0.0 < temp && temp < 1.0) { y = temp; } else { // Freak out! throw Exception("STEP", "Step size too large."); } t += h; stream << t << " " << y << "\n"; } }