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