public void testEvents() throws DerivativeException, IntegratorException {

    TestProblem4 pb = new TestProblem4();
    double minStep = 0;
    double maxStep = pb.getFinalTime() - pb.getInitialTime();
    double scalAbsoluteTolerance = 1.0e-8;
    double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;

    FirstOrderIntegrator integ =
        new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
    TestProblemHandler handler = new TestProblemHandler(pb, integ);
    integ.addStepHandler(handler);
    EventHandler[] functions = pb.getEventsHandlers();
    for (int l = 0; l < functions.length; ++l) {
      integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-8 * maxStep, 1000);
    }
    assertEquals(functions.length, integ.getEventHandlers().size());
    integ.integrate(
        pb,
        pb.getInitialTime(),
        pb.getInitialState(),
        pb.getFinalTime(),
        new double[pb.getDimension()]);

    assertTrue(handler.getMaximalValueError() < 1.0e-7);
    assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
    assertEquals(12.0, handler.getLastTime(), 1.0e-8 * maxStep);
    integ.clearEventHandlers();
    assertEquals(0, integ.getEventHandlers().size());
  }
  public void testIncreasingTolerance() throws DerivativeException, IntegratorException {

    int previousCalls = Integer.MAX_VALUE;
    for (int i = -12; i < -2; ++i) {
      TestProblem1 pb = new TestProblem1();
      double minStep = 0;
      double maxStep = pb.getFinalTime() - pb.getInitialTime();
      double scalAbsoluteTolerance = Math.pow(10.0, i);
      double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;

      FirstOrderIntegrator integ =
          new HighamHall54Integrator(
              minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
      TestProblemHandler handler = new TestProblemHandler(pb, integ);
      integ.addStepHandler(handler);
      integ.integrate(
          pb,
          pb.getInitialTime(),
          pb.getInitialState(),
          pb.getFinalTime(),
          new double[pb.getDimension()]);

      // the 1.3 factor is only valid for this test
      // and has been obtained from trial and error
      // there is no general relation between local and global errors
      assertTrue(handler.getMaximalValueError() < (1.3 * scalAbsoluteTolerance));
      assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);

      int calls = pb.getCalls();
      assertEquals(integ.getEvaluations(), calls);
      assertTrue(calls <= previousCalls);
      previousCalls = calls;
    }
  }
  public void testBackward() throws DerivativeException, IntegratorException {

    TestProblem5 pb = new TestProblem5();
    double minStep = 0;
    double maxStep = pb.getFinalTime() - pb.getInitialTime();
    double scalAbsoluteTolerance = 1.0e-8;
    double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;

    FirstOrderIntegrator integ =
        new GraggBulirschStoerIntegrator(
            minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
    TestProblemHandler handler = new TestProblemHandler(pb, integ);
    integ.addStepHandler(handler);
    integ.integrate(
        pb,
        pb.getInitialTime(),
        pb.getInitialState(),
        pb.getFinalTime(),
        new double[pb.getDimension()]);

    assertTrue(handler.getLastError() < 9.0e-10);
    assertTrue(handler.getMaximalValueError() < 9.0e-10);
    assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
    assertEquals("Gragg-Bulirsch-Stoer", integ.getName());
  }
 private double getMaxError(FirstOrderIntegrator integrator, TestProblemAbstract pb)
     throws DerivativeException, IntegratorException {
   TestProblemHandler handler = new TestProblemHandler(pb, integrator);
   integrator.addStepHandler(handler);
   integrator.integrate(
       pb,
       pb.getInitialTime(),
       pb.getInitialState(),
       pb.getFinalTime(),
       new double[pb.getDimension()]);
   return handler.getMaximalValueError();
 }
  public void testIncreasingTolerance() throws DerivativeException, IntegratorException {

    int previousCalls = Integer.MAX_VALUE;
    for (int i = -12; i < -4; ++i) {
      TestProblem1 pb = new TestProblem1();
      double minStep = 0;
      double maxStep = pb.getFinalTime() - pb.getInitialTime();
      double absTolerance = Math.pow(10.0, i);
      double relTolerance = absTolerance;

      FirstOrderIntegrator integ =
          new GraggBulirschStoerIntegrator(
              minStep, maxStep,
              absTolerance, relTolerance);
      TestProblemHandler handler = new TestProblemHandler(pb, integ);
      integ.addStepHandler(handler);
      integ.integrate(
          pb,
          pb.getInitialTime(),
          pb.getInitialState(),
          pb.getFinalTime(),
          new double[pb.getDimension()]);

      // the coefficients are only valid for this test
      // and have been obtained from trial and error
      // there is no general relation between local and global errors
      double ratio = handler.getMaximalValueError() / absTolerance;
      assertTrue(ratio < 2.4);
      assertTrue(ratio > 0.02);
      assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);

      int calls = pb.getCalls();
      assertEquals(integ.getEvaluations(), calls);
      assertTrue(calls <= previousCalls);
      previousCalls = calls;
    }
  }