PiecewiseCubicHermiteSplineInterpolatorWithSensitivity extends PiecewisePolynomialInterpolator { @Override public PiecewisePolynomialResultsWithSensitivity interpolateWithSensitivity(final double[] xValues, final double[] yValues) { ArgumentChecker.notNull(xValues, "xValues"); ArgumentChecker.notNull(yValues, "yValues"); ArgumentChecker.isTrue(xValues.length == yValues.length, "xValues length = yValues length"); ArgumentChecker.isTrue(xValues.length > 1, "Data points should be more than 1"); final int nDataPts = xValues.length; for (int i = 0; i < nDataPts; ++i) { ArgumentChecker.isFalse(Double.isNaN(xValues[i]), "xData containing NaN"); ArgumentChecker.isFalse(Double.isInfinite(xValues[i]), "xData containing Infinity"); ArgumentChecker.isFalse(Double.isNaN(yValues[i]), "yData containing NaN"); ArgumentChecker.isFalse(Double.isInfinite(yValues[i]), "yData containing Infinity"); } double[] xValuesSrt = Arrays.copyOf(xValues, nDataPts); double[] yValuesSrt = Arrays.copyOf(yValues, nDataPts); ParallelArrayBinarySort.parallelBinarySort(xValuesSrt, yValuesSrt); for (int i = 1; i < nDataPts; ++i) { ArgumentChecker.isFalse(xValuesSrt[i - 1] == xValuesSrt[i], "xValues should be distinct"); } final DoubleMatrix2D[] temp = solve(xValuesSrt, yValuesSrt); ArgumentChecker.noNulls(temp, "error in solve - some matrices are null"); int n = temp.length; ArgumentChecker.isTrue(n == nDataPts, "wrong number of matricies"); for (int k = 0; k < n; k++) { DoubleMatrix2D m = temp[k]; final int rows = m.getNumberOfRows(); final int cols = m.getNumberOfColumns(); for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { ArgumentChecker.isTrue(Doubles.isFinite(m.getEntry(i, j)), "Matrix contains a NaN or infinite"); } } } DoubleMatrix2D coefMatrix = temp[0]; DoubleMatrix2D[] coefMatrixSense = new DoubleMatrix2D[n - 1]; System.arraycopy(temp, 1, coefMatrixSense, 0, n - 1); return new PiecewisePolynomialResultsWithSensitivity(new DoubleMatrix1D(xValuesSrt), coefMatrix, 4, 1, coefMatrixSense); }  @Override PiecewisePolynomialResultsWithSensitivity interpolateWithSensitivity(final double[] xValues, final double[] yValues); @Override PiecewisePolynomialResult interpolate(final double[] xValues, final double[] yValues); @Override PiecewisePolynomialResult interpolate(double[] xValues, double[][] yValuesMatrix);  }
@Test public void interpolationTest() { final int nExamples = Y.length; final int n = XX.length; for (int example = 0; example < nExamples; example++) { PiecewisePolynomialResult pp = PCHIP_S.interpolateWithSensitivity(X, Y[example]); for (int i = 0; i < n; i++) { final double y = PPVAL_S.evaluate(pp, XX[i]).getEntry(0); assertEquals("example: " + example + ", index:" + i, YY[example][i], y, 1e-14); } } }
@Test public void sensitivityTest() { final int nExamples = Y.length; final int n = XX.length; final int nData = X.length; for (int example = 0; example < nExamples; example++) { PiecewisePolynomialResultsWithSensitivity pp = PCHIP_S.interpolateWithSensitivity(X, Y[example]); DoubleMatrix1D[] fdRes = fdSenseCal(Y[example], XX); for (int i = 0; i < n; i++) { DoubleMatrix1D res = PPVAL_S.nodeSensitivity(pp, XX[i]); for (int j = 0; j < nData; j++) { assertEquals("example: " + example + ", sample: " + i + ", node: " + j, fdRes[j].getEntry(i), res.getEntry(j), 1e-4); } } } }