Predictor Experiment

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.