/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.math.interpolation; import org.apache.commons.lang.Validate; import com.opengamma.analytics.math.function.PiecewisePolynomialFunction1D; import com.opengamma.analytics.math.interpolation.data.Interpolator1DDataBundle; import com.opengamma.analytics.math.interpolation.data.Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle; import com.opengamma.util.ArgumentChecker; /** * Given a data set {xValues[i], yValues[i]}, extrapolate {x[i], x[i] * y[i]} by a polynomial function defined by ProductPiecewisePolynomialInterpolator1D, * that is, use polynomial coefficients for the leftmost (rightmost) interval obtained in ProductPiecewisePolynomialInterpolator1D. */ public class ProductPolynomialExtrapolator1D extends Interpolator1D { private static final long serialVersionUID = 1L; private final ProductPiecewisePolynomialInterpolator1D _interpolator; private final PiecewisePolynomialFunction1D _func; private static final double SMALL = 1e-14; /** * The extrapolator using PiecewisePolynomialWithSensitivityFunction1D * @param interpolator The interpolator */ public ProductPolynomialExtrapolator1D(Interpolator1D interpolator) { this(interpolator, new PiecewisePolynomialFunction1D()); } /** * The extrapolator using a specific polynomial function * @param interpolator The interpolator * @param func The polynomial function */ public ProductPolynomialExtrapolator1D(Interpolator1D interpolator, PiecewisePolynomialFunction1D func) { ArgumentChecker.notNull(interpolator, "interpolator"); ArgumentChecker.notNull(func, "func"); ArgumentChecker.isTrue(interpolator instanceof ProductPiecewisePolynomialInterpolator1D, "This interpolator should be used with ProductPiecewisePolynomialInterpolator1D"); _interpolator = (ProductPiecewisePolynomialInterpolator1D) interpolator; _func = func; } @Override public Interpolator1DDataBundle getDataBundle(final double[] x, final double[] y) { return _interpolator.getDataBundle(x, y); } @Override public Interpolator1DDataBundle getDataBundleFromSortedArrays(final double[] x, final double[] y) { return _interpolator.getDataBundleFromSortedArrays(x, y); } /** * {@inheritDoc} * For small Math.abs(value), this method returns the exact value if clamped at (0,0), * otherwise this returns a reference value */ @Override public Double interpolate(final Interpolator1DDataBundle data, final Double value) { Validate.notNull(data, "data"); Validate.notNull(value, "value"); ArgumentChecker.isTrue(value < data.firstKey() || value > data.lastKey(), "value was within data range"); Validate.isTrue(data instanceof Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle); Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle polyData = (Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle) data; return _interpolator.interpolate(polyData, value, _func, SMALL); } /** * {@inheritDoc} * For small Math.abs(value), this method returns the exact value if clamped at (0,0), * otherwise this returns a reference value */ @Override public double firstDerivative(final Interpolator1DDataBundle data, final Double value) { Validate.notNull(data, "data"); Validate.notNull(value, "value"); ArgumentChecker.isTrue(value < data.firstKey() || value > data.lastKey(), "value was within data range"); Validate.isTrue(data instanceof Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle); Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle polyData = (Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle) data; return _interpolator.firstDerivative(polyData, value, _func, SMALL); } /** * {@inheritDoc} * For small Math.abs(value), this method returns the exact value if clamped at (0,0), * otherwise this returns a reference value */ @Override public double[] getNodeSensitivitiesForValue(final Interpolator1DDataBundle data, final Double value) { Validate.notNull(data, "data"); Validate.notNull(value, "value"); ArgumentChecker.isTrue(value < data.firstKey() || value > data.lastKey(), "value was within data range"); Validate.isTrue(data instanceof Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle); Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle polyData = (Interpolator1DPiecewisePoynomialWithExtraKnotsDataBundle) data; return _interpolator.getNodeSensitivitiesForValue(polyData, value, _func, SMALL); } @Override protected double[] getFiniteDifferenceSensitivities(final Interpolator1DDataBundle data, final Double value) { throw new IllegalArgumentException("Use the method, getNodeSensitivitiesForValue"); } }