View Javadoc
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.math4.legacy.analysis.interpolation;
18  
19  import org.apache.commons.math4.legacy.TestUtils;
20  import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
21  import org.apache.commons.math4.legacy.analysis.polynomials.PolynomialFunction;
22  import org.apache.commons.math4.legacy.analysis.polynomials.PolynomialSplineFunction;
23  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
24  import org.apache.commons.math4.legacy.exception.NonMonotonicSequenceException;
25  import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
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
44      public void testInterpolateLinearDegenerateTwoSegment() {
45          double x[] = {0.0, 0.5, 1.0};
46          double y[] = { 0.0, 0.5, 1.0 };
47          UnivariateInterpolator i = new LinearInterpolator();
48          UnivariateFunction f = i.interpolate(x, y);
49          verifyInterpolation(f, x, y);
50  
51          // Verify coefficients using analytical values
52          PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials();
53          double target[] = {y[0], 1d};
54          TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance);
55          target = new double[]{y[1], 1d};
56          TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance);
57  
58          // Check interpolation
59          Assert.assertEquals(0.0,f.value(0.0), interpolationTolerance);
60          Assert.assertEquals(0.4,f.value(0.4), interpolationTolerance);
61          Assert.assertEquals(1.0,f.value(1.0), interpolationTolerance);
62      }
63  
64      @Test
65      public void testInterpolateLinearDegenerateThreeSegment() {
66          double x[] = {0.0, 0.5, 1.0, 1.5};
67          double y[] = { 0.0, 0.5, 1.0, 1.5 };
68          UnivariateInterpolator i = new LinearInterpolator();
69          UnivariateFunction f = i.interpolate(x, y);
70          verifyInterpolation(f, x, y);
71  
72          // Verify coefficients using analytical values
73          PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials();
74          double target[] = {y[0], 1d};
75          TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance);
76          target = new double[]{y[1], 1d};
77          TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance);
78          target = new double[]{y[2], 1d};
79          TestUtils.assertEquals(polynomials[2].getCoefficients(), target, coefficientTolerance);
80  
81          // Check interpolation
82          Assert.assertEquals(0,f.value(0), interpolationTolerance);
83          Assert.assertEquals(1.4,f.value(1.4), interpolationTolerance);
84          Assert.assertEquals(1.5,f.value(1.5), interpolationTolerance);
85      }
86  
87      @Test
88      public void testInterpolateLinear() {
89          double x[] = { 0.0, 0.5, 1.0 };
90          double y[] = { 0.0, 0.5, 0.0 };
91          UnivariateInterpolator i = new LinearInterpolator();
92          UnivariateFunction f = i.interpolate(x, y);
93          verifyInterpolation(f, x, y);
94  
95          // Verify coefficients using analytical values
96          PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials();
97          double target[] = {y[0], 1d};
98          TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance);
99          target = new double[]{y[1], -1d};
100         TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance);
101     }
102 
103     @Test
104     public void testIllegalArguments() {
105         // Data set arrays of different size.
106         UnivariateInterpolator i = new LinearInterpolator();
107         try {
108             double xval[] = { 0.0, 1.0 };
109             double yval[] = { 0.0, 1.0, 2.0 };
110             i.interpolate(xval, yval);
111             Assert.fail("Failed to detect data set array with different sizes.");
112         } catch (DimensionMismatchException iae) {
113             // Expected.
114         }
115         // X values not sorted.
116         try {
117             double xval[] = { 0.0, 1.0, 0.5 };
118             double yval[] = { 0.0, 1.0, 2.0 };
119             i.interpolate(xval, yval);
120             Assert.fail("Failed to detect unsorted arguments.");
121         } catch (NonMonotonicSequenceException iae) {
122             // Expected.
123         }
124         // Not enough data to interpolate.
125         try {
126             double xval[] = { 0.0 };
127             double yval[] = { 0.0 };
128             i.interpolate(xval, yval);
129             Assert.fail("Failed to detect unsorted arguments.");
130         } catch (NumberIsTooSmallException iae) {
131             // Expected.
132         }
133     }
134 
135     /**
136      * verifies that f(x[i]) = y[i] for i = 0..n-1 where n is common length.
137      */
138     protected void verifyInterpolation(UnivariateFunction f, double x[], double y[]) {
139         for (int i = 0; i < x.length; i++) {
140             Assert.assertEquals(f.value(x[i]), y[i], knotTolerance);
141         }
142     }
143 }