### Question:
ScalarSecondOrderDifferentiator implements Differentiator<Double, Double, Double> { @Override public Function<Double, Double> differentiate(Function<Double, Double> function) { ArgChecker.notNull(function, "function"); return new Function<Double, Double>() { @SuppressWarnings("synthetic-access") @Override public Double apply(Double x) { ArgChecker.notNull(x, "x"); return (function.apply(x + eps) + function.apply(x - eps) - 2d * function.apply(x)) / epsSqr; } }; } ScalarSecondOrderDifferentiator();  ScalarSecondOrderDifferentiator(double eps); @Override Function<Double, Double> differentiate(Function<Double, Double> function); @Override Function<Double, Double> differentiate(Function<Double, Double> function, Function<Double, Boolean> domain);  }### Answer:
@Test public void testNullFunction() { assertThatIllegalArgumentException() .isThrownBy(() -> CALC.differentiate((Function<Double, Double>) null)); }
@Test public void testDomainOut() { Function<Double, Boolean> domain = new Function<Double, Boolean>() { @Override public Boolean apply(final Double x) { return x >= 0d && x <= 1.0e-8; } }; assertThatIllegalArgumentException() .isThrownBy(() -> CALC.differentiate(F, domain).apply(1.0e-9)); }
@Test public void analyticTest() { final double x = 0.2245; assertThat(CALC.differentiate(F).apply(x)).isCloseTo(DX_ANALYTIC.apply(x), offset(EPS)); }
@Test public void domainTest() { final double[] x = new double[] {1.2, 0, Math.PI}; final Function<Double, Double> alFunc = CALC.differentiate(F, DOMAIN); for (int i = 0; i < 3; i++) { assertThat(alFunc.apply(x[i])).isCloseTo(DX_ANALYTIC.apply(x[i]), offset(EPS)); } }