Bound(DoubleArray xValues, DoubleArray yValues, BoundCurveInterpolator interpolator) { this.nodeCount = xValues.size(); this.firstXValue = xValues.get(0); this.firstYValue = yValues.get(0); this.firstYValueLog = Math.log(firstYValue); this.lastXValue = xValues.get(nodeCount - 1); this.lastYValue = yValues.get(nodeCount - 1); this.lastYValueLog = Math.log(lastYValue); this.eps = EPS * (lastXValue - firstXValue); // left this.leftGradient = interpolator.firstDerivative(firstXValue) / interpolator.interpolate(firstXValue); this.leftResValueInterpolator = interpolator.interpolate(firstXValue + eps); this.leftSens = interpolator.parameterSensitivity(firstXValue + eps); // right this.rightGradient = interpolator.firstDerivative(lastXValue) / interpolator.interpolate(lastXValue); this.rightResValueInterpolator = interpolator.interpolate(lastXValue - eps); this.rightSens = interpolator.parameterSensitivity(lastXValue - eps); }
@Override public DoubleArray parameterSensitivity(double x, double y) { int uniqueX = yInterpolators.length; final DoubleArray[] ySens = new DoubleArray[uniqueX]; // use each y-interpolator to find the z-value sensitivity for each unique x for (int i = 0; i < uniqueX; i++) { ySens[i] = yInterpolators[i].parameterSensitivity(y); } // use each y-interpolator to find the z-value for each unique x DoubleArray zValuesEffective = DoubleArray.of(uniqueX, i -> yInterpolators[i].interpolate(y)); // find the sensitivity of the unique x-values against derived z-values DoubleArray xSens = xInterpolator .bind(xValuesUnique, zValuesEffective, xExtrapolatorLeft, xExtrapolatorRight) .parameterSensitivity(x); return project(xSens, ySens); }
Bound(DoubleArray xValues, DoubleArray yValues, BoundCurveInterpolator interpolator) { this.nodeCount = xValues.size(); this.firstXValue = xValues.get(0); this.firstYValue = yValues.get(0); this.firstDfValue = Math.exp(-firstXValue * firstYValue); this.firstYGradient = interpolator.firstDerivative(firstXValue); double gradient = -firstYValue * firstDfValue - firstXValue * firstDfValue * firstYGradient; this.eps = EPS * (xValues.get(nodeCount - 1) - firstXValue); this.leftQuadCoef = gradient / firstXValue - (firstDfValue - 1d) / firstXValue / firstXValue; this.leftLinCoef = -gradient + 2d * (firstDfValue - 1d) / firstXValue; this.leftSens = Suppliers.memoize(() -> interpolator.parameterSensitivity(firstXValue + eps)); }
public void test_firstDerivative() { BoundCurveInterpolator bci = LL_INTERPOLATOR.bind(X_DATA, Y_DATA, FLAT_EXTRAPOLATOR, FLAT_EXTRAPOLATOR); double eps = 1e-8; double lo = bci.interpolate(0.2); double hi = bci.interpolate(0.2 + eps); double deriv = (hi - lo) / eps; assertEquals(bci.firstDerivative(0.2), deriv, 1e-6); }
@Override public double interpolate(double x, double y) { // use each y-interpolator to find the z-value for each unique x DoubleArray zValuesEffective = DoubleArray.of(yInterpolators.length, i -> yInterpolators[i].interpolate(y)); // interpolate unique x-values against derived z-values return xInterpolator.bind(xValuesUnique, zValuesEffective, xExtrapolatorLeft, xExtrapolatorRight).interpolate(x); }
@Override public UnitParameterSensitivity yValueParameterSensitivity(double x) { return createParameterSensitivity(boundInterpolator.parameterSensitivity(x)); }
@Override public double firstDerivative(double x) { return boundInterpolator.firstDerivative(x); }
BoundCurveExtrapolator boundLeft = extrapolatorLeft.bind(xValues, yValues, interpolatorOnly); BoundCurveExtrapolator boundRight = extrapolatorRight.bind(xValues, yValues, interpolatorOnly); return interpolatorOnly.bind(boundLeft, boundRight);
Bound(DoubleArray xValues, DoubleArray yValues, BoundCurveInterpolator interpolator) { this.nodeCount = xValues.size(); this.firstXValue = xValues.get(0); this.firstYValue = yValues.get(0); this.lastXValue = xValues.get(nodeCount - 1); this.lastYValue = yValues.get(nodeCount - 1); this.eps = EPS * (lastXValue - firstXValue); // left this.leftGradient = (interpolator.interpolate(firstXValue + eps) - firstYValue) / eps; this.leftSens = interpolator.parameterSensitivity(firstXValue + eps); // right this.rightGradient = (lastYValue - interpolator.interpolate(lastXValue - eps)) / eps; this.rightSens = interpolator.parameterSensitivity(lastXValue - eps); }
public void test_firstDerivative() { BoundCurveInterpolator bci = LINEAR_INTERPOLATOR.bind(X_DATA, Y_DATA, FLAT_EXTRAPOLATOR, FLAT_EXTRAPOLATOR); double eps = 1e-8; double lo = bci.interpolate(0.2); double hi = bci.interpolate(0.2 + eps); double deriv = (hi - lo) / eps; assertEquals(bci.firstDerivative(0.2), deriv, 1e-6); }
@Override public Double apply(Double x) { return 0.5 * (bind.interpolate(x + EPS) * (x + EPS) - bind.interpolate(x - EPS) * (x - EPS)) / EPS; } };
Bound(DoubleArray xValues, DoubleArray yValues, BoundCurveInterpolator interpolator) { this.nodeCount = xValues.size(); this.firstXValue = xValues.get(0); this.firstYValue = yValues.get(0); this.lastXValue = xValues.get(nodeCount - 1); double gradient = interpolator.firstDerivative(firstXValue); this.eps = EPS * (lastXValue - firstXValue); this.leftQuadCoef = gradient / firstXValue - (firstYValue - 1d) / firstXValue / firstXValue; this.leftLinCoef = -gradient + 2d * (firstYValue - 1d) / firstXValue; this.leftSens = Suppliers.memoize(() -> interpolator.parameterSensitivity(firstXValue + eps)); }
public void test_sensitivities() { BoundCurveInterpolator bci = DQ_INTERPOLATOR.bind(X_SENS, Y_SENS, FLAT_EXTRAPOLATOR, FLAT_EXTRAPOLATOR); double lastXValue = X_SENS.get(X_SENS.size() - 1); for (int i = 0; i < 100; i++) { double t = lastXValue * RANDOM.nextDouble(); DoubleArray sensitivity = bci.parameterSensitivity(t); assertEquals(sensitivity.sum(), 1d, TOL); } }
public void test_firstDerivative() { BoundCurveInterpolator bci = STEP_UPPER_INTERPOLATOR.bind(X_DATA, Y_DATA, FLAT_EXTRAPOLATOR, FLAT_EXTRAPOLATOR); for (int i = 0; i < X_DATA.size(); i++) { assertEquals(bci.firstDerivative(X_DATA.get(i)), 0d, TOL); } for (int i = 0; i < X_TEST.size(); i++) { assertEquals(bci.firstDerivative(X_TEST.get(i)), 0d, TOL); } }
public void test_firstNode() { BoundCurveInterpolator bci = LINEAR_INTERPOLATOR.bind(X_DATA, Y_DATA, FLAT_EXTRAPOLATOR, FLAT_EXTRAPOLATOR); assertEquals(bci.interpolate(0.0), 3.0, TOL); assertEquals(bci.firstDerivative(0.0), bci.firstDerivative(0.01), TOL); assertEquals(bci.parameterSensitivity(0.0).get(0), 1d, TOL); assertEquals(bci.parameterSensitivity(0.0).get(1), 0d, TOL); }
Bound(DoubleArray xValues, DoubleArray yValues, BoundCurveInterpolator interpolator) { this.nodeCount = xValues.size(); this.lastXValue = xValues.get(nodeCount - 1); this.lastYValue = yValues.get(nodeCount - 1); this.lastDf = Math.exp(-lastXValue * lastYValue); this.eps = EPS * (lastXValue - xValues.get(0)); this.rightYGradient = (lastYValue - interpolator.interpolate(lastXValue - eps)) / eps; this.rightYSens = interpolator.parameterSensitivity(lastXValue - eps).multipliedBy(-1d); this.coef1 = -lastYValue * lastDf - lastXValue * lastDf * rightYGradient; this.coef0 = lastDf - coef1 * lastXValue; }
public void test_firstDerivative() { BoundCurveInterpolator bci = DQ_INTERPOLATOR.bind(X_DATA, Y_DATA, FLAT_EXTRAPOLATOR, FLAT_EXTRAPOLATOR); double eps = 1e-8; double lo = bci.interpolate(0.2); double hi = bci.interpolate(0.2 + eps); double deriv = (hi - lo) / eps; assertEquals(bci.firstDerivative(0.2), deriv, 1e-6); }
public void test_interpolation() { BoundCurveInterpolator bci = DQ_INTERPOLATOR.bind(X_DATA, Y_DATA, FLAT_EXTRAPOLATOR, FLAT_EXTRAPOLATOR); for (int i = 0; i < X_TEST.length; i++) { assertEquals(bci.interpolate(X_TEST[i]), Y_TEST[i], 1e-8); } }
Bound(DoubleArray xValues, DoubleArray yValues, BoundCurveInterpolator interpolator) { this.nodeCount = xValues.size(); this.firstXValue = xValues.get(0); this.firstYValue = yValues.get(0); this.lastXValue = xValues.get(nodeCount - 1); this.lastYValue = yValues.get(nodeCount - 1); this.eps = EPS * (lastXValue - firstXValue); // left this.firstGradient = interpolator.firstDerivative(firstXValue); this.firstSens = Suppliers.memoize(() -> interpolator.parameterSensitivity(firstXValue)); this.firstGradSens = Suppliers.memoize(() -> interpolator.parameterSensitivity(firstXValue + eps).minus(firstSens.get()).dividedBy(eps)); // right this.lastGradient = interpolator.firstDerivative(lastXValue); this.lastSens = Suppliers.memoize(() -> interpolator.parameterSensitivity(lastXValue)); this.lastGradSens = Suppliers.memoize(() -> lastSens.get().minus(interpolator.parameterSensitivity(lastXValue - eps)).dividedBy(eps)); }
public void test_sensitivityEdgeCase() { BoundCurveInterpolator bci = DQ_INTERPOLATOR.bind(X_SENS, Y_SENS, FLAT_EXTRAPOLATOR, FLAT_EXTRAPOLATOR); double lastXValue = X_SENS.get(X_SENS.size() - 1); DoubleArray sensitivity = bci.parameterSensitivity(lastXValue); for (int i = 0; i < sensitivity.size() - 1; i++) { assertEquals(0, sensitivity.get(i), EPS); } assertEquals(1.0, sensitivity.get(sensitivity.size() - 1), EPS); }