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.analysis.BivariateFunction;
20 import org.apache.commons.statistics.distribution.ContinuousDistribution;
21 import org.apache.commons.statistics.distribution.UniformContinuousDistribution;
22 import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
23 import org.apache.commons.math4.legacy.exception.InsufficientDataException;
24 import org.apache.commons.math4.legacy.exception.NonMonotonicSequenceException;
25 import org.apache.commons.math4.legacy.exception.NullArgumentException;
26 import org.apache.commons.rng.UniformRandomProvider;
27 import org.apache.commons.rng.simple.RandomSource;
28 import org.apache.commons.math4.core.jdkmath.JdkMath;
29 import org.apache.commons.numbers.core.Precision;
30 import org.junit.Assert;
31 import org.junit.Test;
32
33
34
35
36 public final class PiecewiseBicubicSplineInterpolatingFunctionTest {
37
38
39
40 @Test
41 public void testPreconditions() {
42 double[] xval = new double[] { 3, 4, 5, 6.5, 7.5 };
43 double[] yval = new double[] { -4, -3, -1, 2.5, 3.5 };
44 double[][] zval = new double[xval.length][yval.length];
45
46 @SuppressWarnings("unused")
47 PiecewiseBicubicSplineInterpolatingFunction bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval, yval, zval);
48
49 try {
50 bcf = new PiecewiseBicubicSplineInterpolatingFunction(null, yval, zval);
51 Assert.fail("Failed to detect x null pointer");
52 } catch (NullArgumentException iae) {
53
54 }
55
56 try {
57 bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval, null, zval);
58 Assert.fail("Failed to detect y null pointer");
59 } catch (NullArgumentException iae) {
60
61 }
62
63 try {
64 bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval, yval, null);
65 Assert.fail("Failed to detect z null pointer");
66 } catch (NullArgumentException iae) {
67
68 }
69
70 try {
71 double xval1[] = { 0.0, 1.0, 2.0, 3.0 };
72 bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval1, yval, zval);
73 Assert.fail("Failed to detect insufficient x data");
74 } catch (InsufficientDataException iae) {
75
76 }
77
78 try {
79 double yval1[] = { 0.0, 1.0, 2.0, 3.0 };
80 bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval, yval1, zval);
81 Assert.fail("Failed to detect insufficient y data");
82 } catch (InsufficientDataException iae) {
83
84 }
85
86 try {
87 double zval1[][] = new double[4][4];
88 bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval, yval, zval1);
89 Assert.fail("Failed to detect insufficient z data");
90 } catch (InsufficientDataException iae) {
91
92 }
93
94 try {
95 double xval1[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
96 bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval1, yval, zval);
97 Assert.fail("Failed to detect data set array with different sizes.");
98 } catch (DimensionMismatchException iae) {
99
100 }
101
102 try {
103 double yval1[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
104 bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval, yval1, zval);
105 Assert.fail("Failed to detect data set array with different sizes.");
106 } catch (DimensionMismatchException iae) {
107
108 }
109
110
111 try {
112 double xval1[] = { 0.0, 1.0, 0.5, 7.0, 3.5 };
113 bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval1, yval, zval);
114 Assert.fail("Failed to detect unsorted x arguments.");
115 } catch (NonMonotonicSequenceException iae) {
116
117 }
118
119
120 try {
121 double yval1[] = { 0.0, 1.0, 1.5, 0.0, 3.0 };
122 bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval, yval1, zval);
123 Assert.fail("Failed to detect unsorted y arguments.");
124 } catch (NonMonotonicSequenceException iae) {
125
126 }
127 }
128
129
130
131
132
133
134 @Test
135 public void testPlane() {
136 final int numberOfElements = 10;
137 final double minimumX = -10;
138 final double maximumX = 10;
139 final double minimumY = -10;
140 final double maximumY = 10;
141 final int numberOfSamples = 100;
142
143 final double interpolationTolerance = 7e-15;
144 final double maxTolerance = 6e-14;
145
146
147 BivariateFunction f = new BivariateFunction() {
148 @Override
149 public double value(double x, double y) {
150 return 2 * x - 3 * y + 5;
151 }
152 };
153
154 testInterpolation(minimumX,
155 maximumX,
156 minimumY,
157 maximumY,
158 numberOfElements,
159 numberOfSamples,
160 f,
161 interpolationTolerance,
162 maxTolerance);
163 }
164
165
166
167
168
169
170 @Test
171 public void testParabaloid() {
172 final int numberOfElements = 10;
173 final double minimumX = -10;
174 final double maximumX = 10;
175 final double minimumY = -10;
176 final double maximumY = 10;
177 final int numberOfSamples = 100;
178
179 final double interpolationTolerance = 1e-13;
180 final double maxTolerance = 6e-14;
181
182
183 BivariateFunction f = new BivariateFunction() {
184 @Override
185 public double value(double x, double y) {
186 return 2 * x * x - 3 * y * y + 4 * x * y - 5;
187 }
188 };
189
190 testInterpolation(minimumX,
191 maximumX,
192 minimumY,
193 maximumY,
194 numberOfElements,
195 numberOfSamples,
196 f,
197 interpolationTolerance,
198 maxTolerance);
199 }
200
201
202
203
204
205
206
207
208
209
210
211
212 private void testInterpolation(double minimumX,
213 double maximumX,
214 double minimumY,
215 double maximumY,
216 int numberOfElements,
217 int numberOfSamples,
218 BivariateFunction f,
219 double meanTolerance,
220 double maxTolerance) {
221 double expected;
222 double actual;
223 double currentX;
224 double currentY;
225 final double deltaX = (maximumX - minimumX) / ((double) numberOfElements);
226 final double deltaY = (maximumY - minimumY) / ((double) numberOfElements);
227 final double[] xValues = new double[numberOfElements];
228 final double[] yValues = new double[numberOfElements];
229 final double[][] zValues = new double[numberOfElements][numberOfElements];
230
231 for (int i = 0; i < numberOfElements; i++) {
232 xValues[i] = minimumX + deltaX * (double) i;
233 for (int j = 0; j < numberOfElements; j++) {
234 yValues[j] = minimumY + deltaY * (double) j;
235 zValues[i][j] = f.value(xValues[i], yValues[j]);
236 }
237 }
238
239 final BivariateFunction interpolation
240 = new PiecewiseBicubicSplineInterpolatingFunction(xValues,
241 yValues,
242 zValues);
243
244 for (int i = 0; i < numberOfElements; i++) {
245 currentX = xValues[i];
246 for (int j = 0; j < numberOfElements; j++) {
247 currentY = yValues[j];
248 expected = f.value(currentX, currentY);
249 actual = interpolation.value(currentX, currentY);
250 Assert.assertTrue(Precision.equals(expected, actual));
251 }
252 }
253
254 final UniformRandomProvider rng = RandomSource.WELL_19937_C.create(1234567L);
255 final ContinuousDistribution.Sampler distX = UniformContinuousDistribution.of(xValues[0], xValues[xValues.length - 1]).createSampler(rng);
256 final ContinuousDistribution.Sampler distY = UniformContinuousDistribution.of(yValues[0], yValues[yValues.length - 1]).createSampler(rng);
257
258 double sumError = 0;
259 for (int i = 0; i < numberOfSamples; i++) {
260 currentX = distX.sample();
261 currentY = distY.sample();
262 expected = f.value(currentX, currentY);
263 actual = interpolation.value(currentX, currentY);
264 sumError += JdkMath.abs(actual - expected);
265 Assert.assertEquals(expected, actual, maxTolerance);
266 }
267
268 final double meanError = sumError / numberOfSamples;
269 Assert.assertEquals(0, meanError, meanTolerance);
270 }
271 }