QuadraticInterpolator implements Interpolator { @Override public InterpolatingFunction interpolate(double[] x, double[] y) { if (x.length != y.length) { throw new IllegalArgumentException(MessageFormat.format( "Dimension mismatch {0} != {1}.", x.length, y.length)); } if (x.length < minNumPoints) { throw new IllegalArgumentException(MessageFormat.format( "{0} points are required, got only {1}.", minNumPoints, x.length)); } for (int i = 0; i < x.length - 1; i++) { if (x[i] >= x[i + 1]) { throw new IllegalArgumentException(MessageFormat.format( "Points {0} and {1} are not strictly increasing ({2} >= {3}).", i, i + 1, x[i], x[i + 1])); } } int numberOfResultingFunctions = x.length - 2; PolynomialFunction[] polynomials = new PolynomialFunction[numberOfResultingFunctions]; for (int row = 1; row <= numberOfResultingFunctions; row++) { final double[] coefficients = getCoefficientsForThreePoints(x[row - 1], x[row], x[row + 1], y[row - 1], y[row], y[row + 1]); polynomials[row - 1] = new PolynomialFunction(coefficients); } double[] knots = new double[x.length - 1]; System.arraycopy(x, 0, knots, 0, x.length - 2); knots[knots.length - 1] = x[x.length - 1]; return new InterpolatingFunction(knots, polynomials); }  @Override int getMinNumPoints(); @Override InterpolatingFunction interpolate(double[] x, double[] y);  }
@Test public void testInterpolationOfStraightLine() { double[] x = new double[]{0d, 2d, 4d, 6d, 8d}; double[] y = new double[]{1d, 1d, 1d, 1d, 1d}; final InterpolatingFunction function = quadraticInterpolator.interpolate(x, y); assertKnownValuesAreAssignedCorrectly(x, y, function); assertEquals(1d, function.value(1d), 0); assertEquals(1d, function.value(3d), 0); assertEquals(1d, function.value(5d), 0); assertEquals(1d, function.value(7d), 0); }
@Test public void testInterpolationOfFunctionWithPositiveAndNegativeSlope() { double[] x = new double[]{0d, 2d, 4d, 6d, 8d}; double[] y = new double[]{1d, 3d, 5d, 3d, 1d}; final InterpolatingFunction function = quadraticInterpolator.interpolate(x, y); assertKnownValuesAreAssignedCorrectly(x, y, function); assertEquals(2d, function.value(1d), 0); assertEquals(4d, function.value(3d), 0.5); assertEquals(4d, function.value(5d), 0.01); assertEquals(2d, function.value(7d), 0); }
@Test public void testInterpolationOfQuadraticFunction() { double[] x = new double[]{0d, 2d, 4d, 6d, 8d}; double[] y = new double[]{Math.pow(0d, 2), Math.pow(2d, 2), Math.pow(4d, 2), Math.pow(6d, 2), Math.pow(8d, 2)}; final InterpolatingFunction function = quadraticInterpolator.interpolate(x, y); assertKnownValuesAreAssignedCorrectly(x, y, function); assertEquals(Math.pow(1d, 2), function.value(1d), 0); assertEquals(Math.pow(3d, 2), function.value(3d), 0); assertEquals(Math.pow(5d, 2), function.value(5d), 0); assertEquals(Math.pow(7d, 2), function.value(7d), 0); }
@Test public void testInterpolationOfSinusFunction() { double[] x = new double[]{0d, 2d, 4d, 6d, 8d, 10d, 12d, 14d, 16d}; double[] y = new double[]{Math.sin(0d), Math.sin(Math.PI / 8), Math.sin(Math.PI / 4), Math.sin(Math.PI / 8 * 3), Math.sin(Math.PI / 2), Math.sin(Math.PI / 8 * 5), Math.sin(Math.PI / 4 * 3), Math.sin(Math.PI / 8 * 7), Math.sin(Math.PI)}; final InterpolatingFunction function = quadraticInterpolator.interpolate(x, y); assertKnownValuesAreAssignedCorrectly(x, y, function); assertEquals(Math.sin(Math.PI / 16), function.value(1d), 1e-2); assertEquals(Math.sin(Math.PI / 16 * 3), function.value(3d), 1e-2); assertEquals(Math.sin(Math.PI / 16 * 5), function.value(5d), 1e-2); assertEquals(Math.sin(Math.PI / 16 * 7), function.value(7d), 1e-3); assertEquals(Math.sin(Math.PI / 16 * 9), function.value(9d), 1e-2); assertEquals(Math.sin(Math.PI / 16 * 11), function.value(11d), 1e-2); assertEquals(Math.sin(Math.PI / 16 * 13), function.value(13d), 1e-2); assertEquals(Math.sin(Math.PI / 16 * 15), function.value(15d), 1e-2); }
@Test public void testInterpolationOfRandomValues() { double[] x = new double[]{0d, 4d, 7d, 8d, 10d, 14d, 16d}; double[] y = new double[]{2d, 1d, 8d, 5d, 4d, 1d, 7d}; final InterpolatingFunction function = quadraticInterpolator.interpolate(x, y); assertKnownValuesAreAssignedCorrectly(x, y, function); assertEquals(0.03, function.value(2d), 1e-2); assertEquals(7.5, function.value(5.5), 1e-2); assertEquals(6.3, function.value(7.5), 1e-2); assertEquals(4.54, function.value(9d), 1e-2); assertEquals(0, function.value(12d), 1e-2); assertEquals(3.38, function.value(15d), 1e-2); }