DoubleQuadraticInterpolator1D extends Interpolator1D { @Override public double firstDerivative(final Interpolator1DDataBundle data, final Double value) { ArgumentChecker.notNull(value, "value"); ArgumentChecker.notNull(data, "data bundle"); ArgumentChecker.isTrue(data instanceof Interpolator1DDoubleQuadraticDataBundle, "data bundle is of wrong type"); final Interpolator1DDoubleQuadraticDataBundle quadraticData = (Interpolator1DDoubleQuadraticDataBundle) data; final int low = data.getLowerBoundIndex(value); final int high = low + 1; final int n = data.size() - 1; final double[] xData = data.getKeys(); if (n == 0) { return 0.0; } if (low == 0 || n == 1) { final RealPolynomialFunction1D quadraticFirstDerivative = quadraticData.getQuadraticFirstDerivative(0); final double x = value - xData[1]; return quadraticFirstDerivative.evaluate(x); } else if (high >= n) { final RealPolynomialFunction1D quadraticFirstDerivative = quadraticData.getQuadraticFirstDerivative(n - 2); final double x = value - xData[n - 1]; return quadraticFirstDerivative.evaluate(x); } final RealPolynomialFunction1D quadratic1 = quadraticData.getQuadratic(low - 1); final RealPolynomialFunction1D quadratic2 = quadraticData.getQuadratic(high - 1); final RealPolynomialFunction1D quadratic1FirstDerivative = quadraticData.getQuadraticFirstDerivative(low - 1); final RealPolynomialFunction1D quadratic2FirstDerivative = quadraticData.getQuadraticFirstDerivative(high - 1); final double w = _weightFunction.getWeight((xData[high] - value) / (xData[high] - xData[low])); final double res = w * quadratic1FirstDerivative.evaluate(value - xData[low]) + (1 - w) * quadratic2FirstDerivative.evaluate(value - xData[high]) + (quadratic2.evaluate(value - xData[high]) - quadratic1.evaluate(value - xData[low])) / (xData[high] - xData[low]); return res; } DoubleQuadraticInterpolator1D();  DoubleQuadraticInterpolator1D(final WeightingFunction weightFunction); @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 Interpolator1DDoubleQuadraticDataBundle getDataBundle(final double[] x, final double[] y); @Override Interpolator1DDoubleQuadraticDataBundle getDataBundleFromSortedArrays(final double[] x, final double[] y);  }
@Test public void firstDerivativeTest() { double a = 1.34; double b = 7.0 / 3.0; double c = -0.52; double[] x = new double[] {-11.0 / 2.3, 0.0, 0.01, 2.71, 17.0 / 3.2 }; int n = x.length; double[] y = new double[n]; for (int i = 0; i < n; i++) { y[i] = a + b * x[i] + c * x[i] * x[i]; } Interpolator1DDataBundle db = INTERPOLATOR.getDataBundle(x, y); Double grad = INTERPOLATOR.firstDerivative(db, x[n - 1]); assertEquals(b + 2 * c * x[n - 1], grad, 1e-15); }