1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.analysis.interpolation;
23
24 import org.hipparchus.analysis.BivariateFunction;
25 import org.hipparchus.analysis.CalculusFieldBivariateFunction;
26 import org.hipparchus.exception.MathIllegalArgumentException;
27 import org.hipparchus.exception.NullArgumentException;
28 import org.hipparchus.random.RandomDataGenerator;
29 import org.hipparchus.util.Binary64;
30 import org.hipparchus.util.FastMath;
31 import org.hipparchus.util.Precision;
32 import org.junit.Assert;
33 import org.junit.Test;
34
35
36
37
38 public final class PiecewiseBicubicSplineInterpolatingFunctionTest {
39
40
41
42 @Test
43 public void testPreconditions() {
44 double[] xval = new double[] { 3, 4, 5, 6.5, 7.5 };
45 double[] yval = new double[] { -4, -3, -1, 2.5, 3.5 };
46 double[][] zval = new double[xval.length][yval.length];
47
48 @SuppressWarnings("unused")
49 PiecewiseBicubicSplineInterpolatingFunction bcf = new PiecewiseBicubicSplineInterpolatingFunction(xval, yval, zval);
50
51 try {
52 new PiecewiseBicubicSplineInterpolatingFunction(null, yval, zval);
53 Assert.fail("Failed to detect x null pointer");
54 } catch (NullArgumentException iae) {
55
56 }
57
58 try {
59 new PiecewiseBicubicSplineInterpolatingFunction(xval, null, zval);
60 Assert.fail("Failed to detect y null pointer");
61 } catch (NullArgumentException iae) {
62
63 }
64
65 try {
66 new PiecewiseBicubicSplineInterpolatingFunction(xval, yval, null);
67 Assert.fail("Failed to detect z null pointer");
68 } catch (NullArgumentException iae) {
69
70 }
71
72 try {
73 final double[][] fnull = new double[1][];
74 new PiecewiseBicubicSplineInterpolatingFunction(xval, yval, fnull);
75 Assert.fail("Failed to detect z[0] null pointer");
76 } catch (NullArgumentException iae) {
77
78 }
79
80 try {
81 final double[][] f = new double[1][1];
82 new PiecewiseBicubicSplineInterpolatingFunction(new double[0], yval, f);
83 Assert.fail("Failed to detect empty x pointer");
84 } catch (MathIllegalArgumentException iae) {
85
86 }
87
88 try {
89 final double[][] f = new double[1][1];
90 new PiecewiseBicubicSplineInterpolatingFunction(xval, new double[0], f);
91 Assert.fail("Failed to detect empty y pointer");
92 } catch (MathIllegalArgumentException iae) {
93
94 }
95
96
97 try {
98 final double[][] f = new double[1][0];
99 new PiecewiseBicubicSplineInterpolatingFunction(xval, yval, f);
100 Assert.fail("Failed to detect empty z[0] pointer");
101 } catch (MathIllegalArgumentException iae) {
102
103 }
104
105 try {
106 final double[] xval1 = { 0.0, 1.0, 2.0, 3.0 };
107 new PiecewiseBicubicSplineInterpolatingFunction(xval1, yval, zval);
108 Assert.fail("Failed to detect insufficient x data");
109 } catch (MathIllegalArgumentException iae) {
110
111 }
112
113 try {
114 final double[] yval1 = { 0.0, 1.0, 2.0, 3.0 };
115 new PiecewiseBicubicSplineInterpolatingFunction(xval, yval1, zval);
116 Assert.fail("Failed to detect insufficient y data");
117 } catch (MathIllegalArgumentException iae) {
118
119 }
120
121 try {
122 final double[][] zval1 = new double[4][4];
123 new PiecewiseBicubicSplineInterpolatingFunction(xval, yval, zval1);
124 Assert.fail("Failed to detect insufficient z data");
125 } catch (MathIllegalArgumentException iae) {
126
127 }
128
129 try {
130 final double[][] zval1 = new double[5][4];
131 new PiecewiseBicubicSplineInterpolatingFunction(xval, yval, zval1);
132 Assert.fail("Failed to detect insufficient z data");
133 } catch (MathIllegalArgumentException iae) {
134
135 }
136
137 try {
138 final double[] xval1 = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
139 new PiecewiseBicubicSplineInterpolatingFunction(xval1, yval, zval);
140 Assert.fail("Failed to detect data set array with different sizes.");
141 } catch (MathIllegalArgumentException iae) {
142
143 }
144
145 try {
146 final double[] yval1 = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
147 new PiecewiseBicubicSplineInterpolatingFunction(xval, yval1, zval);
148 Assert.fail("Failed to detect data set array with different sizes.");
149 } catch (MathIllegalArgumentException iae) {
150
151 }
152
153
154 try {
155 final double[] xval1 = { 0.0, 1.0, 0.5, 7.0, 3.5 };
156 new PiecewiseBicubicSplineInterpolatingFunction(xval1, yval, zval);
157 Assert.fail("Failed to detect unsorted x arguments.");
158 } catch (MathIllegalArgumentException iae) {
159
160 }
161
162
163 try {
164 final double[] yval1 = { 0.0, 1.0, 1.5, 0.0, 3.0 };
165 new PiecewiseBicubicSplineInterpolatingFunction(xval, yval1, zval);
166 Assert.fail("Failed to detect unsorted y arguments.");
167 } catch (MathIllegalArgumentException iae) {
168
169 }
170 }
171
172
173
174
175
176
177 @Test
178 public void testPlane() {
179 final int numberOfElements = 10;
180 final double minimumX = -10;
181 final double maximumX = 10;
182 final double minimumY = -10;
183 final double maximumY = 10;
184 final int numberOfSamples = 100;
185
186 final double interpolationTolerance = 7e-15;
187 final double maxTolerance = 6e-14;
188
189
190 BivariateFunction f = (x, y) -> 2 * x - 3 * y + 5;
191 CalculusFieldBivariateFunction<Binary64> fT = (x, y) -> x.multiply(2).subtract(y.multiply(3)).add(5);
192
193 testInterpolation(minimumX,
194 maximumX,
195 minimumY,
196 maximumY,
197 numberOfElements,
198 numberOfSamples,
199 f, fT,
200 interpolationTolerance,
201 maxTolerance);
202 }
203
204
205
206
207
208
209 @Test
210 public void testParabaloid() {
211 final int numberOfElements = 10;
212 final double minimumX = -10;
213 final double maximumX = 10;
214 final double minimumY = -10;
215 final double maximumY = 10;
216 final int numberOfSamples = 100;
217
218 final double interpolationTolerance = 2e-14;
219 final double maxTolerance = 6e-14;
220
221
222 BivariateFunction f = (x, y) -> 2 * x * x - 3 * y * y + 4 * x * y - 5;
223 CalculusFieldBivariateFunction<Binary64> fT = (x, y) -> x.square().multiply(2).
224 subtract(y.square().multiply(3)).
225 add(x.multiply(y).multiply(4)).
226 subtract(5);
227
228 testInterpolation(minimumX,
229 maximumX,
230 minimumY,
231 maximumY,
232 numberOfElements,
233 numberOfSamples,
234 f, fT,
235 interpolationTolerance,
236 maxTolerance);
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251 private void testInterpolation(double minimumX,
252 double maximumX,
253 double minimumY,
254 double maximumY,
255 int numberOfElements,
256 int numberOfSamples,
257 BivariateFunction f,
258 final CalculusFieldBivariateFunction<Binary64> fT,
259 double meanTolerance,
260 double maxTolerance) {
261 double expected;
262 double actual;
263 Binary64 expected64;
264 Binary64 actual64;
265 double currentX;
266 double currentY;
267 Binary64 currentX64;
268 Binary64 currentY64;
269 final double deltaX = (maximumX - minimumX) / ((double) numberOfElements);
270 final double deltaY = (maximumY - minimumY) / ((double) numberOfElements);
271 final double[] xValues = new double[numberOfElements];
272 final double[] yValues = new double[numberOfElements];
273 final double[][] zValues = new double[numberOfElements][numberOfElements];
274
275 for (int i = 0; i < numberOfElements; i++) {
276 xValues[i] = minimumX + deltaX * (double) i;
277 for (int j = 0; j < numberOfElements; j++) {
278 yValues[j] = minimumY + deltaY * (double) j;
279 zValues[i][j] = f.value(xValues[i], yValues[j]);
280 }
281 }
282
283 final PiecewiseBicubicSplineInterpolatingFunction interpolation
284 = new PiecewiseBicubicSplineInterpolatingFunction(xValues,
285 yValues,
286 zValues);
287
288 for (int i = 0; i < numberOfElements; i++) {
289 currentX = xValues[i];
290 currentX64 = new Binary64(currentX);
291 for (int j = 0; j < numberOfElements; j++) {
292 currentY = yValues[j];
293 currentY64 = new Binary64(currentY);
294 Assert.assertTrue(Precision.equals(f.value(currentX, currentY),
295 interpolation.value(currentX, currentY)));
296 Assert.assertTrue(Precision.equals(fT.value(currentX64, currentY64).getReal(),
297 interpolation.value(currentX64, currentY64).getReal()));
298 }
299 }
300
301 final RandomDataGenerator gen = new RandomDataGenerator(1234567L);
302
303 double sumError = 0;
304 double sumError64 = 0;
305 for (int i = 0; i < numberOfSamples; i++) {
306 currentX = gen.nextUniform(xValues[0], xValues[xValues.length - 1]);
307 currentY = gen.nextUniform(yValues[0], yValues[yValues.length - 1]);
308 currentX64 = new Binary64(currentX);
309 currentY64 = new Binary64(currentY);
310 expected = f.value(currentX, currentY);
311 actual = interpolation.value(currentX, currentY);
312 expected64 = fT.value(currentX64, currentY64);
313 actual64 = interpolation.value(currentX64, currentY64);
314 sumError += FastMath.abs(actual - expected);
315 sumError64 += FastMath.abs(actual64.subtract(expected64)).getReal();
316 Assert.assertEquals(expected, actual, maxTolerance);
317 Assert.assertEquals(expected64.getReal(), actual64.getReal(), maxTolerance);
318 }
319
320 final double meanError = sumError / numberOfSamples;
321 Assert.assertEquals(0, meanError, meanTolerance);
322 final double meanError64 = sumError64 / numberOfSamples;
323 Assert.assertEquals(0, meanError64, meanTolerance);
324
325 }
326
327 @Test
328 public void testIsValidPoint() {
329
330 final double[] x = new double[] { 0., 1., 2., 3., 4. };
331 final double[] y = x.clone();
332 final PiecewiseBicubicSplineInterpolatingFunction interpolatingFunction =
333 new PiecewiseBicubicSplineInterpolatingFunction(x, y, new double[x.length][y.length]);
334
335 Assert.assertFalse(interpolatingFunction.isValidPoint(x[0] - 1, y[0]));
336 Assert.assertFalse(interpolatingFunction.isValidPoint(x[x.length - 1] + 1, y[0]));
337 Assert.assertFalse(interpolatingFunction.isValidPoint(x[0], y[0] - 1));
338 Assert.assertFalse(interpolatingFunction.isValidPoint(x[0], y[y.length - 1] + 1));
339 }
340
341 }