/** * 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); }