/**
   * No clamped points added. checking agreement with the extrapolation done by the underlying
   * interpolation
   */
  @Test
  public void notClampedTest() {
    double[][] xValuesSet =
        new double[][] {
          {-5.0, -1.4, 3.2, 3.5, 7.6}, {1., 2., 4.5, 12.1, 14.2}, {-5.2, -3.4, -3.2, -0.9, -0.2}
        };
    double[][] yValuesSet =
        new double[][] {
          {-2.2, 1.1, 1.9, 2.3, -0.1}, {3.4, 5.2, 4.3, 1.1, 0.2}, {1.4, 2.2, 4.1, 1.9, 0.99}
        };

    for (int k = 0; k < xValuesSet.length; ++k) {
      double[] xValues = Arrays.copyOf(xValuesSet[k], xValuesSet[k].length);
      double[] yValues = Arrays.copyOf(yValuesSet[k], yValuesSet[k].length);
      int nData = xValues.length;
      int nKeys = 100;
      double interval = (xValues[2] - xValues[0]) / (nKeys - 1.0);

      int n = INTERP_SENSE.length;
      for (int i = 0; i < n; ++i) {
        ProductPiecewisePolynomialInterpolator interp =
            new ProductPiecewisePolynomialInterpolator(INTERP_SENSE[i]);
        PiecewisePolynomialResult result = interp.interpolateWithSensitivity(xValues, yValues);
        ReciprocalExtrapolator1D extrap1D =
            new ReciprocalExtrapolator1D(
                new ProductPiecewisePolynomialInterpolator1D(INTERP_SENSE[i]));
        Interpolator1DDataBundle data = extrap1D.getDataBundle(xValues, yValues);
        InterpolatorTestUtil.assertArrayRelative("notClampedTest", xValues, data.getKeys(), EPS);
        InterpolatorTestUtil.assertArrayRelative("notClampedTest", yValues, data.getValues(), EPS);
        /* left extrapolation */
        double grad = FUNC.differentiate(result, xValues[0]).getEntry(0);
        for (int j = 1; j < nKeys; ++j) {
          double key = xValues[0] - interval * j;
          double ref = grad * (key - xValues[0]) + yValues[0] * xValues[0];
          InterpolatorTestUtil.assertRelative(
              "notClampedTest", ref / key, extrap1D.interpolate(data, key), EPS);
          double keyUp = key + DELTA;
          double keyDw = key - DELTA;
          double refDeriv =
              0.5 * (extrap1D.interpolate(data, keyUp) - extrap1D.interpolate(data, keyDw)) / DELTA;
          InterpolatorTestUtil.assertRelative(
              "notClampedTest", refDeriv, extrap1D.firstDerivative(data, key), DELTA);
          double[] refSense = new double[nData];
          for (int l = 0; l < nData; ++l) {
            double[] yValuesUp = Arrays.copyOf(yValues, nData);
            double[] yValuesDw = Arrays.copyOf(yValues, nData);
            yValuesUp[l] += DELTA;
            yValuesDw[l] -= DELTA;
            Interpolator1DDataBundle dataUp = extrap1D.getDataBundle(xValues, yValuesUp);
            Interpolator1DDataBundle dataDw = extrap1D.getDataBundle(xValues, yValuesDw);
            refSense[l] =
                0.5
                    * (extrap1D.interpolate(dataUp, key) - extrap1D.interpolate(dataDw, key))
                    / DELTA;
          }
          InterpolatorTestUtil.assertArrayRelative(
              "notClampedTest",
              extrap1D.getNodeSensitivitiesForValue(data, key),
              refSense,
              DELTA * 10.0);
        }
        /* right extrapolation */
        for (int j = 1; j < nKeys; ++j) {
          double key = xValues[nData - 1] + interval * j;
          InterpolatorTestUtil.assertRelative(
              "notClampedTest",
              FUNC.evaluate(result, key).getEntry(0) / key,
              extrap1D.interpolate(data, key),
              EPS);
          double keyUp = key + DELTA;
          double keyDw = key - DELTA;
          double refDeriv =
              0.5 * (extrap1D.interpolate(data, keyUp) - extrap1D.interpolate(data, keyDw)) / DELTA;
          InterpolatorTestUtil.assertRelative(
              "notClampedTest", refDeriv, extrap1D.firstDerivative(data, key), DELTA);
          double[] refSense = new double[nData];
          for (int l = 0; l < nData; ++l) {
            double[] yValuesUp = Arrays.copyOf(yValues, nData);
            double[] yValuesDw = Arrays.copyOf(yValues, nData);
            yValuesUp[l] += DELTA;
            yValuesDw[l] -= DELTA;
            Interpolator1DDataBundle dataUp = extrap1D.getDataBundle(xValues, yValuesUp);
            Interpolator1DDataBundle dataDw = extrap1D.getDataBundle(xValues, yValuesDw);
            refSense[l] =
                0.5
                    * (extrap1D.interpolate(dataUp, key) - extrap1D.interpolate(dataDw, key))
                    / DELTA;
          }
          InterpolatorTestUtil.assertArrayRelative(
              "notClampedTest",
              extrap1D.getNodeSensitivitiesForValue(data, key),
              refSense,
              DELTA * 10.0);
        }
      }
    }
  }