@Override protected DoubleArray doParameterSensitivity(double xValue) { double[] result = new double[yValues.length]; int lowerIndex = lowerBoundIndex(xValue, xValues); // check if x-value is at the last node if (lowerIndex == intervalCount) { // sensitivity is entirely to the last node result[intervalCount] = 1d; } else { double x1 = xValues[lowerIndex]; double x2 = xValues[lowerIndex + 1]; double y1 = yValues[lowerIndex]; double y2 = yValues[lowerIndex + 1]; double diffInv = 1.0 / (x2 - x1); double x1diffInv = (xValue - x1) * diffInv; double x2diffInv = (x2 - xValue) * diffInv; double yDiv = y1 / y2; result[lowerIndex] = Math.pow(yDiv, -x1diffInv) * x2diffInv; result[lowerIndex + 1] = Math.pow(yDiv, x2diffInv) * x1diffInv; } return DoubleArray.ofUnsafe(result); }
@Override protected double doFirstDerivative(double xValue) { int lowerIndex = lowerBoundIndex(xValue, xValues); // check if x-value is at the last node if (lowerIndex == intervalCount) { // if value is at last node, calculate the gradient from the previous interval double x1 = xValues[lowerIndex - 1]; double x2 = xValues[lowerIndex]; double y1 = yValues[lowerIndex - 1]; double y2 = yValues[lowerIndex]; return y2 * Math.log(y2 / y1) / (x2 - x1); } double x1 = xValues[lowerIndex]; double x2 = xValues[lowerIndex + 1]; double y1 = yValues[lowerIndex]; double y2 = yValues[lowerIndex + 1]; double yDiv = y2 / y1; double xDiff = (x2 - x1); return Math.pow(yDiv, (xValue - x1) / xDiff) * y1 * Math.log(yDiv) / xDiff; }
@Override protected double doInterpolateFromExtrapolator(double xValue) { int lowerIndex = lowerBoundIndex(xValue, xValues); // check if x-value is at the last node if (lowerIndex == intervalCount) { // if value is at last node, calculate using the previous interval lowerIndex--; } double x1 = xValues[lowerIndex]; double x2 = xValues[lowerIndex + 1]; double y1 = yValues[lowerIndex]; double y2 = yValues[lowerIndex + 1]; return Math.pow(y2 / y1, (xValue - x1) / (x2 - x1)) * y1; }
@Override public BoundCurveInterpolator bind(DoubleArray xValues, DoubleArray yValues) { return new Bound(xValues, yValues); }
@Override public BoundCurveInterpolator bind( BoundCurveExtrapolator extrapolatorLeft, BoundCurveExtrapolator extrapolatorRight) { return new Bound(this, extrapolatorLeft, extrapolatorRight); } }
@Override protected double doInterpolate(double xValue) { // x-value is less than the x-value of the last node (lowerIndex < intervalCount) int lowerIndex = lowerBoundIndex(xValue, xValues); double x1 = xValues[lowerIndex]; double x2 = xValues[lowerIndex + 1]; double y1 = yValues[lowerIndex]; double y2 = yValues[lowerIndex + 1]; return Math.pow(y2 / y1, (xValue - x1) / (x2 - x1)) * y1; }