com.opengamma.strata.math.impl.interpolation.PiecewisePolynomialInterpolator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of strata-math Show documentation
Show all versions of strata-math Show documentation
Mathematic support for Strata
/*
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.math.impl.interpolation;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.collect.array.DoubleMatrix;
/**
* Abstract class for interpolations based on piecewise polynomial functions .
*/
public abstract class PiecewisePolynomialInterpolator {
/**
* Interpolate.
*
* @param xValues X values of data
* @param yValues Y values of data
* @return {@link PiecewisePolynomialResult} containing knots, coefficients of piecewise polynomials,
* number of intervals, degree of polynomials, dimension of spline
*/
public abstract PiecewisePolynomialResult interpolate(final double[] xValues, final double[] yValues);
/**
* Interpolate.
*
* @param xValues X values of data
* @param yValuesMatrix Y values of data
* @return Coefficient matrix whose i-th row vector is {a_n, a_{n-1}, ... }
* of f(x) = a_n * (x-x_i)^n + a_{n-1} * (x-x_i)^{n-1} +... for the i-th interval
*/
public abstract PiecewisePolynomialResult interpolate(final double[] xValues, final double[][] yValuesMatrix);
/**
* Interpolate.
*
* @param xValues X values of data
* @param yValues Y values of data
* @param xKey the key
* @return value of the underlying cubic spline function at the value of x
*/
public double interpolate(final double[] xValues, final double[] yValues, final double xKey) {
ArgChecker.isFalse(Double.isNaN(xKey), "xKey containing NaN");
ArgChecker.isFalse(Double.isInfinite(xKey), "xKey containing Infinity");
final PiecewisePolynomialResult result = this.interpolate(xValues, yValues);
final DoubleArray knots = result.getKnots();
final int nKnots = knots.size();
final DoubleMatrix coefMatrix = result.getCoefMatrix();
double res = 0.;
int indicator = 0;
if (xKey < knots.get(1)) {
indicator = 0;
} else {
for (int i = 1; i < nKnots - 1; ++i) {
if (knots.get(i) <= xKey) {
indicator = i;
}
}
}
final DoubleArray coefs = coefMatrix.row(indicator);
res = getValue(coefs, xKey, knots.get(indicator));
ArgChecker.isFalse(Double.isInfinite(res), "Too large input");
ArgChecker.isFalse(Double.isNaN(res), "Too large input");
return res;
}
/**
* Interpolate.
*
* @param xValues X values of data
* @param yValues Y values of data
* @param xKeys the keys
* @return Values of the underlying cubic spline function at the values of x
*/
public DoubleArray interpolate(final double[] xValues, final double[] yValues, final double[] xKeys) {
ArgChecker.notNull(xKeys, "xKeys");
final int keyLength = xKeys.length;
for (int i = 0; i < keyLength; ++i) {
ArgChecker.isFalse(Double.isNaN(xKeys[i]), "xKeys containing NaN");
ArgChecker.isFalse(Double.isInfinite(xKeys[i]), "xKeys containing Infinity");
}
final PiecewisePolynomialResult result = this.interpolate(xValues, yValues);
final DoubleArray knots = result.getKnots();
final int nKnots = knots.size();
final DoubleMatrix coefMatrix = result.getCoefMatrix();
double[] res = new double[keyLength];
for (int j = 0; j < keyLength; ++j) {
int indicator = 0;
if (xKeys[j] < knots.get(1)) {
indicator = 0;
} else {
for (int i = 1; i < nKnots - 1; ++i) {
if (knots.get(i) <= xKeys[j]) {
indicator = i;
}
}
}
final DoubleArray coefs = coefMatrix.row(indicator);
res[j] = getValue(coefs, xKeys[j], knots.get(indicator));
ArgChecker.isFalse(Double.isInfinite(res[j]), "Too large input");
ArgChecker.isFalse(Double.isNaN(res[j]), "Too large input");
}
return DoubleArray.copyOf(res);
}
/**
* Interpolate.
*
* @param xValues the values
* @param yValues the values
* @param xMatrix the matrix
* @return Values of the underlying cubic spline function at the values of x
*/
public DoubleMatrix interpolate(final double[] xValues, final double[] yValues, final double[][] xMatrix) {
ArgChecker.notNull(xMatrix, "xMatrix");
DoubleMatrix matrix = DoubleMatrix.copyOf(xMatrix);
return DoubleMatrix.ofArrayObjects(
xMatrix.length,
xMatrix[0].length,
i -> interpolate(xValues, yValues, matrix.rowArray(i)));
}
/**
* Interpolate.
*
* @param xValues the values
* @param yValuesMatrix the matrix
* @param x the x
* @return Values of the underlying cubic spline functions interpolating {yValuesMatrix.RowVectors} at the value of x
*/
public DoubleArray interpolate(final double[] xValues, final double[][] yValuesMatrix, final double x) {
DoubleMatrix matrix = DoubleMatrix.copyOf(yValuesMatrix);
return DoubleArray.of(matrix.rowCount(), i -> interpolate(xValues, matrix.rowArray(i), x));
}
/**
* Interpolate.
*
* @param xValues the values
* @param yValuesMatrix the matrix
* @param x the s
* @return Values of the underlying cubic spline functions interpolating {yValuesMatrix.RowVectors} at the values of x
*/
public DoubleMatrix interpolate(final double[] xValues, final double[][] yValuesMatrix, final double[] x) {
ArgChecker.notNull(x, "x");
final DoubleMatrix matrix = DoubleMatrix.copyOf(yValuesMatrix);
return DoubleMatrix.ofArrayObjects(
yValuesMatrix.length,
x.length,
i -> interpolate(xValues, matrix.rowArray(i), x));
}
/**
* Interpolate.
*
* @param xValues the values
* @param yValuesMatrix the matrix
* @param xMatrix the matrix
* @return Values of the underlying cubic spline functions interpolating {yValuesMatrix.RowVectors} at the values of xMatrix
*/
public DoubleMatrix[] interpolate(final double[] xValues, final double[][] yValuesMatrix, final double[][] xMatrix) {
ArgChecker.notNull(xMatrix, "xMatrix");
final int keyColumn = xMatrix[0].length;
final DoubleMatrix matrix = DoubleMatrix.copyOf(xMatrix);
DoubleMatrix[] resMatrix2D = new DoubleMatrix[keyColumn];
for (int i = 0; i < keyColumn; ++i) {
resMatrix2D[i] = interpolate(xValues, yValuesMatrix, matrix.columnArray(i));
}
return resMatrix2D;
}
/**
* Derive interpolant on {xValues_i, yValues_i} and (yValues) node sensitivity.
* @param xValues X values of data
* @param yValues Y values of data
* @return {@link PiecewisePolynomialResultsWithSensitivity}
*/
public abstract PiecewisePolynomialResultsWithSensitivity interpolateWithSensitivity(final double[] xValues, final double[] yValues);
/**
* Hyman filter modifies derivative values at knot points which are initially computed by a "primary" interpolator.
* @return The primary interpolator for Hyman filter, interpolation method itself for other interpolators
*/
public PiecewisePolynomialInterpolator getPrimaryMethod() {
return this;
}
//-------------------------------------------------------------------------
/**
* @param coefs {a_n,a_{n-1},...} of f(x) = a_n x^{n} + a_{n-1} x^{n-1} + ....
* @param x the x
* @param leftknot the knot specifying underlying interpolation function
* @return the value of the underlying interpolation function at the value of x
*/
protected double getValue(DoubleArray coefs, double x, double leftknot) {
// needs to delegate as method is protected
return getValue(coefs.toArrayUnsafe(), x, leftknot);
}
/**
* @param coefs {a_n,a_{n-1},...} of f(x) = a_n x^{n} + a_{n-1} x^{n-1} + ....
* @param x the x
* @param leftknot the knot specifying underlying interpolation function
* @return the value of the underlying interpolation function at the value of x
*/
protected double getValue(double[] coefs, double x, double leftknot) {
int nCoefs = coefs.length;
double s = x - leftknot;
double res = coefs[0];
for (int i = 1; i < nCoefs; i++) {
res *= s;
res += coefs[i];
}
return res;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy