/**
  * Simpson's integration method.
  *
  * <p>Note that the Commons implementation fails if the lower bound is larger than the upper - in
  * this case, the bounds are reversed and the result negated.
  *
  * @param f The function to integrate, not null
  * @param lower The lower bound, not null
  * @param upper The upper bound, not null
  * @return The result of the integration
  */
 @Override
 public Double integrate(Function<Double, Double> f, Double lower, Double upper) {
   ArgChecker.notNull(f, "function");
   ArgChecker.notNull(lower, "lower bound");
   ArgChecker.notNull(upper, "upper bound");
   try {
     if (lower < upper) {
       return integrator.integrate(MAX_EVAL, CommonsMathWrapper.wrapUnivariate(f), lower, upper);
     }
     log.info("Upper bound was less than lower bound; swapping bounds and negating result");
     return -integrator.integrate(MAX_EVAL, CommonsMathWrapper.wrapUnivariate(f), upper, lower);
   } catch (NumberIsTooSmallException | NumberIsTooLargeException e) {
     throw new MathException(e);
   }
 }
  @Test
  /** Test of integrator for the sine function. */
  public void testSinFunction() {

    UnivariateFunction f = new Gaussian(10, 2);
    UnivariateIntegrator integrator = new SimpsonIntegrator();
    double a, b, expected, tolerance, result;

    a = 8;
    b = 12;
    expected = 0.68269;
    tolerance = 0.00001;

    tolerance = Math.abs(expected * integrator.getRelativeAccuracy());
    result = integrator.integrate(MAX_EVAL, f, a, b);
    assertEquals(expected, result, tolerance);

    log.info(
        "Result: "
            + result
            + ", tolerance: "
            + tolerance
            + " - Relative accuracy: "
            + integrator.getRelativeAccuracy()
            + " - Absolute accuracy: "
            + integrator.getAbsoluteAccuracy()
            + " - Iterations: "
            + integrator.getIterations());

    NormalDistribution distribution = new NormalDistribution(10, 2);
    result = distribution.cumulativeProbability(a, b);
    log.info("Distribution result: " + result);
  }