@Override
 public double firstDerivative(final Interpolator1DDataBundle data, final Double value) {
   Validate.notNull(value, "value");
   Validate.notNull(data, "data bundle");
   Validate.isTrue(data instanceof Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle);
   final Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle polyData =
       (Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle) data;
   final DoubleMatrix1D res = FUNC.differentiate(polyData.getPiecewisePolynomialResult(), value);
   return res.getEntry(0);
 }
  @Override
  public double[] getNodeSensitivitiesForValue(
      final Interpolator1DDataBundle data, final Double value) {
    Validate.notNull(value, "value");
    Validate.notNull(data, "data bundle");
    Validate.isTrue(data instanceof Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle);
    final Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle polyData =
        (Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle) data;
    final int nData = polyData.size();
    final double[] res = new double[nData];

    final double eps = polyData.getEps();
    final double small = polyData.getSmall();
    for (int i = 0; i < nData; ++i) {
      final double den =
          Math.abs(polyData.getValues()[i]) < small ? eps : polyData.getValues()[i] * eps;
      final double up =
          FUNC.evaluate(polyData.getPiecewisePolynomialResultUp()[i], value).getData()[0];
      final double dw =
          FUNC.evaluate(polyData.getPiecewisePolynomialResultDw()[i], value).getData()[0];
      res[i] = 0.5 * (up - dw) / den;
    }
    return res;
  }