/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.math.interpolation.data; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertTrue; import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; import java.util.Arrays; import org.testng.annotations.Test; import com.opengamma.analytics.math.function.Function1D; import com.opengamma.analytics.math.function.RealPolynomialFunction1D; import com.opengamma.util.test.TestGroup; /** * Test. */ @Test(groups = TestGroup.UNIT) public class Interpolator1DCubicSplineDataBundleTest { private static final RealPolynomialFunction1D LINEAR = new RealPolynomialFunction1D(new double[] {1, 3}); private static final RealPolynomialFunction1D CUBIC = new RealPolynomialFunction1D(new double[] {1, 3, 3, 1}); private static final Function1D<Double, Double> NORMAL = new Function1D<Double, Double>() { @Override public Double evaluate(final Double x) { return Math.exp(-x * x / 2); } }; private static final double[] X; private static final double[] Y; private static final Interpolator1DCubicSplineDataBundle DATA; private static final double EPS = 1e-12; static { final int n = 10; X = new double[n]; Y = new double[n]; for (int i = 0; i < n; i++) { X[i] = 2 * (i + 1); Y[i] = CUBIC.evaluate(X[i]); } DATA = new Interpolator1DCubicSplineDataBundle(new ArrayInterpolator1DDataBundle(X, Y)); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullData() { new Interpolator1DCubicSplineDataBundle(null); } @Test(expectedExceptions = IllegalArgumentException.class) public void testSetNegativeIndex() { DATA.setYValueAtIndex(-2, 3); } @Test(expectedExceptions = IllegalArgumentException.class) public void testSetHighIndex() { DATA.setYValueAtIndex(100, 4); } @Test public void testGetters() { assertTrue(DATA.containsKey(2.)); assertFalse(DATA.containsKey(3.4)); assertEquals(DATA.firstKey(), 2., EPS); assertEquals(DATA.firstValue(), CUBIC.evaluate(2.), EPS); assertEquals(DATA.get(4.), CUBIC.evaluate(4.), EPS); assertArrayEquals(DATA.getKeys(), X, 0); assertEquals(DATA.getLowerBoundIndex(7.), 2); assertEquals(DATA.getLowerBoundKey(7.), 6, EPS); assertArrayEquals(DATA.getValues(), Y, EPS); assertEquals(DATA.higherKey(7.), 8, 0); assertEquals(DATA.higherValue(7.), CUBIC.evaluate(8.), EPS); assertEquals(DATA.lastKey(), 20., EPS); assertEquals(DATA.lastValue(), CUBIC.evaluate(20.), EPS); assertEquals(DATA.size(), 10); final InterpolationBoundedValues boundedValues = DATA.getBoundedValues(4.); assertEquals(boundedValues.getLowerBoundIndex(), 1); assertEquals(boundedValues.getLowerBoundKey(), 4., EPS); assertEquals(boundedValues.getLowerBoundValue(), CUBIC.evaluate(4.), EPS); assertEquals(boundedValues.getHigherBoundKey(), 6., EPS); assertEquals(boundedValues.getHigherBoundValue(), CUBIC.evaluate(6.), EPS); } @Test public void testEqualsAndHashCode() { Interpolator1DCubicSplineDataBundle other = new Interpolator1DCubicSplineDataBundle( new ArrayInterpolator1DDataBundle(X, Y)); assertEquals(other, DATA); assertEquals(other.hashCode(), DATA.hashCode()); other = new Interpolator1DCubicSplineDataBundle(new ArrayInterpolator1DDataBundle(Y, Y)); assertFalse(other.equals(DATA)); other = new Interpolator1DCubicSplineDataBundle(new ArrayInterpolator1DDataBundle(X, X)); assertFalse(other.equals(DATA)); } @Test public void testSecondDerivatives() { int n = 10; double x[] = new double[n]; double y[] = new double[n]; for (int i = 0; i < n; i++) { x[i] = (i - 5); y[i] = LINEAR.evaluate(x[i]); } Interpolator1DCubicSplineDataBundle data = new Interpolator1DCubicSplineDataBundle( new ArrayInterpolator1DDataBundle(x, y)); double[] y2 = data.getSecondDerivatives(); assertEquals(y2.length, 10); assertEquals(y2[0], 0, EPS); assertEquals(y2[y2.length - 1], 0, EPS); for (final double element : y2) { assertEquals(0.0, element, 0.0); } n = 150; x = new double[n]; y = new double[n]; for (int i = 0; i < n; i++) { x[i] = (i - 75) / 10.; y[i] = NORMAL.evaluate(x[i]); } data = new Interpolator1DCubicSplineDataBundle(new ArrayInterpolator1DDataBundle(x, y)); y2 = data.getSecondDerivatives(); for (int i = 0; i < n; i++) { final double temp = (x[i] * x[i] - 1) * Math.exp(-x[i] * x[i] / 2.0); assertEquals(temp, y2[i], 1e-2); } } // @Test // public void testLargeData() { // int n = 499; // double x[] = new double[n]; // double y[] = new double[n]; // for (int i = 0; i < n; i++) { // x[i] = i / 20.0; // y[i] = Math.sin(x[i]); // } // Interpolator1DCubicSplineDataBundle data = new Interpolator1DCubicSplineDataBundle( // new ArrayInterpolator1DDataBundle(x, y)); // // double[] y2 = data.getSecondDerivatives(); // } @Test public void testSecondDerivativesSensitivities() { final double[][] sense = DATA.getSecondDerivativesSensitivities(); final int n = X.length; assertEquals(sense.length, n, 0); assertEquals(sense[0].length, n, 0); for (int i = 0; i < n; i++) { assertEquals(sense[0][i], 0.0, 0.0); assertEquals(sense[n - 1][i], 0.0, 0.0); } } @Test public void testSetYValue() { final int n = X.length; final double[] x = Arrays.copyOf(X, n); final double[] y = Arrays.copyOf(Y, n); Arrays.sort(x); Arrays.sort(y); Interpolator1DCubicSplineDataBundle data1 = new Interpolator1DCubicSplineDataBundle( new ArrayInterpolator1DDataBundle(x, y)); Interpolator1DCubicSplineDataBundle data2; final double newY = 120; final double[] yData = Arrays.copyOf(y, n); double[] y21, y22; double[][] dy21, dy22; for (int i = 0; i < n; i++) { yData[i] = newY; data1.setYValueAtIndex(i, newY); data2 = new Interpolator1DCubicSplineDataBundle(new ArrayInterpolator1DDataBundle(x, yData)); assertArrayEquals(data1.getKeys(), data2.getKeys(), 0); assertArrayEquals(data1.getValues(), data2.getValues(), 0); y21 = data1.getSecondDerivatives(); y22 = data2.getSecondDerivatives(); dy21 = data1.getSecondDerivativesSensitivities(); dy22 = data2.getSecondDerivativesSensitivities(); assertArrayEquals(y21, y22, 0); for (int j = 0; j < n; j++) { for (int k = 0; k < dy21.length; k++) { assertArrayEquals(dy21[k], dy22[k], 0); } } assertEquals(data1, data2); yData[i] = y[i]; data1 = new Interpolator1DCubicSplineDataBundle(new ArrayInterpolator1DDataBundle(x, y)); } } }