/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.math.interpolation.data; import java.io.Serializable; import java.util.Arrays; import com.opengamma.util.ArgumentChecker; /** * */ public class Interpolator1DQuadraticSplineDataBundle implements Interpolator1DDataBundle, Serializable { private final Interpolator1DDataBundle _underlyingData; private final double[] _a; private final double[] _b; public Interpolator1DQuadraticSplineDataBundle(final Interpolator1DDataBundle underlyingData) { ArgumentChecker.notNull(underlyingData, "underlying data"); _underlyingData = underlyingData; final double[] x = _underlyingData.getKeys(); final double[] h = _underlyingData.getValues(); final int n = _underlyingData.size(); final double[] dx = new double[n]; dx[0] = x[0]; for (int i = 1; i < n; i++) { dx[i] = x[i] - x[i - 1]; } _a = new double[n + 1]; _b = new double[n + 1]; _a[0] = Math.sqrt(_underlyingData.firstValue() / _underlyingData.firstKey()); for (int i = 1; i < n; i++) { _a[i] = _a[i - 1] + _b[i - 1] * dx[i - 1]; final double a = Math.pow(dx[i], 3) / 3; final double b = _a[i] * dx[i] * dx[i]; final double c = _a[i] * _a[i] * dx[i] + h[i - 1] - h[i]; double root = b * b - 4 * a * c; ArgumentChecker.isTrue(root >= 0, "root of neg"); root = Math.sqrt(root); final double temp1 = (-b + root) / 2 / a; _b[i] = temp1; // _b[i] = 2 * (h[i] - h[i - 1] - _a[i] * dx[i]) / dx[i] / dx[i]; } _a[n] = _a[n - 1]; } @Override public boolean containsKey(final Double key) { return _underlyingData.containsKey(key); } @Override public Double firstKey() { return _underlyingData.firstKey(); } @Override public Double firstValue() { return _underlyingData.firstValue(); } @Override public Double get(final Double key) { return _underlyingData.get(key); } @Override public InterpolationBoundedValues getBoundedValues(final Double key) { return _underlyingData.getBoundedValues(key); } @Override public double[] getKeys() { return _underlyingData.getKeys(); } @Override public int getLowerBoundIndex(final Double value) { final double[] keys = _underlyingData.getKeys(); final int n = _underlyingData.size(); if (value < keys[0]) { return 0; } if (value > keys[n - 1]) { return n; } int index = Arrays.binarySearch(keys, value); if (index >= 0) { // Fast break out if it's an exact match. return index; } if (index < 0) { index = -(index + 1); index--; } return index; } @Override public Double getLowerBoundKey(final Double value) { return _underlyingData.getLowerBoundKey(value); } @Override public double[] getValues() { return _underlyingData.getValues(); } @Override public Double higherKey(final Double key) { return _underlyingData.higherKey(key); } @Override public Double higherValue(final Double key) { return _underlyingData.higherValue(key); } @Override public Double lastKey() { return _underlyingData.lastKey(); } @Override public Double lastValue() { return _underlyingData.lastValue(); } @Override public int size() { return _underlyingData.size(); } @Override public void setYValueAtIndex(final int index, final double y) { } public double getA(final int index) { return _a[index]; } public double getB(final int index) { return _b[index]; } }