Ejemplo 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;
}
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";
	}
}
ForwardEulerSolver::ForwardEulerSolver(int N, double startTime, double endTime, double initialValue){
    if (endTime > startTime){
        if (N > 1){
            SetIterationNumber(N);
            SetInitialValue(initialValue);
            SetTimeInterval(startTime, endTime);
            SetStepSize((endTime - startTime)/(N - 1));
            double* output = SolveEquation();
            for (int i = 0; i < GetIterationNumber(); ++i) {
                std::cout << output[i] << " " << GetInitialTime() + i*GetStepSize() << " " << test(GetInitialTime() + i*GetStepSize())<< "\n";
            }
        }
        else{
            std::cerr << "The number of iterations needs to be > 1!!\n";
        }
    }
    else{
        std::cerr << "Final time needs to be after initial!!\n";
    }
}