/**
* 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 org.apache.commons.lang.Validate;
import com.opengamma.analytics.math.interpolation.data.ArrayInterpolator1DDataBundle;
import com.opengamma.analytics.math.interpolation.data.InterpolationBoundedValues;
import com.opengamma.analytics.math.interpolation.data.Interpolator1DDataBundle;
/**
* A one-dimensional interpolator. The interpolated value of the function
* <i>y</i> at <i>x</i> between two data points <i>(x<sub>1</sub>,
* y<sub>1</sub>)</i> and <i>(x<sub>2</sub>, y<sub>2</sub>)</i> is given by:<br>
* <i>y = y<sub>1</sub> (y<sub>2</sub> / y<sub>1</sub>) ^ ((x - x<sub>1</sub>) /
* (x<sub>2</sub> - x<sub>1</sub>))</i><br>
* It is the equivalent of performing a linear interpolation on a data set after
* taking the logarithm of the y-values.
*
*/
public class LogLinearInterpolator1D extends Interpolator1D {
private static final long serialVersionUID = 1L;
@Override
public Double interpolate(final Interpolator1DDataBundle model, final Double value) {
Validate.notNull(value, "value");
Validate.notNull(model, "data bundle");
final InterpolationBoundedValues boundedValues = model.getBoundedValues(value);
final Double x1 = boundedValues.getLowerBoundKey();
final Double y1 = boundedValues.getLowerBoundValue();
if (model.getLowerBoundIndex(value) == model.size() - 1) {
return y1;
}
final Double x2 = boundedValues.getHigherBoundKey();
final Double y2 = boundedValues.getHigherBoundValue();
return Math.pow(y2 / y1, (value - x1) / (x2 - x1)) * y1;
}
@Override
public double firstDerivative(final Interpolator1DDataBundle model, final Double value) {
Validate.notNull(value, "value");
Validate.notNull(model, "data bundle");
final InterpolationBoundedValues boundedValues = model.getBoundedValues(value);
final Double x1 = boundedValues.getLowerBoundKey();
final Double y1 = boundedValues.getLowerBoundValue();
if (model.getLowerBoundIndex(value) == model.size() - 1) {
return 0.;
}
final Double x2 = boundedValues.getHigherBoundKey();
final Double y2 = boundedValues.getHigherBoundValue();
return Math.pow(y2 / y1, (value - x1) / (x2 - x1)) * y1 * Math.log(y2 / y1) / (x2 - x1);
}
@Override
public Interpolator1DDataBundle getDataBundle(final double[] x, final double[] y) {
return new ArrayInterpolator1DDataBundle(x, y);
}
@Override
public Interpolator1DDataBundle getDataBundleFromSortedArrays(final double[] x, final double[] y) {
return new ArrayInterpolator1DDataBundle(x, y, true);
}
@Override
public double[] getNodeSensitivitiesForValue(Interpolator1DDataBundle data, Double value) {
return getFiniteDifferenceSensitivities(data, value);
}
}