@Override protected double doFirstDerivative(double xValue) { int nCoefs = poly.getOrder(); int numberOfIntervals = poly.getNumberOfIntervals(); return differentiate(xValue, poly.getKnots(), poly.getCoefMatrix(), poly.getDimensions(), nCoefs, numberOfIntervals); }
@Override protected double doFirstDerivative(double xValue) { int nCoefs = poly.getOrder(); int numberOfIntervals = poly.getNumberOfIntervals(); return differentiate(xValue, poly.getKnots(), poly.getCoefMatrix(), poly.getDimensions(), nCoefs, numberOfIntervals); }
@Override protected double doFirstDerivative(double xValue) { double resValue = evaluate(xValue, poly.getKnots(), poly.getCoefMatrix(), poly.getDimensions()); int nCoefs = poly.getOrder(); int numberOfIntervals = poly.getNumberOfIntervals(); double resDerivative = differentiate(xValue, poly.getKnots(), poly.getCoefMatrix(), poly.getDimensions(), nCoefs, numberOfIntervals); return Math.exp(resValue) * resDerivative; }
@Override protected double doFirstDerivative(double xValue) { double resValue = evaluate(xValue, poly.getKnots(), poly.getCoefMatrix(), poly.getDimensions()); int nCoefs = poly.getOrder(); int numberOfIntervals = poly.getNumberOfIntervals(); double resDerivative = differentiate( xValue, poly.getKnots(), poly.getCoefMatrix(), poly.getDimensions(), nCoefs, numberOfIntervals); return Math.exp(resValue) * resDerivative; }
/** * Finds the first derivatives. * * @param pp the PiecewisePolynomialResult * @param xKeys the key * @return the first derivatives of piecewise polynomial functions at xKeys * When _dim in PiecewisePolynomialResult is greater than 1, i.e., the struct contains * multiple piecewise polynomials, a row vector of return value corresponds to each piecewise polynomial */ public DoubleMatrix differentiate(PiecewisePolynomialResult pp, double[] xKeys) { ArgChecker.notNull(pp, "pp"); ArgChecker.isFalse(pp.getOrder() < 2, "polynomial degree < 1"); DoubleArray knots = pp.getKnots(); int nCoefs = pp.getOrder(); int rowCount = pp.getDimensions() * pp.getNumberOfIntervals(); int colCount = nCoefs - 1; DoubleMatrix coef = DoubleMatrix.of( rowCount, colCount, (i, j) -> pp.getCoefMatrix().get(i, j) * (nCoefs - j - 1)); PiecewisePolynomialResult ppDiff = new PiecewisePolynomialResult(knots, coef, colCount, pp.getDimensions()); return evaluate(ppDiff, xKeys); }
/** * Finds the second derivatives. * * @param pp the PiecewisePolynomialResult * @param xKey the key * @return the second derivatives of piecewise polynomial functions at xKey * When _dim in PiecewisePolynomialResult is greater than 1, i.e., the struct contains * multiple piecewise polynomials, an element in the return values corresponds to each piecewise polynomial */ public DoubleArray differentiateTwice(PiecewisePolynomialResult pp, double xKey) { ArgChecker.notNull(pp, "pp"); ArgChecker.isFalse(pp.getOrder() < 3, "polynomial degree < 2"); DoubleArray knots = pp.getKnots(); int nCoefs = pp.getOrder(); int rowCount = pp.getDimensions() * pp.getNumberOfIntervals(); int colCount = nCoefs - 2; DoubleMatrix coef = DoubleMatrix.of( rowCount, colCount, (i, j) -> pp.getCoefMatrix().get(i, j) * (nCoefs - j - 1) * (nCoefs - j - 2)); PiecewisePolynomialResult ppDiff = new PiecewisePolynomialResult(knots, coef, nCoefs - 1, pp.getDimensions()); return evaluate(ppDiff, xKey); }
/** * Finds the second derivatives. * * @param pp the PiecewisePolynomialResult * @param xKeys the key * @return the second derivatives of piecewise polynomial functions at xKeys * When _dim in PiecewisePolynomialResult is greater than 1, i.e., the struct contains * multiple piecewise polynomials, a row vector of return value corresponds to each piecewise polynomial */ public DoubleMatrix differentiateTwice(PiecewisePolynomialResult pp, double[] xKeys) { ArgChecker.notNull(pp, "pp"); ArgChecker.isFalse(pp.getOrder() < 3, "polynomial degree < 2"); DoubleArray knots = pp.getKnots(); int nCoefs = pp.getOrder(); int rowCount = pp.getDimensions() * pp.getNumberOfIntervals(); int colCount = nCoefs - 2; DoubleMatrix coef = DoubleMatrix.of( rowCount, colCount, (i, j) -> pp.getCoefMatrix().get(i, j) * (nCoefs - j - 1) * (nCoefs - j - 2)); PiecewisePolynomialResult ppDiff = new PiecewisePolynomialResult(knots, coef, nCoefs - 1, pp.getDimensions()); return evaluate(ppDiff, xKeys); }
/** * Finds the first derivatives. * * @param pp the PiecewisePolynomialResult * @param xKey the key * @return the first derivatives of piecewise polynomial functions at xKey * When _dim in PiecewisePolynomialResult is greater than 1, i.e., the struct contains * multiple piecewise polynomials, an element in the return values corresponds to each piecewise polynomial */ public DoubleArray differentiate(PiecewisePolynomialResult pp, double xKey) { ArgChecker.notNull(pp, "pp"); ArgChecker.isFalse(pp.getOrder() < 2, "polynomial degree < 1"); DoubleArray knots = pp.getKnots(); int nCoefs = pp.getOrder(); int rowCount = pp.getDimensions() * pp.getNumberOfIntervals(); int colCount = nCoefs - 1; DoubleMatrix coef = DoubleMatrix.of( rowCount, colCount, (i, j) -> pp.getCoefMatrix().get(i, j) * (nCoefs - j - 1)); PiecewisePolynomialResult ppDiff = new PiecewisePolynomialResult(knots, coef, colCount, pp.getDimensions()); return evaluate(ppDiff, xKey); }
/** * */ public void localMonotonicityIncTest() { final double[] xValues = new double[] {2., 3., 5., 8., 9., 13. }; final double[] yValues = new double[] {1., 1.01, 2., 2.1, 2.2, 2.201 }; PiecewisePolynomialInterpolator interp = new NaturalSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interpPos = new MonotonicityPreservingCubicSplineInterpolator(interp); PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues); assertEquals(resultPos.getDimensions(), result.getDimensions()); assertEquals(resultPos.getNumberOfIntervals(), result.getNumberOfIntervals()); assertEquals(resultPos.getOrder(), result.getOrder()); final int nKeys = 111; double key0 = 2.; for (int i = 1; i < nKeys; ++i) { final double key = 2. + 11. / (nKeys - 1) * i; assertTrue(function.evaluate(resultPos, key).get(0) - function.evaluate(resultPos, key0).get(0) >= 0.); key0 = 2. + 11. / (nKeys - 1) * i; } }
/** * */ public void localMonotonicityClampedTest() { final double[] xValues = new double[] {-2., 3., 4., 8., 9.1, 10. }; final double[] yValues = new double[] {0., 10., 9.5, 2., 1.1, -2.2, -2.6, 0. }; PiecewisePolynomialInterpolator interp = new CubicSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interpPos = new MonotonicityPreservingCubicSplineInterpolator(interp); PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues); assertEquals(resultPos.getDimensions(), result.getDimensions()); assertEquals(resultPos.getNumberOfIntervals(), result.getNumberOfIntervals()); assertEquals(resultPos.getOrder(), result.getOrder()); final int nKeys = 121; double key0 = -2.; for (int i = 1; i < nKeys; ++i) { final double key = -2. + 12. / (nKeys - 1) * i; assertTrue(function.evaluate(resultPos, key).get(0) - function.evaluate(resultPos, key0).get(0) <= 0.); key0 = -2. + 11. / (nKeys - 1) * i; } }
/** * */ public void localMonotonicityDecTest() { final double[] xValues = new double[] {-2., 3., 4., 8., 9.1, 10. }; final double[] yValues = new double[] {10., 9.5, 2., 1.1, -2.2, -2.6 }; PiecewisePolynomialInterpolator interp = new CubicSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interpPos = new MonotonicityPreservingCubicSplineInterpolator(interp); PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues); assertEquals(resultPos.getDimensions(), result.getDimensions()); assertEquals(resultPos.getNumberOfIntervals(), result.getNumberOfIntervals()); assertEquals(resultPos.getOrder(), result.getOrder()); final int nKeys = 121; double key0 = -2.; for (int i = 1; i < nKeys; ++i) { final double key = -2. + 12. / (nKeys - 1) * i; assertTrue(function.evaluate(resultPos, key).get(0) - function.evaluate(resultPos, key0).get(0) <= 0.); key0 = -2. + 11. / (nKeys - 1) * i; } }
/** * */ public void positivityEndIntervalsTest() { final double[] xValues = new double[] {1., 2., 3., 4., 5., 6. }; final double[][] yValues = new double[][] { {0.01, 0.01, 0.01, 10., 20., 1. }, {0.01, 0.01, 10., 10., 0.01, 0.01 } }; PiecewisePolynomialInterpolator interp = new NaturalSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interpPos = new NonnegativityPreservingCubicSplineInterpolator(interp); PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues); assertEquals(resultPos.getDimensions(), result.getDimensions()); assertEquals(resultPos.getNumberOfIntervals(), result.getNumberOfIntervals()); assertEquals(resultPos.getOrder(), result.getOrder()); final int nPts = 101; for (int i = 0; i < 101; ++i) { final double key = 1. + 5. / (nPts - 1) * i; assertTrue(function.evaluate(resultPos, key).get(0) >= 0.); } int dim = yValues.length; int nData = xValues.length; for (int j = 0; j < dim; ++j) { for (int i = 1; i < nData - 2; ++i) { DoubleMatrix coefMatrix = resultPos.getCoefMatrix(); double tau = Math.signum(coefMatrix.get(dim * i + j, 3)); assertTrue(coefMatrix.get(dim * i + j, 2) * tau >= -3. * yValues[j][i] * tau / (xValues[i + 1] - xValues[i])); assertTrue(coefMatrix.get(dim * i + j, 2) * tau <= 3. * yValues[j][i] * tau / (xValues[i] - xValues[i - 1])); } } }
/** * PiecewiseCubicHermiteSplineInterpolator is not modified for positive data */ public void noModificationTest() { final double[] xValues = new double[] {1., 2., 3., 4., 5. }; final double[][] yValues = new double[][] { {0.1, 1., 1., 20., 5. }, {1., 2., 3., 0., 0. } }; PiecewisePolynomialInterpolator interp = new PiecewiseCubicHermiteSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); PiecewisePolynomialInterpolator interpPos = new NonnegativityPreservingCubicSplineInterpolator(interp); PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues); assertEquals(resultPos.getDimensions(), result.getDimensions()); assertEquals(resultPos.getNumberOfIntervals(), result.getNumberOfIntervals()); assertEquals(resultPos.getOrder(), result.getOrder()); for (int i = 1; i < xValues.length - 1; ++i) { for (int j = 0; j < 4; ++j) { final double ref = result.getCoefMatrix().get(i, j) == 0. ? 1. : Math.abs(result.getCoefMatrix().get(i, j)); assertEquals(resultPos.getCoefMatrix().get(i, j), result.getCoefMatrix().get(i, j), ref * EPS); } } }
/** * */ public void positivityClampedTest() { final double[] xValues = new double[] {1., 2., 3., 4., 5. }; final double[] yValues = new double[] {0., 0.1, 1., 1., 20., 5., 0. }; PiecewisePolynomialInterpolator interp = new CubicSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interpPos = new NonnegativityPreservingCubicSplineInterpolator(interp); PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues); assertEquals(resultPos.getDimensions(), result.getDimensions()); assertEquals(resultPos.getNumberOfIntervals(), result.getNumberOfIntervals()); assertEquals(resultPos.getOrder(), result.getOrder()); final int nPts = 101; for (int i = 0; i < 101; ++i) { final double key = 1. + 4. / (nPts - 1) * i; assertTrue(function.evaluate(resultPos, key).get(0) >= 0.); } final int nData = xValues.length; for (int i = 1; i < nData - 2; ++i) { final double tau = Math.signum(resultPos.getCoefMatrix().get(i, 3)); assertTrue(resultPos.getCoefMatrix().get(i, 2) * tau >= -3. * yValues[i + 1] * tau / (xValues[i + 1] - xValues[i])); assertTrue(resultPos.getCoefMatrix().get(i, 2) * tau <= 3. * yValues[i + 1] * tau / (xValues[i] - xValues[i - 1])); } }
/** * */ public void positivityNotAKnotTest() { final double[] xValues = new double[] {1., 2., 3., 4., 5. }; final double[] yValues = new double[] {0.1, 1., 1., 20., 5. }; PiecewisePolynomialInterpolator interp = new CubicSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interpPos = new NonnegativityPreservingCubicSplineInterpolator(interp); PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues); assertEquals(resultPos.getDimensions(), result.getDimensions()); assertEquals(resultPos.getNumberOfIntervals(), result.getNumberOfIntervals()); assertEquals(resultPos.getOrder(), result.getOrder()); final int nPts = 101; for (int i = 0; i < 101; ++i) { final double key = 1. + 4. / (nPts - 1) * i; assertTrue(function.evaluate(resultPos, key).get(0) >= 0.); } final int nData = xValues.length; for (int i = 1; i < nData - 2; ++i) { final double tau = Math.signum(resultPos.getCoefMatrix().get(i, 3)); assertTrue(resultPos.getCoefMatrix().get(i, 2) * tau >= -3. * yValues[i] * tau / (xValues[i + 1] - xValues[i])); assertTrue(resultPos.getCoefMatrix().get(i, 2) * tau <= 3. * yValues[i] * tau / (xValues[i] - xValues[i - 1])); } }
/** * */ public void flipTest() { final double[] xValues = new double[] {1., 2., 3., 4., 5., 6. }; final double[] yValues = new double[] {3., 0.1, 0.01, 0.01, 0.1, 3. }; final double[] xValuesFlip = new double[] {6., 2., 3., 5., 4., 1. }; final double[] yValuesFlip = new double[] {3., 0.1, 0.01, 0.1, 0.01, 3. }; PiecewisePolynomialInterpolator interp = new NaturalSplineInterpolator(); PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interpPos = new NonnegativityPreservingCubicSplineInterpolator(interp); PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues); PiecewisePolynomialResult resultPosFlip = interpPos.interpolate(xValuesFlip, yValuesFlip); assertEquals(resultPos.getDimensions(), resultPosFlip.getDimensions()); assertEquals(resultPos.getNumberOfIntervals(), resultPosFlip.getNumberOfIntervals()); assertEquals(resultPos.getOrder(), resultPosFlip.getOrder()); final int nPts = 101; for (int i = 0; i < 101; ++i) { final double key = 1. + 5. / (nPts - 1) * i; assertTrue(function.evaluate(resultPos, key).get(0) >= 0.); } final int nData = xValues.length; for (int i = 0; i < nData - 1; ++i) { for (int k = 0; k < 4; ++k) assertEquals(resultPos.getCoefMatrix().get(i, k), resultPosFlip.getCoefMatrix().get(i, k)); } }
/** * */ public void localMonotonicityClampedMultiTest() { final double[] xValues = new double[] {-2., 3., 4., 8., 9.1, 10. }; final double[][] yValues = new double[][] { {0., 10., 9.5, 2., 1.1, -2.2, -2.6, 0. }, {10., 10., 9.5, 2., 1.1, -2.2, -2.6, 10. } }; PiecewisePolynomialInterpolator interp = new CubicSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interpPos = new MonotonicityPreservingCubicSplineInterpolator(interp); PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues); assertEquals(resultPos.getDimensions(), result.getDimensions()); assertEquals(resultPos.getNumberOfIntervals(), result.getNumberOfIntervals()); assertEquals(resultPos.getOrder(), result.getOrder()); final int nKeys = 121; double key0 = -2.; for (int i = 1; i < nKeys; ++i) { final double key = -2. + 12. / (nKeys - 1) * i; assertTrue(function.evaluate(resultPos, key).get(0) - function.evaluate(resultPos, key0).get(0) <= 0.); key0 = -2. + 11. / (nKeys - 1) * i; } key0 = -2.; for (int i = 1; i < nKeys; ++i) { final double key = -2. + 12. / (nKeys - 1) * i; assertTrue(function.evaluate(resultPos, key).get(1) - function.evaluate(resultPos, key0).get(1) <= 0.); key0 = -2. + 11. / (nKeys - 1) * i; } }
/** * */ public void extremumTest() { final double[] xValues = new double[] {1., 2., 3., 4., 5., 6., 7. }; final double[] yValues = new double[] {1., 1., 4., 5., 4., 1., 1. }; PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interp = new ConstrainedCubicSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); assertEquals(result.getDimensions(), 1); assertEquals(result.getNumberOfIntervals(), 6); assertEquals(result.getOrder(), 4); final int nKeys = 31; double key0 = 1.; for (int i = 1; i < nKeys; ++i) { final double key = 1. + 3. / (nKeys - 1) * i; assertTrue(function.evaluate(result, key).get(0) - function.evaluate(result, key0).get(0) >= 0.); key0 = 1. + 3. / (nKeys - 1) * i; } key0 = 4.; for (int i = 1; i < nKeys; ++i) { final double key = 4. + 3. / (nKeys - 1) * i; assertTrue(function.evaluate(result, key).get(0) - function.evaluate(result, key0).get(0) <= 0.); key0 = 4. + 3. / (nKeys - 1) * i; } }
/** * PiecewiseCubicHermiteSplineInterpolator is not modified except the first 2 and last 2 intervals */ public void localMonotonicityDec2Test() { final double[] xValues = new double[] {-2., 3., 4., 8., 9.1, 10., 12., 14. }; final double[] yValues = new double[] {11., 9.5, 2., 1.1, -2.2, -2.6, 2., 2. }; PiecewisePolynomialInterpolator interp = new PiecewiseCubicHermiteSplineInterpolator(); PiecewisePolynomialResult result = interp.interpolate(xValues, yValues); PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D(); PiecewisePolynomialInterpolator interpPos = new MonotonicityPreservingCubicSplineInterpolator(interp); PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues); assertEquals(resultPos.getDimensions(), result.getDimensions()); assertEquals(resultPos.getNumberOfIntervals(), result.getNumberOfIntervals()); assertEquals(resultPos.getOrder(), result.getOrder()); for (int i = 2; i < resultPos.getNumberOfIntervals() - 2; ++i) { for (int j = 0; j < 4; ++j) { assertEquals(resultPos.getCoefMatrix().get(i, j), result.getCoefMatrix().get(i, j), EPS); } } final int nKeys = 121; double key0 = -2.; for (int i = 1; i < nKeys; ++i) { final double key = -2. + 12. / (nKeys - 1) * i; assertTrue(function.evaluate(resultPos, key).get(0) - function.evaluate(resultPos, key0).get(0) <= 0.); key0 = -2. + 11. / (nKeys - 1) * i; } }