class NaturalCubicSplineInterpolator1D extends Interpolator1D {

  @Override
  public Double interpolate(final Interpolator1DDataBundle data, final Double value) {
    Validate.notNull(value, "value");
    Validate.notNull(data, "data bundle");
    Validate.isTrue(data instanceof Interpolator1DCubicSplineDataBundle);
    Interpolator1DCubicSplineDataBundle splineData = (Interpolator1DCubicSplineDataBundle) data;
    final int low = data.getLowerBoundIndex(value);
    final int high = low + 1;
    final int n = data.size() - 1;
    final double[] xData = data.getKeys();
    final double[] yData = data.getValues();
    if (data.getLowerBoundIndex(value) == n) {
      return yData[n];
    }
    final double delta = xData[high] - xData[low];
    if (Math.abs(delta) < _eps) {
      throw new MathException("x data points were not distinct");
    }
    final double a = (xData[high] - value) / delta;
    final double b = (value - xData[low]) / delta;
    final double[] y2 = splineData.getSecondDerivatives();
    return a * yData[low] + b * yData[high] + (a * (a * a - 1) * y2[low] + b * (b * b - 1) * y2[high]) * delta * delta / 6.;
  }

  public  NaturalCubicSplineInterpolator1D();
  public  NaturalCubicSplineInterpolator1D(final double eps);

}