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.exception.MathIllegalArgumentException;
26 import org.hipparchus.random.RandomDataGenerator;
27 import org.junit.jupiter.api.Test;
28
29 import static org.junit.jupiter.api.Assertions.assertEquals;
30 import static org.junit.jupiter.api.Assertions.fail;
31
32
33
34
35 final class BicubicInterpolatorTest {
36
37
38
39 @Test
40 void testPreconditions() {
41 double[] xval = new double[] {3, 4, 5, 6.5};
42 double[] yval = new double[] {-4, -3, -1, 2.5};
43 double[][] zval = new double[xval.length][yval.length];
44
45 BivariateGridInterpolator interpolator = new BicubicInterpolator();
46
47 @SuppressWarnings("unused")
48 BivariateFunction p = interpolator.interpolate(xval, yval, zval);
49
50 double[] wxval = new double[] {3, 2, 5, 6.5};
51 try {
52 p = interpolator.interpolate(wxval, yval, zval);
53 fail("an exception should have been thrown");
54 } catch (MathIllegalArgumentException e) {
55
56 }
57
58 double[] wyval = new double[] {-4, -3, -1, -1};
59 try {
60 p = interpolator.interpolate(xval, wyval, zval);
61 fail("an exception should have been thrown");
62 } catch (MathIllegalArgumentException e) {
63
64 }
65
66 double[][] wzval = new double[xval.length][yval.length + 1];
67 try {
68 p = interpolator.interpolate(xval, yval, wzval);
69 fail("an exception should have been thrown");
70 } catch (MathIllegalArgumentException e) {
71
72 }
73 wzval = new double[xval.length - 1][yval.length];
74 try {
75 p = interpolator.interpolate(xval, yval, wzval);
76 fail("an exception should have been thrown");
77 } catch (MathIllegalArgumentException e) {
78
79 }
80 }
81
82
83
84
85
86
87 @Test
88 void testPlane() {
89 BivariateFunction f = new BivariateFunction() {
90 @Override
91 public double value(double x, double y) {
92 return 2 * x - 3 * y + 5;
93 }
94 };
95
96 testInterpolation(3000,
97 1e-13,
98 f,
99 false);
100 }
101
102
103
104
105
106
107 @Test
108 void testParaboloid() {
109 BivariateFunction f = new BivariateFunction() {
110 @Override
111 public double value(double x, double y) {
112 return 2 * x * x - 3 * y * y + 4 * x * y - 5;
113 }
114 };
115
116 testInterpolation(3000,
117 1e-12,
118 f,
119 false);
120 }
121
122
123
124
125
126
127
128 private void testInterpolation(int numSamples,
129 double tolerance,
130 BivariateFunction f,
131 boolean print) {
132 final int sz = 21;
133 final double[] xval = new double[sz];
134 final double[] yval = new double[sz];
135
136 final double delta = 1d / (sz - 1);
137 for (int i = 0; i < sz; i++) {
138 xval[i] = -1 + 15 * i * delta;
139 yval[i] = -20 + 30 * i * delta;
140 }
141
142 final double[][] zval = new double[xval.length][yval.length];
143 for (int i = 0; i < xval.length; i++) {
144 for (int j = 0; j < yval.length; j++) {
145 zval[i][j] = f.value(xval[i], yval[j]);
146 }
147 }
148
149 final BicubicInterpolator interpolator = new BicubicInterpolator();
150 final BicubicInterpolatingFunction p = interpolator.interpolate(xval, yval, zval);
151 double x, y;
152
153 final RandomDataGenerator gen = new RandomDataGenerator(1234567L);
154 int count = 0;
155 while (true) {
156 x = gen.nextUniform(xval[0], xval[xval.length - 1]);
157 y = gen.nextUniform(yval[0], yval[yval.length - 1]);
158 if (!p.isValidPoint(x, y)) {
159 if (print) {
160 System.out.println("# " + x + " " + y);
161 }
162 continue;
163 }
164
165 if (count++ > numSamples) {
166 break;
167 }
168 final double expected = f.value(x, y);
169 final double actual = p.value(x, y);
170
171 if (print) {
172 System.out.println(x + " " + y + " " + expected + " " + actual);
173 }
174
175 assertEquals(expected, actual, tolerance);
176 }
177 }
178 }