class TimeSquareInterpolator1D extends Interpolator1D {

  @Override
  public double[] getNodeSensitivitiesForValue(final Interpolator1DDataBundle data, final Double value) {
    ArgumentChecker.notNull(value, "Value to be interpolated must not be null");
    ArgumentChecker.notNull(data, "Data bundle must not be null");
    final int n = data.size();
    final double[] resultSensitivity = new double[n];
    final InterpolationBoundedValues boundedValues = data.getBoundedValues(value);
    final double x1 = boundedValues.getLowerBoundKey();
    final double y1 = boundedValues.getLowerBoundValue();
    final int index = boundedValues.getLowerBoundIndex();
    if (index == n - 1) {
      resultSensitivity[n - 1] = 1.0;
      return resultSensitivity;
    }
    final double x2 = boundedValues.getHigherBoundKey();
    final double y2 = boundedValues.getHigherBoundValue();
    if ((y1 < EPS) || (y2 < EPS)) {
      throw new NotImplementedException("node sensitivity not implemented when one node is 0 value");
    }
    final double w = (x2 - value) / (x2 - x1);
    final double xy21 = x1 * y1 * y1;
    final double xy22 = x2 * y2 * y2;
    final double xy2 = w * xy21 + (1 - w) * xy22;
    final double resultValue = Math.sqrt(xy2 / value);
    final double resultValueBar = 1.0;
    final double xy2Bar = 0.5 / resultValue / value * resultValueBar;
    final double xy21Bar = w * xy2Bar;
    final double xy22Bar = (1 - w) * xy2Bar;
    final double y2Bar = 2 * x2 * y2 * xy22Bar;
    final double y1Bar = 2 * x1 * y1 * xy21Bar;
    resultSensitivity[index] = y1Bar;
    resultSensitivity[index + 1] = y2Bar;
    return resultSensitivity;
  }

}