Package com.opengamma.analytics.math.function

Source Code of com.opengamma.analytics.math.function.PiecewisePolynomialWithSensitivityFunction1DTest

/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.function;

import static org.testng.Assert.assertEquals;

import java.util.Arrays;

import org.testng.annotations.Test;

import com.opengamma.analytics.math.interpolation.ConstrainedCubicSplineInterpolator;
import com.opengamma.analytics.math.interpolation.CubicSplineInterpolator;
import com.opengamma.analytics.math.interpolation.NaturalSplineInterpolator;
import com.opengamma.analytics.math.interpolation.PiecewiseCubicHermiteSplineInterpolator;
import com.opengamma.analytics.math.interpolation.PiecewisePolynomialInterpolator;
import com.opengamma.analytics.math.interpolation.PiecewisePolynomialResultsWithSensitivity;
import com.opengamma.analytics.math.interpolation.SemiLocalCubicSplineInterpolator;

/**
*
*/
public class PiecewisePolynomialWithSensitivityFunction1DTest {
  private static final double EPS = 1.e-7;
  private static final PiecewisePolynomialWithSensitivityFunction1D FUNCTION = new PiecewisePolynomialWithSensitivityFunction1D();

  /**
   *
   */
  @Test
  public void firstDerivativeFiniteDifferenceTest() {
    final PiecewisePolynomialInterpolator[] interps = new PiecewisePolynomialInterpolator[] {new NaturalSplineInterpolator(), new CubicSplineInterpolator(),
        new PiecewiseCubicHermiteSplineInterpolator(), new ConstrainedCubicSplineInterpolator(), new SemiLocalCubicSplineInterpolator() };
    final int nInterps = interps.length;
    for (int k = 0; k < nInterps; ++k) {
      final double[] xValues = new double[] {1., 2.8, 3.1, 5.9, 10., 16. };
      final double[] yValues = new double[] {1., 2., 3., -2., 5., -5. };
      final int nData = xValues.length;
      double[] yValuesUp = Arrays.copyOf(yValues, nData);
      double[] yValuesDw = Arrays.copyOf(yValues, nData);
      final double[] xKeys = new double[10 * nData];
      final double xMin = xValues[0];
      final double xMax = xValues[nData - 1];
      for (int i = 0; i < 10 * nData; ++i) {
        xKeys[i] = xMin + (xMax - xMin) / (10 * nData - 1) * i;
      }

      PiecewisePolynomialResultsWithSensitivity result = interps[k].interpolateWithSensitivity(xValues, yValues);
      for (int j = 0; j < nData; ++j) {
        yValuesUp[j] = yValues[j] * (1. + EPS);
        yValuesDw[j] = yValues[j] * (1. - EPS);
        final PiecewisePolynomialResultsWithSensitivity resultUp = interps[k].interpolateWithSensitivity(xValues, yValuesUp);
        final PiecewisePolynomialResultsWithSensitivity resultDw = interps[k].interpolateWithSensitivity(xValues, yValuesDw);

        final double[] valuesUp = FUNCTION.evaluate(resultUp, xKeys).getData()[0];
        final double[] valuesDw = FUNCTION.evaluate(resultDw, xKeys).getData()[0];
        final double[] diffUp = FUNCTION.differentiate(resultUp, xKeys).getData()[0];
        final double[] diffDw = FUNCTION.differentiate(resultDw, xKeys).getData()[0];
        for (int i = 0; i < 10 * nData; ++i) {
          final double xKeyUp = xKeys[i] * (1. + EPS);
          final double xKeyDw = xKeys[i] * (1. - EPS);
          double valueFinite = 0.5 * (valuesUp[i] - valuesDw[i]) / EPS / yValues[j];
          double senseFinite = 0.5 * (diffUp[i] - diffDw[i]) / EPS / yValues[j];
          final double resNodeSensitivity = FUNCTION.nodeSensitivity(result, xKeys[i]).getEntry(j);
          final double resNodeSensitivityXkeyUp = FUNCTION.nodeSensitivity(result, xKeyUp).getEntry(j);
          final double resNodeSensitivityXkeyDw = FUNCTION.nodeSensitivity(result, xKeyDw).getEntry(j);
          final double senseFiniteXkey = 0.5 * (resNodeSensitivityXkeyUp - resNodeSensitivityXkeyDw) / EPS / xKeys[i];
          final double resDiffNodeSensitivity = FUNCTION.differentiateNodeSensitivity(result, xKeys[i]).getEntry(j);
          assertEquals(valueFinite, resNodeSensitivity, Math.max(Math.abs(yValues[j]) * EPS, EPS));
          assertEquals(senseFinite, resDiffNodeSensitivity, Math.max(Math.abs(yValues[j]) * EPS, EPS));
          assertEquals(senseFiniteXkey, resDiffNodeSensitivity, Math.max(Math.abs(xKeys[i]) * EPS, EPS));
        }
        yValuesUp[j] = yValues[j];
        yValuesDw[j] = yValues[j];
      }
    }
  }

  /**
   *
   */
  @Test
  public void secondDerivativeFiniteDifferenceTest() {
    final PiecewisePolynomialInterpolator[] interps = new PiecewisePolynomialInterpolator[] {new NaturalSplineInterpolator(), new CubicSplineInterpolator(),
        new PiecewiseCubicHermiteSplineInterpolator(), new ConstrainedCubicSplineInterpolator(), new SemiLocalCubicSplineInterpolator() };
    final int nInterps = interps.length;
    for (int k = 0; k < nInterps; ++k) {
      final double[] xValues = new double[] {1., 2.8, 3.1, 5.9, 10., 16. };
      final double[] yValues = new double[] {1., 2., 3., -2., 5., -5. };
      final int nData = xValues.length;
      double[] yValuesUp = Arrays.copyOf(yValues, nData);
      double[] yValuesDw = Arrays.copyOf(yValues, nData);
      final double[] xKeys = new double[10 * nData];
      final double xMin = xValues[0];
      final double xMax = xValues[nData - 1];
      for (int i = 0; i < 10 * nData; ++i) {
        xKeys[i] = xMin + (xMax - xMin) / (10 * nData - 1) * i;
      }

      PiecewisePolynomialResultsWithSensitivity result = interps[k].interpolateWithSensitivity(xValues, yValues);
      for (int j = 0; j < nData; ++j) {
        yValuesUp[j] = yValues[j] * (1. + EPS);
        yValuesDw[j] = yValues[j] * (1. - EPS);
        final PiecewisePolynomialResultsWithSensitivity resultUp = interps[k].interpolateWithSensitivity(xValues, yValuesUp);
        final PiecewisePolynomialResultsWithSensitivity resultDw = interps[k].interpolateWithSensitivity(xValues, yValuesDw);

        final double[] diffUp = FUNCTION.differentiateTwice(resultUp, xKeys).getData()[0];
        final double[] diffDw = FUNCTION.differentiateTwice(resultDw, xKeys).getData()[0];
        for (int i = 0; i < 10 * nData; ++i) {
          final double xKeyUp = xKeys[i] * (1. + EPS);
          final double xKeyDw = xKeys[i] * (1. - EPS);

          double senseFinite = 0.5 * (diffUp[i] - diffDw[i]) / EPS / yValues[j];
          final double resdiffNodeSensitivityXkeyUp = FUNCTION.differentiateNodeSensitivity(result, xKeyUp).getEntry(j);
          final double resdiffNodeSensitivityXkeyDw = FUNCTION.differentiateNodeSensitivity(result, xKeyDw).getEntry(j);
          final double senseFiniteXkey = 0.5 * (resdiffNodeSensitivityXkeyUp - resdiffNodeSensitivityXkeyDw) / EPS / xKeys[i];
          final double resDiffTwiceNodeSensitivity = FUNCTION.differentiateTwiceNodeSensitivity(result, xKeys[i]).getEntry(j);

          assertEquals(senseFinite, resDiffTwiceNodeSensitivity, Math.max(Math.abs(yValues[j]) * EPS, EPS));
          assertEquals(senseFiniteXkey, resDiffTwiceNodeSensitivity, Math.max(Math.abs(xKeys[i]) * EPS, EPS));
        }
        yValuesUp[j] = yValues[j];
        yValuesDw[j] = yValues[j];
      }
    }
  }

  /**
   * Interpolations with longer yValues
   */
  @Test
  public void clampedFiniteDifferenceTest() {
    final PiecewisePolynomialInterpolator[] interps = new PiecewisePolynomialInterpolator[] {new CubicSplineInterpolator() };
    final int nInterps = interps.length;
    for (int k = 0; k < nInterps; ++k) {
      final double[] xValues = new double[] {1., 2.8, 3.1, 5.9, 10., 16. };
      final double[] bcs = new double[] {-2., -1.5, 0., 1. / 3., 3.2 };
      final int nBcs = bcs.length;
      for (int l = 0; l < nBcs; ++l) {
        for (int m = 0; m < nBcs; ++m) {
          final double[] yValues = new double[] {bcs[l], 1., 2., 3., -2., 5., -5., bcs[m] };
          final int nData = xValues.length;
          double[] yValuesUp = Arrays.copyOf(yValues, nData + 2);
          double[] yValuesDw = Arrays.copyOf(yValues, nData + 2);
          final double[] xKeys = new double[10 * nData];
          final double xMin = xValues[0];
          final double xMax = xValues[nData - 1];
          for (int i = 0; i < 10 * nData; ++i) {
            xKeys[i] = xMin + (xMax - xMin) / (10 * nData - 1) * i;
          }

          PiecewisePolynomialResultsWithSensitivity result = interps[k].interpolateWithSensitivity(xValues, yValues);
          for (int j = 0; j < nData; ++j) {
            yValuesUp[j + 1] = yValues[j + 1] * (1. + EPS);
            yValuesDw[j + 1] = yValues[j + 1] * (1. - EPS);
            final PiecewisePolynomialResultsWithSensitivity resultUp = interps[k].interpolateWithSensitivity(xValues, yValuesUp);
            final PiecewisePolynomialResultsWithSensitivity resultDw = interps[k].interpolateWithSensitivity(xValues, yValuesDw);

            final double[] valuesUp = FUNCTION.evaluate(resultUp, xKeys).getData()[0];
            final double[] valuesDw = FUNCTION.evaluate(resultDw, xKeys).getData()[0];
            final double[] diffUp = FUNCTION.differentiate(resultUp, xKeys).getData()[0];
            final double[] diffDw = FUNCTION.differentiate(resultDw, xKeys).getData()[0];
            for (int i = 0; i < 10 * nData; ++i) {
              final double xKeyUp = xKeys[i] * (1. + EPS);
              final double xKeyDw = xKeys[i] * (1. - EPS);
              double valueFinite = 0.5 * (valuesUp[i] - valuesDw[i]) / EPS / yValues[j + 1];
              double senseFinite = 0.5 * (diffUp[i] - diffDw[i]) / EPS / yValues[j + 1];
              final double resNodeSensitivity = FUNCTION.nodeSensitivity(result, xKeys[i]).getEntry(j);
              final double resNodeSensitivityXkeyUp = FUNCTION.nodeSensitivity(result, xKeyUp).getEntry(j);
              final double resNodeSensitivityXkeyDw = FUNCTION.nodeSensitivity(result, xKeyDw).getEntry(j);
              final double senseFiniteXkey = 0.5 * (resNodeSensitivityXkeyUp - resNodeSensitivityXkeyDw) / EPS / xKeys[i];
              final double resDiffNodeSensitivity = FUNCTION.differentiateNodeSensitivity(result, xKeys[i]).getEntry(j);
              assertEquals(valueFinite, resNodeSensitivity, Math.max(Math.abs(yValues[j + 1]) * EPS, EPS));
              assertEquals(senseFinite, resDiffNodeSensitivity, Math.max(Math.abs(yValues[j + 1]) * EPS, EPS));
              assertEquals(senseFiniteXkey, resDiffNodeSensitivity, Math.max(Math.abs(xKeys[i]) * EPS, EPS));
            }
            yValuesUp[j + 1] = yValues[j + 1];
            yValuesDw[j + 1] = yValues[j + 1];
          }
        }
      }
    }
  }

  /**
   *
   */
  @Test
  public void clampedSecondDerivativeFiniteDifferenceTest() {
    final PiecewisePolynomialInterpolator[] interps = new PiecewisePolynomialInterpolator[] {new CubicSplineInterpolator() };
    final int nInterps = interps.length;
    for (int k = 0; k < nInterps; ++k) {
      final double[] xValues = new double[] {1., 2.8, 3.1, 5.9, 10., 16. };
      final double[] bcs = new double[] {-2., -1.5, 0., 1. / 3., 3.2 };
      final int nBcs = bcs.length;
      for (int l = 0; l < nBcs; ++l) {
        for (int m = 0; m < nBcs; ++m) {
          final double[] yValues = new double[] {bcs[l], 1., 2., 3., -2., 5., -5., bcs[m] };
          final int nData = xValues.length;
          double[] yValuesUp = Arrays.copyOf(yValues, nData + 2);
          double[] yValuesDw = Arrays.copyOf(yValues, nData + 2);
          final double[] xKeys = new double[10 * nData];
          final double xMin = xValues[0];
          final double xMax = xValues[nData - 1];
          for (int i = 0; i < 10 * nData; ++i) {
            xKeys[i] = xMin + (xMax - xMin) / (10 * nData - 1) * i;
          }

          PiecewisePolynomialResultsWithSensitivity result = interps[k].interpolateWithSensitivity(xValues, yValues);
          for (int j = 0; j < nData; ++j) {
            yValuesUp[j + 1] = yValues[j + 1] * (1. + EPS);
            yValuesDw[j + 1] = yValues[j + 1] * (1. - EPS);
            final PiecewisePolynomialResultsWithSensitivity resultUp = interps[k].interpolateWithSensitivity(xValues, yValuesUp);
            final PiecewisePolynomialResultsWithSensitivity resultDw = interps[k].interpolateWithSensitivity(xValues, yValuesDw);

            final double[] diffUp = FUNCTION.differentiateTwice(resultUp, xKeys).getData()[0];
            final double[] diffDw = FUNCTION.differentiateTwice(resultDw, xKeys).getData()[0];
            for (int i = 0; i < 10 * nData; ++i) {
              final double xKeyUp = xKeys[i] * (1. + EPS);
              final double xKeyDw = xKeys[i] * (1. - EPS);

              double senseFinite = 0.5 * (diffUp[i] - diffDw[i]) / EPS / yValues[j + 1];
              final double resdiffNodeSensitivityXkeyUp = FUNCTION.differentiateNodeSensitivity(result, xKeyUp).getEntry(j);
              final double resdiffNodeSensitivityXkeyDw = FUNCTION.differentiateNodeSensitivity(result, xKeyDw).getEntry(j);
              final double senseFiniteXkey = 0.5 * (resdiffNodeSensitivityXkeyUp - resdiffNodeSensitivityXkeyDw) / EPS / xKeys[i];
              final double resDiffTwiceNodeSensitivity = FUNCTION.differentiateTwiceNodeSensitivity(result, xKeys[i]).getEntry(j);

              assertEquals(senseFinite, resDiffTwiceNodeSensitivity, Math.max(Math.abs(yValues[j + 1]) * EPS, EPS));
              assertEquals(senseFiniteXkey, resDiffTwiceNodeSensitivity, Math.max(Math.abs(xKeys[i]) * EPS, EPS));
            }
            yValuesUp[j + 1] = yValues[j + 1];
            yValuesDw[j + 1] = yValues[j + 1];
          }
        }
      }
    }
  }
}
TOP

Related Classes of com.opengamma.analytics.math.function.PiecewisePolynomialWithSensitivityFunction1DTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.