private Map<Double, Interpolator1DDataBundle> testData(final Map<DoublesPair, Double> data) { final Map<Double, Interpolator1DDataBundle> result = new TreeMap<>(); final TreeMap<DoublesPair, Double> sorted = new TreeMap<>(_comparator); sorted.putAll(data); final Iterator<Map.Entry<DoublesPair, Double>> iterator = sorted.entrySet().iterator(); final Map.Entry<DoublesPair, Double> firstEntry = iterator.next(); double x = firstEntry.getKey().first; Map<Double, Double> yzValues = new TreeMap<>(); yzValues.put(firstEntry.getKey().second, firstEntry.getValue()); while (iterator.hasNext()) { final Map.Entry<DoublesPair, Double> nextEntry = iterator.next(); final double newX = nextEntry.getKey().first; if (Double.doubleToLongBits(newX) != Double.doubleToLongBits(x)) { final Interpolator1DDataBundle interpolatorData = _yInterpolator.getDataBundle(yzValues); result.put(x, interpolatorData); yzValues = new TreeMap<>(); yzValues.put(nextEntry.getKey().second, nextEntry.getValue()); x = newX; } else { yzValues.put(nextEntry.getKey().second, nextEntry.getValue()); } if (!iterator.hasNext()) { yzValues.put(nextEntry.getKey().second, nextEntry.getValue()); final Interpolator1DDataBundle interpolatorData = _yInterpolator.getDataBundle(yzValues); result.put(x, interpolatorData); } } return result; }
static { final TreeMap<Double, Double> data = new TreeMap<>(); final TreeMap<Double, Double> transformedData = new TreeMap<>(); double x; for (int i = 0; i < 10; i++) { x = Double.valueOf(i); data.put(x, FUNCTION.evaluate(x)); transformedData.put(x, Math.log(FUNCTION.evaluate(x))); } MODEL = LINEAR.getDataBundle(data); TRANSFORMED_MODEL = INTERPOLATOR.getDataBundle(transformedData); }
@Test public void firstDerivativeTest() { double a = 1.0; double b = 1.5; double c = -0.5; double[] x = new double[] {0., 2., 5.}; 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]; } Interpolator1D interpolator = new NaturalCubicSplineInterpolator1D(); Interpolator1DDataBundle db = interpolator.getDataBundle(x, y); Double grad = interpolator.firstDerivative(db, x[n - 1]); Function1D<Double, Double> func = interpolator.getFunction(db); ScalarFirstOrderDifferentiator diff = new ScalarFirstOrderDifferentiator(); Function1D<Double, Boolean> domain = new Function1D<Double, Boolean>() { @Override public Boolean evaluate(Double x) { return x <= 5.0; } }; Function1D<Double, Double> gradFunc = diff.differentiate(func, domain); assertEquals(gradFunc.evaluate(x[n - 1]), grad, 1e-8); }
@Test(expectedExceptions = IllegalArgumentException.class) public void samexNodesTest() { final double[] xData = new double[] {0.4, 0.7, 0.9, 0.9, 1.3, 1.8}; final double[] yData = new double[] {0.4, 0.5, 0.6, 0.7, 0.8, 1.0}; final Interpolator1DDataBundle data = INTERPOLATOR.getDataBundle(xData, yData); double y = INTERPOLATOR.interpolate(data, 1.0); assertTrue("y: " + y, !Double.isNaN(y)); }
@Override public Double interpolate( final Map<Double, Interpolator1DDataBundle> dataBundle, final DoublesPair value) { ArgumentChecker.notNull(value, "value"); ArgumentChecker.notNull(dataBundle, "data bundle"); final Map<Double, Double> xData = new HashMap<>(); for (final Map.Entry<Double, Interpolator1DDataBundle> entry : dataBundle.entrySet()) { xData.put(entry.getKey(), _yInterpolator.interpolate(entry.getValue(), value.getSecond())); } return _xInterpolator.interpolate(_xInterpolator.getDataBundle(xData), value.getFirst()); }
@Test public void dataBundleTest() { Interpolator1DDataBundle db = INTERPOLATOR.getDataBundle(X_DATA, Y_DATA); double[] keys = db.getKeys(); double[] values = db.getValues(); final int n = X_DATA.length; assertEquals("keys length", n, keys.length); assertEquals("values length", n, values.length); for (int i = 0; i < n; i++) { assertEquals("keys " + i, X_DATA[i], keys[i]); assertEquals("values " + i, Y_DATA[i], values[i]); } }
@Override public Map<DoublesPair, Double> getNodeSensitivitiesForValue( final Map<Double, Interpolator1DDataBundle> dataBundle, final DoublesPair value) { ArgumentChecker.notNull(value, "value"); ArgumentChecker.notNull(dataBundle, "data bundle"); final Map<Double, Double> xData = new HashMap<>(); final double[][] temp = new double[dataBundle.size()][]; int i = 0; for (final Map.Entry<Double, Interpolator1DDataBundle> entry : dataBundle.entrySet()) { // this is the sensitivity of the point projected onto a column of y-points to those points temp[i++] = _yInterpolator.getNodeSensitivitiesForValue(entry.getValue(), value.getSecond()); xData.put(entry.getKey(), _yInterpolator.interpolate(entry.getValue(), value.getSecond())); } // this is the sensitivity of the point to the points projected onto y columns final double[] xSense = _xInterpolator.getNodeSensitivitiesForValue( _xInterpolator.getDataBundle(xData), value.getFirst()); ArgumentChecker.isTrue( xSense.length == dataBundle.size(), "Number of x sensitivities {} must be equal to the data bundle size {}", xSense.length, dataBundle.size()); final Map<DoublesPair, Double> res = new HashMap<>(); double sense; i = 0; int j = 0; for (final Map.Entry<Double, Interpolator1DDataBundle> entry : dataBundle.entrySet()) { final double[] yValues = entry.getValue().getKeys(); for (j = 0; j < yValues.length; j++) { sense = xSense[i] * temp[i][j]; res.put(DoublesPair.of(entry.getKey().doubleValue(), yValues[j]), sense); } i++; } return res; }
@Test public void testDataBundleType1() { assertEquals( INTERPOLATOR.getDataBundle(new double[] {1, 2, 3}, new double[] {1, 2, 3}).getClass(), ArrayInterpolator1DDataBundle.class); }
/** * The node values must be in the transformed space * * @param x The positions of the nodes (not necessarily in order) * @param y The values of the nodes - these must be in the transformed space * @return a data bundle */ @Override public Interpolator1DDataBundle getDataBundle(final double[] x, final double[] y) { return _base.getDataBundle(x, y); }
@Test public void testDataBundleType1() { assertEquals( INTERPOLATOR.getDataBundle(X_DATA, Y_DATA).getClass(), Interpolator1DPiecewisePoynomialDataBundle.class); }
public class PCHIPInterpolator1DTest { private static final Interpolator1D INTERPOLATOR = Interpolator1DFactory.getInterpolator(Interpolator1DFactory.PCHIP); private static final double[] X_DATA = new double[] {0, 0.4, 1.0, 1.8, 2.8, 5}; private static final double[] Y_DATA = new double[] {3., 4., 4.1, 4.5, 7.2, 8.0}; private static final Interpolator1DDataBundle DATA = INTERPOLATOR.getDataBundle(X_DATA, Y_DATA); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullData() { INTERPOLATOR.interpolate(null, 2.3); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullValue() { INTERPOLATOR.interpolate(DATA, null); } @Test public void testDataBundleType1() { assertEquals( INTERPOLATOR.getDataBundle(X_DATA, Y_DATA).getClass(), Interpolator1DPiecewisePoynomialDataBundle.class); } @Test public void testDataBundleType2() { assertEquals( INTERPOLATOR.getDataBundleFromSortedArrays(X_DATA, Y_DATA).getClass(), Interpolator1DPiecewisePoynomialDataBundle.class); } @Test public void dataBundleTest() { Interpolator1DDataBundle db = INTERPOLATOR.getDataBundle(X_DATA, Y_DATA); double[] keys = db.getKeys(); double[] values = db.getValues(); final int n = X_DATA.length; assertEquals("keys length", n, keys.length); assertEquals("values length", n, values.length); for (int i = 0; i < n; i++) { assertEquals("keys " + i, X_DATA[i], keys[i]); assertEquals("values " + i, Y_DATA[i], values[i]); } } @Test public void montonicTest() { final boolean print = false; if (print) { System.out.println("MonotonicCubicInterpolator1DTest"); } final int n = 100; final double low = X_DATA[0]; final double range = X_DATA[X_DATA.length - 1] - X_DATA[0]; double value = INTERPOLATOR.interpolate(DATA, low); for (int i = 1; i < n; i++) { double x = low + i * range / (n - 1); double y = INTERPOLATOR.interpolate(DATA, x); assertTrue(y > value); value = y; if (print) { System.out.println(x + "\t" + y); } } } @Test(expectedExceptions = IllegalArgumentException.class) public void samexNodesTest() { final double[] xData = new double[] {0.4, 0.7, 0.9, 0.9, 1.3, 1.8}; final double[] yData = new double[] {0.4, 0.5, 0.6, 0.7, 0.8, 1.0}; final Interpolator1DDataBundle data = INTERPOLATOR.getDataBundle(xData, yData); double y = INTERPOLATOR.interpolate(data, 1.0); assertTrue("y: " + y, !Double.isNaN(y)); } }