Routine Name: Predictor Experiment
Author: Kyle Hovey
Language: C++
Description/Purpose:
This code tests the accuracy of a given method against some examples found in the course textbook. In \(7.1\), we analyze \(u’ = -\sin(x); u_0 = 1; dt = 10^{-3}\). In \(7.2\), we change our driving function to \(u’ = \lambda (u - \cos(x)) - \sin(x)\) and require \(\lambda = -10\). And finally, for \(7.3\), we require \(\lambda = -2100\).
Input: A method for solving the examples
Output: The solutions given by the method
Usage/Example:
#include <iostream>
#include <cmath>
#include "../../predictorCorrector/src/predictorCorrector/predictorCorrector.h"
int main() {
/*
* 7.1
*/
const auto dt = 1E-3;
const auto uo = 1;
const auto simple = [](const double& t, const double& u) -> double {
(void) u;
return -std::sin(t);
};
const auto T = 2;
auto soln = PredCorr::predictorCorrector<double>(simple, dt, uo);
std::cout << "7.1:" << std::endl;
std::cout << "U_2000 = approx(2): " << soln(T) << std::endl;
std::cout << "Exact(2): " << std::cos(T) << std::endl;
std::cout << "Error: " << std::abs(soln(T) - std::cos(T)) << std::endl;
std::cout << std::endl;
/*
* 7.2
*/
const auto modified = [](const double& t, const double& u) -> double {
return -10 * (u - std::cos(t)) - std::sin(t);
};
soln = PredCorr::predictorCorrector<double>(modified, dt, uo);
std::cout << "7.2:" << std::endl;
std::cout << "U_2000 = approx(2): " << soln(T) << std::endl;
std::cout << "Exact(2): " << std::cos(T) << std::endl;
std::cout << "Error: " << std::abs(soln(T) - std::cos(T)) << std::endl;
std::cout << std::endl;
/*
* 7.3
*/
const auto largeLambda = [](const double& t, const double& u) -> double {
return -2100 * (u - std::cos(t)) - std::sin(t);
};
soln = PredCorr::predictorCorrector<double>(largeLambda, dt, uo);
std::cout << "7.3:" << std::endl;
std::cout << "U_2000 = approx(2): " << soln(T) << std::endl;
std::cout << "Exact(2): " << std::cos(T) << std::endl;
std::cout << "Error: " << std::abs(soln(T) - std::cos(T)) << std::endl;
return EXIT_SUCCESS;
}
Output:
The error is still significant for \(7.1\) and \(7.2\), which is strange considering it is the same error experienced in Explicit Euler. I can’t find the source of this error yet, but it is easy to see that the error blows up for \(7.3\) where \(\lambda = -21000\), indicating that the predictor corrector method is also unstable in the same context Explicit Euler was.
It seems that, for a larger time step, Implicit Euler still beats out Predictor Corrector using an Adams-Bashforth method.
7.1:
U_2000 = approx(2): -0.818595
Exact(2): -0.416147
Error: 0.402448
7.2:
U_2000 = approx(2): -0.507077
Exact(2): -0.416147
Error: 0.0909297
7.3:
U_2000 = approx(2): 7.51272e+86
Exact(2): -0.416147
Error: 7.51272e+86
Implementation/Code:
All solver implementation for this assignment was covered in the last assignment.