/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.math.interpolation; import static org.testng.AssertJUnit.assertEquals; import org.testng.annotations.Test; import cern.jet.random.engine.MersenneTwister; import cern.jet.random.engine.MersenneTwister64; import cern.jet.random.engine.RandomEngine; import com.opengamma.analytics.math.differentiation.ScalarFirstOrderDifferentiator; import com.opengamma.analytics.math.function.Function1D; import com.opengamma.analytics.math.interpolation.data.ArrayInterpolator1DDataBundle; import com.opengamma.analytics.math.interpolation.data.Interpolator1DCubicSplineDataBundle; import com.opengamma.analytics.math.interpolation.data.Interpolator1DDataBundle; import com.opengamma.util.test.TestGroup; /** * Test. */ @Test(groups = TestGroup.UNIT) public class Extrapolator1DNodeSensitivityCalculatorTest { private static final RandomEngine RANDOM = new MersenneTwister64(MersenneTwister.DEFAULT_SEED); private static final FlatExtrapolator1D FLAT_INTERPOLATOR = new FlatExtrapolator1D(); private static final LinearExtrapolator1D LINEAR_INTERPOLATOR = new LinearExtrapolator1D(new LinearInterpolator1D(), 1e-6); private static final LinearExtrapolator1D CUBIC_INTERPOLATOR = new LinearExtrapolator1D(new NaturalCubicSplineInterpolator1D(), 1e-6); private static final Interpolator1DCubicSplineDataBundle DATA; private static final double EPS = 1e-4; private static final Function1D<Double, Double> FUNCTION = new Function1D<Double, Double>() { private static final double A = -0.045; private static final double B = 0.03; private static final double C = 0.3; private static final double D = 0.05; @Override public Double evaluate(final Double x) { return (A + B * x) * Math.exp(-C * x) + D; } }; static { final double[] t = new double[] {0.0, 0.5, 1.0, 2.0, 3.0, 5.0, 7.0, 10.0, 15.0, 17.5, 20.0, 25.0, 30.0 }; final int n = t.length; final double[] r = new double[n]; for (int i = 0; i < n; i++) { r[i] = FUNCTION.evaluate(t[i]); } DATA = new Interpolator1DCubicSplineDataBundle(new ArrayInterpolator1DDataBundle(t, r)); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullCalculator() { new LinearExtrapolator1D(null); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullData1() { LINEAR_INTERPOLATOR.getNodeSensitivitiesForValue(null, 102.); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullData2() { FLAT_INTERPOLATOR.getNodeSensitivitiesForValue(null, 105.); } @Test(expectedExceptions = IllegalArgumentException.class) public void testWithinRange1() { LINEAR_INTERPOLATOR.getNodeSensitivitiesForValue(DATA, 20.); } @Test(expectedExceptions = IllegalArgumentException.class) public void testWithinRange2() { FLAT_INTERPOLATOR.getNodeSensitivitiesForValue(DATA, 20.); } @Test public void testSensitivities() { double[] sensitivityFD, sensitivity; double tUp, tDown; for (int i = 0; i < 100; i++) { tUp = RANDOM.nextDouble() * 10 + 30; tDown = -RANDOM.nextDouble() * 10; sensitivityFD = LINEAR_INTERPOLATOR.getNodeSensitivitiesForValue(DATA, tUp, true); sensitivity = LINEAR_INTERPOLATOR.getNodeSensitivitiesForValue(DATA, tUp); for (int j = 0; j < sensitivity.length; j++) { assertEquals(sensitivityFD[j], sensitivity[j], EPS); } sensitivityFD = LINEAR_INTERPOLATOR.getNodeSensitivitiesForValue(DATA, tDown, true); sensitivity = LINEAR_INTERPOLATOR.getNodeSensitivitiesForValue(DATA, tDown); for (int j = 0; j < sensitivity.length; j++) { assertEquals(sensitivityFD[j], sensitivity[j], EPS); } } for (int i = 0; i < 100; i++) { tUp = RANDOM.nextDouble() * 10 + 30; tDown = -RANDOM.nextDouble() * 10; sensitivityFD = CUBIC_INTERPOLATOR.getNodeSensitivitiesForValue(DATA, tUp, true); sensitivity = CUBIC_INTERPOLATOR.getNodeSensitivitiesForValue(DATA, tUp); for (int j = 0; j < sensitivity.length; j++) { assertEquals(sensitivityFD[j], sensitivity[j], EPS); } sensitivityFD = CUBIC_INTERPOLATOR.getNodeSensitivitiesForValue(DATA, tDown, true); sensitivity = CUBIC_INTERPOLATOR.getNodeSensitivitiesForValue(DATA, tDown); for (int j = 0; j < sensitivity.length; j++) { assertEquals(sensitivityFD[j], sensitivity[j], EPS); } } } @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); } }