ConstrainedCubicSplineInterpolator extends PiecewisePolynomialInterpolator { @Override public PiecewisePolynomialResult interpolate(final double[] xValues, final double[] yValues) { ArgumentChecker.notNull(xValues, "xValues"); ArgumentChecker.notNull(yValues, "yValues"); ArgumentChecker.isTrue(xValues.length == yValues.length, "(xValues length = yValues length) should be true"); ArgumentChecker.isTrue(xValues.length > 1, "Data points should be >= 2"); final int nDataPts = xValues.length; for (int i = 0; i < nDataPts; ++i) { ArgumentChecker.isFalse(Double.isNaN(xValues[i]), "xValues containing NaN"); ArgumentChecker.isFalse(Double.isInfinite(xValues[i]), "xValues containing Infinity"); ArgumentChecker.isFalse(Double.isNaN(yValues[i]), "yValues containing NaN"); ArgumentChecker.isFalse(Double.isInfinite(yValues[i]), "yValues containing Infinity"); } for (int i = 0; i < nDataPts - 1; ++i) { for (int j = i + 1; j < nDataPts; ++j) { ArgumentChecker.isFalse(xValues[i] == xValues[j], "xValues should be distinct"); } } double[] xValuesSrt = Arrays.copyOf(xValues, nDataPts); double[] yValuesSrt = Arrays.copyOf(yValues, nDataPts); ParallelArrayBinarySort.parallelBinarySort(xValuesSrt, yValuesSrt); final double[] intervals = _solver.intervalsCalculator(xValuesSrt); final double[] slopes = _solver.slopesCalculator(yValuesSrt, intervals); final double[] first = firstDerivativeCalculator(slopes); final double[][] coefs = _solver.solve(yValuesSrt, intervals, slopes, first); for (int i = 0; i < nDataPts - 1; ++i) { double ref = 0.; for (int j = 0; j < 4; ++j) { ref += coefs[i][j] * Math.pow(intervals[i], 3 - j); ArgumentChecker.isFalse(Double.isNaN(coefs[i][j]), "Too large input"); ArgumentChecker.isFalse(Double.isInfinite(coefs[i][j]), "Too large input"); } final double bound = Math.max(Math.abs(ref) + Math.abs(yValuesSrt[i + 1]), 1.e-1); ArgumentChecker.isTrue(Math.abs(ref - yValuesSrt[i + 1]) < ERROR * bound, "Input is too large/small or data points are too close"); } return new PiecewisePolynomialResult(new DoubleMatrix1D(xValuesSrt), new DoubleMatrix2D(coefs), 4, 1); }  @Override PiecewisePolynomialResult interpolate(final double[] xValues, final double[] yValues); @Override PiecewisePolynomialResult interpolate(final double[] xValues, final double[][] yValuesMatrix); @Override PiecewisePolynomialResultsWithSensitivity interpolateWithSensitivity(final double[] xValues, final double[] yValues);  }
@Test public void linearTest() { final double[] xValues = new double[] {1., 2., 3., 4., 5., 6. }; final int nData = xValues.length; final double[] yValues = new double[nData]; for (int i = 0; i < nData; ++i) { yValues[i] = xValues[i] / 7. + 1 / 11.; } final double[][] coefsMatExp = new double[][] { {0., 0., 1. / 7., yValues[0] }, {0., 0., 1. / 7., yValues[1] }, {0., 0., 1. / 7., yValues[2] }, {0., 0., 1. / 7., yValues[3] }, {0., 0., 1. / 7., yValues[4] } }; PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interp = new ConstrainedCubicSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); assertEquals(result.getDimensions(), 1); assertEquals(result.getNumberOfIntervals(), 5); assertEquals(result.getOrder(), 4); for (int i = 0; i < result.getNumberOfIntervals(); ++i) { for (int j = 0; j < result.getOrder(); ++j) { final double ref = Math.abs(coefsMatExp[i][j]) == 0. ? 1. : Math.abs(coefsMatExp[i][j]); assertEquals(result.getCoefMatrix().getData()[i][j], coefsMatExp[i][j], ref * EPS); } } final int nKeys = 101; for (int i = 0; i < nKeys; ++i) { final double key = 1. + 5. / (nKeys - 1) * i; final double ref = key / 7. + 1 / 11.; assertEquals(function.evaluate(result, key).getData()[0], ref, ref * EPS); } }
@Test public void linearMultiTest() { final double[] xValues = new double[] {1., 2., 3., 4., 5., 6. }; final int nData = xValues.length; final double[][] yValues = new double[2][nData]; for (int i = 0; i < nData; ++i) { yValues[0][i] = xValues[i] / 7. + 1 / 11.; yValues[1][i] = xValues[i] / 13. + 1 / 3.; } final double[][] coefsMatExp = new double[][] { {0., 0., 1. / 7., yValues[0][0] }, {0., 0., 1. / 13., yValues[1][0] }, {0., 0., 1. / 7., yValues[0][1] }, {0., 0., 1. / 13., yValues[1][1] }, {0., 0., 1. / 7., yValues[0][2] }, {0., 0., 1. / 13., yValues[1][2] }, {0., 0., 1. / 7., yValues[0][3] }, {0., 0., 1. / 13., yValues[1][3] }, {0., 0., 1. / 7., yValues[0][4] }, {0., 0., 1. / 13., yValues[1][4] } }; PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interp = new ConstrainedCubicSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); assertEquals(result.getDimensions(), 2); assertEquals(result.getNumberOfIntervals(), 5); assertEquals(result.getOrder(), 4); for (int i = 0; i < result.getNumberOfIntervals() * result.getDimensions(); ++i) { for (int j = 0; j < result.getOrder(); ++j) { final double ref = Math.abs(coefsMatExp[i][j]) == 0. ? 1. : Math.abs(coefsMatExp[i][j]); assertEquals(result.getCoefMatrix().getData()[i][j], coefsMatExp[i][j], ref * EPS); } } final int nKeys = 101; for (int i = 0; i < nKeys; ++i) { final double key = 1. + 5. / (nKeys - 1) * i; final double ref = key / 7. + 1 / 11.; assertEquals(function.evaluate(result, key).getData()[0], ref, ref * EPS); } }
@Test public void extremumTest() { final double[] xValues = new double[] {1., 2., 3., 4., 5., 6., 7. }; final double[] yValues = new double[] {1., 1., 4., 5., 4., 1., 1. }; PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interp = new ConstrainedCubicSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); assertEquals(result.getDimensions(), 1); assertEquals(result.getNumberOfIntervals(), 6); assertEquals(result.getOrder(), 4); final int nKeys = 31; double key0 = 1.; for (int i = 1; i < nKeys; ++i) { final double key = 1. + 3. / (nKeys - 1) * i; assertTrue(function.evaluate(result, key).getData()[0] - function.evaluate(result, key0).getData()[0] >= 0.); key0 = 1. + 3. / (nKeys - 1) * i; } key0 = 4.; for (int i = 1; i < nKeys; ++i) { final double key = 4. + 3. / (nKeys - 1) * i; assertTrue(function.evaluate(result, key).getData()[0] - function.evaluate(result, key0).getData()[0] <= 0.); key0 = 4. + 3. / (nKeys - 1) * i; } }
@Test public void sampleDataTest() { final double[] xValues = new double[] {0., 10., 30., 50., 70., 90., 100. }; final double[] yValues = new double[] {30., 130., 150., 150., 170., 220., 320. }; PiecewisePolynomialInterpolator interp = new ConstrainedCubicSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); final double[][] coefsMatPartExp = new double[][] { {-9. / 220., 0., 155. / 11., 30. }, {-1. / 2200., -7. / 220., 20. / 11., 130. }, {0., 0., 0., 150. } }; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 4; ++j) { final double ref = Math.abs(coefsMatPartExp[i][j]) == 0. ? 1. : Math.abs(coefsMatPartExp[i][j]); assertEquals(result.getCoefMatrix().getData()[i][j], coefsMatPartExp[i][j], ref * EPS); } } int nKeys = 101; double key0 = 0.; for (int i = 1; i < nKeys; ++i) { final double key = 0. + 100. / (nKeys - 1) * i; assertTrue(function.evaluate(result, key).getData()[0] - function.evaluate(result, key0).getData()[0] >= -EPS); key0 = 0. + 100. / (nKeys - 1) * i; } }
@Test(expectedExceptions = IllegalArgumentException.class) public void dataShortTest() { final double[] xValues = new double[] {1. }; final double[] yValues = new double[] {0., }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void dataShortMultiTest() { final double[] xValues = new double[] {1. }; final double[][] yValues = new double[][] { {0. }, {0.1 } }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void dataDiffTest() { final double[] xValues = new double[] {1., 2., 3., 4. }; final double[] yValues = new double[] {0., 0.1, 3. }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void dataDiffMultiTest() { final double[] xValues = new double[] {1., 2., 3., 4. }; final double[][] yValues = new double[][] { {0., 0.1, 3. }, {0., 0.1, 3. } }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void coincideDataTest() { final double[] xValues = new double[] {1., 1., 3. }; final double[] yValues = new double[] {0., 0.1, 0.05 }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void coincideDataMultiTest() { final double[] xValues = new double[] {1., 2., 2. }; final double[][] yValues = new double[][] { {0., 0.1, 0.05 }, {0., 0.1, 1.05 } }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void nullXdataTest() { double[] xValues = new double[] {1., 2., 3., 4. }; double[] yValues = new double[] {0., 0.1, 0.05, 0.2 }; xValues = null; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void nullYdataTest() { double[] xValues = new double[] {1., 2., 3., 4. }; double[] yValues = new double[] {0., 0.1, 0.05, 0.2 }; yValues = null; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void nullXdataMultiTest() { double[] xValues = new double[] {1., 2., 3., 4. }; double[][] yValues = new double[][] { {0., 0.1, 0.05, 0.2 }, {0., 0.1, 0.05, 0.2 } }; xValues = null; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void nullYdataMultiTest() { double[] xValues = new double[] {1., 2., 3., 4. }; double[][] yValues = new double[][] { {0., 0.1, 0.05, 0.2 }, {0., 0.1, 0.05, 0.2 } }; yValues = null; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void infXdataTest() { double[] xValues = new double[] {1., 2., 3., INF }; double[] yValues = new double[] {0., 0.1, 0.05, 0.2 }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void infYdataTest() { double[] xValues = new double[] {1., 2., 3., 4. }; double[] yValues = new double[] {0.1, 0.05, 0.2, INF }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void nanXdataTest() { double[] xValues = new double[] {1., 2., 3., Double.NaN }; double[] yValues = new double[] {0., 0.1, 0.05, 0.2 }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void nanYdataTest() { double[] xValues = new double[] {1., 2., 3., 4. }; double[] yValues = new double[] {0.1, 0.05, 0.2, Double.NaN }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void infXdataMultiTest() { double[] xValues = new double[] {1., 2., 3., INF }; double[][] yValues = new double[][] { {0., 0.1, 0.05, 0.2 }, {0., 0.1, 0.05, 0.2 } }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void infYdataMultiTest() { double[] xValues = new double[] {1., 2., 3., 4. }; double[][] yValues = new double[][] { {0.1, 0.05, 0.2, 1. }, {0.1, 0.05, 0.2, INF } }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void nanXdataMultiTest() { double[] xValues = new double[] {1., 2., 3., Double.NaN }; double[][] yValues = new double[][] { {0., 0.1, 0.05, 0.2 }, {0., 0.1, 0.05, 0.2 } }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void nanYdataMultiTest() { double[] xValues = new double[] {1., 2., 3., 4. }; double[][] yValues = new double[][] { {0.1, 0.05, 0.2, 1.1 }, {0.1, 0.05, 0.2, Double.NaN } }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void notReconnectedTest() { double[] xValues = new double[] {1., 2., 2.0000001, 4. }; double[] yValues = new double[] {2., 3., 40000000., 5. }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }
@Test(expectedExceptions = IllegalArgumentException.class) public void notReconnectedMultiTest() { double[] xValues = new double[] {1., 2., 2.0000001, 4. }; double[][] yValues = new double[][] {{2., 3., 40000000., 5. } }; PiecewisePolynomialInterpolator interpPos = new ConstrainedCubicSplineInterpolator(); interpPos.interpolate(xValues, yValues); }