CombinedInterpolatorExtrapolator extends Interpolator1D { @Override public double firstDerivative(final Interpolator1DDataBundle data, final Double value) { Validate.notNull(data, "data"); Validate.notNull(value, "value"); if (value < data.firstKey()) { if (_leftExtrapolator != null) { return _leftExtrapolator.firstDerivative(data, value); } } else if (value > data.lastKey()) { if (_rightExtrapolator != null) { return _rightExtrapolator.firstDerivative(data, value); } } return _interpolator.firstDerivative(data, value); } CombinedInterpolatorExtrapolator(final Interpolator1D interpolator);  CombinedInterpolatorExtrapolator(final Interpolator1D interpolator, final Interpolator1D extrapolator);  CombinedInterpolatorExtrapolator(final Interpolator1D interpolator, final Interpolator1D leftExtrapolator, final Interpolator1D rightExtrapolator); @Override Interpolator1DDataBundle getDataBundle(final double[] x, final double[] y); @Override Interpolator1DDataBundle getDataBundleFromSortedArrays(final double[] x, final double[] y); Interpolator1D getInterpolator(); Interpolator1D getLeftExtrapolator(); Interpolator1D getRightExtrapolator(); @Override Double interpolate(final Interpolator1DDataBundle data, final Double value); @Override double firstDerivative(final Interpolator1DDataBundle data, final Double value); @Override double[] getNodeSensitivitiesForValue(final Interpolator1DDataBundle data, final Double value); @Override String toString();  }
@Test public void testBoundary() { for (final double value : X) { assertEquals("dy/dx at " + value, 3d, COMBINED3.firstDerivative(DATA, value), 1e-4); } }