Exemplo n.º 1
0
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;
}
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";
	}
}