Program: 57425
Project: 57425
Buggy source:
/** 
 * Evaluate the impact of the proposed step on the event handler.
 * @param interpolator step interpolator for the proposed step
 * @return true if the event handler triggers an event beforethe end of the proposed step (this implies the step should be rejected)
 * @exception DerivativeException if the interpolator fails tocompute the switching function somewhere within the step
 * @exception EventException if the switching functioncannot be evaluated
 * @exception ConvergenceException if an event cannot be located
 */
public boolean evaluateStep(final StepInterpolator interpolator) throws DerivativeException, EventException, ConvergenceException {
  try {
    forward=interpolator.isForward();
    final double t1=interpolator.getCurrentTime();
    final int n=Math.max(1,(int)Math.ceil(Math.abs(t1 - t0) / maxCheckInterval));
    final double h=(t1 - t0) / n;
    double ta=t0;
    double ga=g0;
    double tb=t0 + (interpolator.isForward() ? convergence : -convergence);
    for (int i=0; i < n; ++i) {
      tb+=h;
      interpolator.setInterpolatedTime(tb);
      final double gb=handler.g(tb,interpolator.getInterpolatedState());
      if (g0Positive ^ (gb >= 0)) {
        increasing=gb >= ga;
        final UnivariateRealFunction f=new UnivariateRealFunction(){
          public double value(          final double t) throws FunctionEvaluationException {
            try {
              interpolator.setInterpolatedTime(t);
              return handler.g(t,interpolator.getInterpolatedState());
            }
 catch (            DerivativeException e) {
              throw new FunctionEvaluationException(e,t);
            }
catch (            EventException e) {
              throw new FunctionEvaluationException(e,t);
            }
          }
        }
;
        final BrentSolver solver=new BrentSolver();
        solver.setAbsoluteAccuracy(convergence);
        solver.setMaximalIterationCount(maxIterationCount);
        double root;
        try {
          root=(ta <= tb) ? solver.solve(f,ta,tb) : solver.solve(f,tb,ta);
        }
 catch (        IllegalArgumentException iae) {
          root=Double.NaN;
        }
        if (Double.isNaN(root) || ((Math.abs(root - ta) <= convergence) && (Math.abs(root - previousEventTime) <= convergence))) {
          ta=tb;
          ga=gb;
        }
 else         if (Double.isNaN(previousEventTime) || (Math.abs(previousEventTime - root) > convergence)) {
          pendingEventTime=root;
          if (pendingEvent && (Math.abs(t1 - pendingEventTime) <= convergence)) {
            return false;
          }
          pendingEvent=true;
          return true;
        }
      }
 else {
        ta=tb;
        ga=gb;
      }
    }
    pendingEvent=false;
    pendingEventTime=Double.NaN;
    return false;
  }
 catch (  FunctionEvaluationException e) {
    final Throwable cause=e.getCause();
    if ((cause != null) && (cause instanceof DerivativeException)) {
      throw (DerivativeException)cause;
    }
 else     if ((cause != null) && (cause instanceof EventException)) {
      throw (EventException)cause;
    }
    throw new EventException(e);
  }
}

Fixed version (ground truth):
/** 
 * Evaluate the impact of the proposed step on the event handler.
 * @param interpolator step interpolator for the proposed step
 * @return true if the event handler triggers an event beforethe end of the proposed step (this implies the step should be rejected)
 * @exception DerivativeException if the interpolator fails tocompute the switching function somewhere within the step
 * @exception EventException if the switching functioncannot be evaluated
 * @exception ConvergenceException if an event cannot be located
 */
public boolean evaluateStep(final StepInterpolator interpolator) throws DerivativeException, EventException, ConvergenceException {
  try {
    forward=interpolator.isForward();
    final double t1=interpolator.getCurrentTime();
    final int n=Math.max(1,(int)Math.ceil(Math.abs(t1 - t0) / maxCheckInterval));
    final double h=(t1 - t0) / n;
    double ta=t0;
    double ga=g0;
    double tb=t0 + (interpolator.isForward() ? convergence : -convergence);
    for (int i=0; i < n; ++i) {
      tb+=h;
      interpolator.setInterpolatedTime(tb);
      final double gb=handler.g(tb,interpolator.getInterpolatedState());
      if (g0Positive ^ (gb >= 0)) {
        if (ga * gb > 0) {
          final double epsilon=(forward ? 0.25 : -0.25) * convergence;
          for (int k=0; (k < 4) && (ga * gb > 0); ++k) {
            ta+=epsilon;
            interpolator.setInterpolatedTime(ta);
            ga=handler.g(ta,interpolator.getInterpolatedState());
          }
          if (ga * gb > 0) {
            throw MathRuntimeException.createInternalError(null);
          }
        }
        increasing=gb >= ga;
        final UnivariateRealFunction f=new UnivariateRealFunction(){
          public double value(          final double t) throws FunctionEvaluationException {
            try {
              interpolator.setInterpolatedTime(t);
              return handler.g(t,interpolator.getInterpolatedState());
            }
 catch (            DerivativeException e) {
              throw new FunctionEvaluationException(e,t);
            }
catch (            EventException e) {
              throw new FunctionEvaluationException(e,t);
            }
          }
        }
;
        final BrentSolver solver=new BrentSolver();
        solver.setAbsoluteAccuracy(convergence);
        solver.setMaximalIterationCount(maxIterationCount);
        final double root=(ta <= tb) ? solver.solve(f,ta,tb) : solver.solve(f,tb,ta);
        if ((Math.abs(root - ta) <= convergence) && (Math.abs(root - previousEventTime) <= convergence)) {
          ta=tb;
          ga=gb;
        }
 else         if (Double.isNaN(previousEventTime) || (Math.abs(previousEventTime - root) > convergence)) {
          pendingEventTime=root;
          if (pendingEvent && (Math.abs(t1 - pendingEventTime) <= convergence)) {
            return false;
          }
          pendingEvent=true;
          return true;
        }
      }
 else {
        ta=tb;
        ga=gb;
      }
    }
    pendingEvent=false;
    pendingEventTime=Double.NaN;
    return false;
  }
 catch (  FunctionEvaluationException e) {
    final Throwable cause=e.getCause();
    if ((cause != null) && (cause instanceof DerivativeException)) {
      throw (DerivativeException)cause;
    }
 else     if ((cause != null) && (cause instanceof EventException)) {
      throw (EventException)cause;
    }
    throw new EventException(e);
  }
}