1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.apache.commons.math4.core.jdkmath.JdkMath;
27 import org.junit.Assert;
28 import org.junit.Test;
29
30
31
32
33
34 public class SplineInterpolatorTest {
35
36
37 protected double knotTolerance = 1E-14;
38
39
40 protected double coefficientTolerance = 1E-14;
41
42
43 protected double interpolationTolerance = 1E-14;
44
45 @Test
46 public void testInterpolateLinearDegenerateTwoSegment() {
47 double tolerance = 1e-15;
48 double x[] = { 0.0, 0.5, 1.0 };
49 double y[] = { 0.0, 0.5, 1.0 };
50 UnivariateInterpolator i = new SplineInterpolator();
51 UnivariateFunction f = i.interpolate(x, y);
52 verifyInterpolation(f, x, y);
53 verifyConsistency((PolynomialSplineFunction) f, x);
54
55
56 PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials();
57 double target[] = {y[0], 1d};
58 TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance);
59 target = new double[]{y[1], 1d};
60 TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance);
61
62
63 Assert.assertEquals(0.0,f.value(0.0), tolerance);
64 Assert.assertEquals(0.4,f.value(0.4), tolerance);
65 Assert.assertEquals(1.0,f.value(1.0), tolerance);
66 }
67
68 @Test
69 public void testInterpolateLinearDegenerateThreeSegment() {
70 double tolerance = 1e-15;
71 double x[] = { 0.0, 0.5, 1.0, 1.5 };
72 double y[] = { 0.0, 0.5, 1.0, 1.5 };
73 UnivariateInterpolator i = new SplineInterpolator();
74 UnivariateFunction f = i.interpolate(x, y);
75 verifyInterpolation(f, x, y);
76
77
78 PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials();
79 double target[] = {y[0], 1d};
80 TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance);
81 target = new double[]{y[1], 1d};
82 TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance);
83 target = new double[]{y[2], 1d};
84 TestUtils.assertEquals(polynomials[2].getCoefficients(), target, coefficientTolerance);
85
86
87 Assert.assertEquals(0,f.value(0), tolerance);
88 Assert.assertEquals(1.4,f.value(1.4), tolerance);
89 Assert.assertEquals(1.5,f.value(1.5), tolerance);
90 }
91
92 @Test
93 public void testInterpolateLinear() {
94 double x[] = { 0.0, 0.5, 1.0 };
95 double y[] = { 0.0, 0.5, 0.0 };
96 UnivariateInterpolator i = new SplineInterpolator();
97 UnivariateFunction f = i.interpolate(x, y);
98 verifyInterpolation(f, x, y);
99 verifyConsistency((PolynomialSplineFunction) f, x);
100
101
102 PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials();
103 double target[] = {y[0], 1.5d, 0d, -2d};
104 TestUtils.assertEquals(polynomials[0].getCoefficients(), target, coefficientTolerance);
105 target = new double[]{y[1], 0d, -3d, 2d};
106 TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance);
107 }
108
109 @Test
110 public void testInterpolateSin() {
111 double sineCoefficientTolerance = 1e-6;
112 double sineInterpolationTolerance = 0.0043;
113 double x[] =
114 {
115 0.0,
116 JdkMath.PI / 6d,
117 JdkMath.PI / 2d,
118 5d * JdkMath.PI / 6d,
119 JdkMath.PI,
120 7d * JdkMath.PI / 6d,
121 3d * JdkMath.PI / 2d,
122 11d * JdkMath.PI / 6d,
123 2.d * JdkMath.PI };
124 double y[] = { 0d, 0.5d, 1d, 0.5d, 0d, -0.5d, -1d, -0.5d, 0d };
125 UnivariateInterpolator i = new SplineInterpolator();
126 UnivariateFunction f = i.interpolate(x, y);
127 verifyInterpolation(f, x, y);
128 verifyConsistency((PolynomialSplineFunction) f, x);
129
130
131
132
133
134
135
136
137
138
139 PolynomialFunction polynomials[] = ((PolynomialSplineFunction) f).getPolynomials();
140 double target[] = {y[0], 1.002676d, 0d, -0.17415829d};
141 TestUtils.assertEquals(polynomials[0].getCoefficients(), target, sineCoefficientTolerance);
142 target = new double[]{y[1], 8.594367e-01, -2.735672e-01, -0.08707914};
143 TestUtils.assertEquals(polynomials[1].getCoefficients(), target, sineCoefficientTolerance);
144 target = new double[]{y[2], 1.471804e-17,-5.471344e-01, 0.08707914};
145 TestUtils.assertEquals(polynomials[2].getCoefficients(), target, sineCoefficientTolerance);
146 target = new double[]{y[3], -8.594367e-01, -2.735672e-01, 0.17415829};
147 TestUtils.assertEquals(polynomials[3].getCoefficients(), target, sineCoefficientTolerance);
148 target = new double[]{y[4], -1.002676, 6.548562e-17, 0.17415829};
149 TestUtils.assertEquals(polynomials[4].getCoefficients(), target, sineCoefficientTolerance);
150 target = new double[]{y[5], -8.594367e-01, 2.735672e-01, 0.08707914};
151 TestUtils.assertEquals(polynomials[5].getCoefficients(), target, sineCoefficientTolerance);
152 target = new double[]{y[6], 3.466465e-16, 5.471344e-01, -0.08707914};
153 TestUtils.assertEquals(polynomials[6].getCoefficients(), target, sineCoefficientTolerance);
154 target = new double[]{y[7], 8.594367e-01, 2.735672e-01, -0.17415829};
155 TestUtils.assertEquals(polynomials[7].getCoefficients(), target, sineCoefficientTolerance);
156
157
158 Assert.assertEquals(JdkMath.sqrt(2d) / 2d,f.value(JdkMath.PI/4d),sineInterpolationTolerance);
159 Assert.assertEquals(JdkMath.sqrt(2d) / 2d,f.value(3d*JdkMath.PI/4d),sineInterpolationTolerance);
160 }
161
162 @Test
163 public void testIllegalArguments() {
164
165 UnivariateInterpolator i = new SplineInterpolator();
166 try {
167 double xval[] = { 0.0, 1.0 };
168 double yval[] = { 0.0, 1.0, 2.0 };
169 i.interpolate(xval, yval);
170 Assert.fail("Failed to detect data set array with different sizes.");
171 } catch (DimensionMismatchException iae) {
172
173 }
174
175 try {
176 double xval[] = { 0.0, 1.0, 0.5 };
177 double yval[] = { 0.0, 1.0, 2.0 };
178 i.interpolate(xval, yval);
179 Assert.fail("Failed to detect unsorted arguments.");
180 } catch (NonMonotonicSequenceException iae) {
181
182 }
183
184 try {
185 double xval[] = { 0.0, 1.0 };
186 double yval[] = { 0.0, 1.0 };
187 i.interpolate(xval, yval);
188 Assert.fail("Failed to detect unsorted arguments.");
189 } catch (NumberIsTooSmallException iae) {
190
191 }
192 }
193
194
195
196
197 protected void verifyInterpolation(UnivariateFunction f, double x[], double y[]) {
198 for (int i = 0; i < x.length; i++) {
199 Assert.assertEquals(f.value(x[i]), y[i], knotTolerance);
200 }
201 }
202
203
204
205
206
207 protected void verifyConsistency(PolynomialSplineFunction f, double x[]) {
208 PolynomialFunction polynomials[] = f.getPolynomials();
209 for (int i = 1; i < x.length - 2; i++) {
210
211 Assert.assertEquals(polynomials[i].value(x[i +1] - x[i]), polynomials[i + 1].value(0), 0.1);
212 Assert.assertEquals(polynomials[i].polynomialDerivative().value(x[i +1] - x[i]),
213 polynomials[i + 1].polynomialDerivative().value(0), 0.5);
214 Assert.assertEquals(polynomials[i].polynomialDerivative().polynomialDerivative().value(x[i +1] - x[i]),
215 polynomials[i + 1].polynomialDerivative().polynomialDerivative().value(0), 0.5);
216 }
217 }
218 }