com.opengamma.analytics.math.interpolation.ExponentialExtrapolator1D.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.math.interpolation.ExponentialExtrapolator1D.java

Source

/**
 * Copyright (C) 2012 - 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.interpolation.data.Interpolator1DDataBundle;

/**
 * Extrapolator based on a exponential function. Outside the data range the function is an exponential exp(m*x) where m is such that 
 *  - on the left: exp(m * data.firstKey()) = data.firstValue()
 *  - on the right: exp(m * data.lastKey()) = data.lastValue()
 */
public class ExponentialExtrapolator1D extends Interpolator1D {

    private static final long serialVersionUID = 1L;

    @Override
    public Interpolator1DDataBundle getDataBundle(final double[] x, final double[] y) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Interpolator1DDataBundle getDataBundleFromSortedArrays(final double[] x, final double[] y) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Double interpolate(final Interpolator1DDataBundle data, final Double value) {
        Validate.notNull(data, "data");
        Validate.notNull(value, "value");
        if (value < data.firstKey()) {
            return leftExtrapolate(data, value);
        } else if (value > data.lastKey()) {
            return rightExtrapolate(data, value);
        }
        throw new IllegalArgumentException("Value " + value + " was within data range");
    }

    @Override
    public double firstDerivative(final Interpolator1DDataBundle data, final Double value) {
        Validate.notNull(data, "data");
        Validate.notNull(value, "value");
        if (value < data.firstKey()) {
            return leftExtrapolateDerivative(data, value);
        } else if (value > data.lastKey()) {
            return rightExtrapolateDerivative(data, value);
        }
        throw new IllegalArgumentException("Value " + value + " was within data range");
    }

    @Override
    public double[] getNodeSensitivitiesForValue(final Interpolator1DDataBundle data, final Double value) {
        Validate.notNull(data, "data");
        if (value < data.firstKey()) {
            return getLeftSensitivities(data, value);
        } else if (value > data.lastKey()) {
            return getRightSensitivities(data, value);
        }
        throw new IllegalArgumentException("Value " + value + " was within data range");
    }

    private Double leftExtrapolate(final Interpolator1DDataBundle data, final Double value) {
        Validate.notNull(data, "data");
        Validate.notNull(value, "value");
        final double x = data.firstKey();
        final double y = data.firstValue();
        final double m = Math.log(y) / x;
        return Math.exp(m * value);
    }

    private Double rightExtrapolate(final Interpolator1DDataBundle data, final Double value) {
        Validate.notNull(data, "data");
        Validate.notNull(value, "value");
        final double x = data.lastKey();
        final double y = data.lastValue();
        final double m = Math.log(y) / x;
        return Math.exp(m * value);
    }

    private Double leftExtrapolateDerivative(final Interpolator1DDataBundle data, final Double value) {
        Validate.notNull(data, "data");
        Validate.notNull(value, "value");
        final double x = data.firstKey();
        final double y = data.firstValue();
        final double m = Math.log(y) / x;
        return m * Math.exp(m * value);
    }

    private Double rightExtrapolateDerivative(final Interpolator1DDataBundle data, final Double value) {
        Validate.notNull(data, "data");
        Validate.notNull(value, "value");
        final double x = data.lastKey();
        final double y = data.lastValue();
        final double m = Math.log(y) / x;
        return m * Math.exp(m * value);
    }

    private double[] getLeftSensitivities(final Interpolator1DDataBundle data, final double value) {
        Validate.notNull(data, "data");
        Validate.notNull(value, "value");
        final double x = data.firstKey();
        final double y = data.firstValue();
        final double m = Math.log(y) / x;
        final double ex = Math.exp(m * value);
        final double[] result = new double[data.size()];
        result[0] = ex * value / (x * y);
        return result;
    }

    private double[] getRightSensitivities(final Interpolator1DDataBundle data, final Double value) {
        Validate.notNull(data, "data");
        Validate.notNull(value, "value");
        final double x = data.lastKey();
        final double y = data.lastValue();
        final double m = Math.log(y) / x;
        final double ex = Math.exp(m * value);
        final double[] result = new double[data.size()];
        result[data.size() - 1] = ex * value / (x * y);
        return result;
    }

}