1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.math3.analysis.interpolation; 18 19 import org.apache.commons.math3.exception.NonMonotonicSequenceException; 20 import org.apache.commons.math3.exception.DimensionMismatchException; 21 import org.apache.commons.math3.exception.NumberIsTooSmallException; 22 import org.apache.commons.math3.TestUtils; 23 import org.apache.commons.math3.analysis.UnivariateFunction; 24 import org.apache.commons.math3.analysis.polynomials.PolynomialFunction; 25 import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction; 26 import org.junit.Assert; 27 import org.junit.Test; 28 29 /** 30 * Test the LinearInterpolator. 31 */ 32 public class LinearInterpolatorTest { 33 34 /** error tolerance for spline interpolator value at knot points */ 35 protected double knotTolerance = 1E-12; 36 37 /** error tolerance for interpolating polynomial coefficients */ 38 protected double coefficientTolerance = 1E-6; 39 40 /** error tolerance for interpolated values */ 41 protected double interpolationTolerance = 1E-12; 42 43 @Test testInterpolateLinearDegenerateTwoSegment()44 public void testInterpolateLinearDegenerateTwoSegment() 45 { 46 double x[] = { 0.0, 0.5, 1.0 }; 47 double y[] = { 0.0, 0.5, 1.0 }; 48 UnivariateInterpolator i = new LinearInterpolator(); 49 UnivariateFunction f = i.interpolate(x, y); 50 verifyInterpolation(f, x, y); 51 52 // Verify coefficients using analytical values 53 PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials(); 54 double target[] = {y[0], 1d}; 55 TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance); 56 target = new double[]{y[1], 1d}; 57 TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance); 58 59 // Check interpolation 60 Assert.assertEquals(0.0,f.value(0.0), interpolationTolerance); 61 Assert.assertEquals(0.4,f.value(0.4), interpolationTolerance); 62 Assert.assertEquals(1.0,f.value(1.0), interpolationTolerance); 63 } 64 65 @Test testInterpolateLinearDegenerateThreeSegment()66 public void testInterpolateLinearDegenerateThreeSegment() 67 { 68 double x[] = { 0.0, 0.5, 1.0, 1.5 }; 69 double y[] = { 0.0, 0.5, 1.0, 1.5 }; 70 UnivariateInterpolator i = new LinearInterpolator(); 71 UnivariateFunction f = i.interpolate(x, y); 72 verifyInterpolation(f, x, y); 73 74 // Verify coefficients using analytical values 75 PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials(); 76 double target[] = {y[0], 1d}; 77 TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance); 78 target = new double[]{y[1], 1d}; 79 TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance); 80 target = new double[]{y[2], 1d}; 81 TestUtils.assertEquals(polynomials[2].getCoefficients(), target, coefficientTolerance); 82 83 // Check interpolation 84 Assert.assertEquals(0,f.value(0), interpolationTolerance); 85 Assert.assertEquals(1.4,f.value(1.4), interpolationTolerance); 86 Assert.assertEquals(1.5,f.value(1.5), interpolationTolerance); 87 } 88 89 @Test testInterpolateLinear()90 public void testInterpolateLinear() { 91 double x[] = { 0.0, 0.5, 1.0 }; 92 double y[] = { 0.0, 0.5, 0.0 }; 93 UnivariateInterpolator i = new LinearInterpolator(); 94 UnivariateFunction f = i.interpolate(x, y); 95 verifyInterpolation(f, x, y); 96 97 // Verify coefficients using analytical values 98 PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials(); 99 double target[] = {y[0], 1d}; 100 TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance); 101 target = new double[]{y[1], -1d}; 102 TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance); 103 } 104 105 @Test testIllegalArguments()106 public void testIllegalArguments() { 107 // Data set arrays of different size. 108 UnivariateInterpolator i = new LinearInterpolator(); 109 try { 110 double xval[] = { 0.0, 1.0 }; 111 double yval[] = { 0.0, 1.0, 2.0 }; 112 i.interpolate(xval, yval); 113 Assert.fail("Failed to detect data set array with different sizes."); 114 } catch (DimensionMismatchException iae) { 115 // Expected. 116 } 117 // X values not sorted. 118 try { 119 double xval[] = { 0.0, 1.0, 0.5 }; 120 double yval[] = { 0.0, 1.0, 2.0 }; 121 i.interpolate(xval, yval); 122 Assert.fail("Failed to detect unsorted arguments."); 123 } catch (NonMonotonicSequenceException iae) { 124 // Expected. 125 } 126 // Not enough data to interpolate. 127 try { 128 double xval[] = { 0.0 }; 129 double yval[] = { 0.0 }; 130 i.interpolate(xval, yval); 131 Assert.fail("Failed to detect unsorted arguments."); 132 } catch (NumberIsTooSmallException iae) { 133 // Expected. 134 } 135 } 136 137 /** 138 * verifies that f(x[i]) = y[i] for i = 0..n-1 where n is common length. 139 */ verifyInterpolation(UnivariateFunction f, double x[], double y[])140 protected void verifyInterpolation(UnivariateFunction f, double x[], double y[]) 141 { 142 for (int i = 0; i < x.length; i++) { 143 Assert.assertEquals(f.value(x[i]), y[i], knotTolerance); 144 } 145 } 146 147 } 148