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.TrivariateFunction;
25 import org.hipparchus.exception.MathIllegalArgumentException;
26 import org.hipparchus.util.FastMath;
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.assertFalse;
31 import static org.junit.jupiter.api.Assertions.assertTrue;
32 import static org.junit.jupiter.api.Assertions.fail;
33
34
35
36
37 public final class TricubicInterpolatorTest {
38
39
40
41 @Test
42 void testPreconditions() {
43 double[] xval = new double[] {3, 4, 5, 6.5};
44 double[] yval = new double[] {-4, -3, -1, 2.5};
45 double[] zval = new double[] {-12, -8, -5.5, -3, 0, 2.5};
46 double[][][] fval = new double[xval.length][yval.length][zval.length];
47
48 @SuppressWarnings("unused")
49 TrivariateFunction tcf = new TricubicInterpolator().interpolate(xval, yval, zval, fval);
50
51 double[] wxval = new double[] {3, 2, 5, 6.5};
52 try {
53 tcf = new TricubicInterpolator().interpolate(wxval, yval, zval, fval);
54 fail("an exception should have been thrown");
55 } catch (MathIllegalArgumentException e) {
56
57 }
58 double[] wyval = new double[] {-4, -1, -1, 2.5};
59 try {
60 tcf = new TricubicInterpolator().interpolate(xval, wyval, zval, fval);
61 fail("an exception should have been thrown");
62 } catch (MathIllegalArgumentException e) {
63
64 }
65 double[] wzval = new double[] {-12, -8, -9, -3, 0, 2.5};
66 try {
67 tcf = new TricubicInterpolator().interpolate(xval, yval, wzval, fval);
68 fail("an exception should have been thrown");
69 } catch (MathIllegalArgumentException e) {
70
71 }
72 double[][][] wfval = new double[xval.length - 1][yval.length][zval.length];
73 try {
74 tcf = new TricubicInterpolator().interpolate(xval, yval, zval, wfval);
75 fail("an exception should have been thrown");
76 } catch (MathIllegalArgumentException e) {
77
78 }
79 wfval = new double[xval.length][yval.length - 1][zval.length];
80 try {
81 tcf = new TricubicInterpolator().interpolate(xval, yval, zval, wfval);
82 fail("an exception should have been thrown");
83 } catch (MathIllegalArgumentException e) {
84
85 }
86 wfval = new double[xval.length][yval.length][zval.length - 1];
87 try {
88 tcf = new TricubicInterpolator().interpolate(xval, yval, zval, wfval);
89 fail("an exception should have been thrown");
90 } catch (MathIllegalArgumentException e) {
91
92 }
93 }
94
95 public void testIsValid() {
96 double[] xval = new double[] {3, 4, 5, 6.5};
97 double[] yval = new double[] {-4, -3, -1, 2.5};
98 double[] zval = new double[] {-12, -8, -5.5, -3, 0, 2.5};
99 double[][][] fval = new double[xval.length][yval.length][zval.length];
100
101 TricubicInterpolatingFunction tcf = new TricubicInterpolator().interpolate(xval, yval, zval, fval);
102
103
104 assertTrue(tcf.isValidPoint(4, -3, -8));
105 assertTrue(tcf.isValidPoint(5, -3, -8));
106 assertTrue(tcf.isValidPoint(4, -1, -8));
107 assertTrue(tcf.isValidPoint(5, -1, -8));
108 assertTrue(tcf.isValidPoint(4, -3, 0));
109 assertTrue(tcf.isValidPoint(5, -3, 0));
110 assertTrue(tcf.isValidPoint(4, -1, 0));
111 assertTrue(tcf.isValidPoint(5, -1, 0));
112
113
114 assertFalse(tcf.isValidPoint(3.5, -3, -8));
115 assertFalse(tcf.isValidPoint(4.5, -3.1, -8));
116 assertFalse(tcf.isValidPoint(4.5, -2, 0));
117 assertFalse(tcf.isValidPoint(4.5, 0, -3.5));
118 assertFalse(tcf.isValidPoint(-10, 4.1, -1));
119 }
120
121
122
123
124
125
126
127 @Test
128 void testPlane() {
129 double[] xval = new double[] {3, 4, 5, 6.5};
130 double[] yval = new double[] {-4, -3, -1, 2, 2.5};
131 double[] zval = new double[] {-12, -8, -5.5, -3, 0, 2.5};
132
133
134 TrivariateFunction f = new TrivariateFunction() {
135 @Override
136 public double value(double x, double y, double z) {
137 return 2 * x - 3 * y - 4 * z + 5;
138 }
139 };
140
141 double[][][] fval = new double[xval.length][yval.length][zval.length];
142
143 for (int i = 0; i < xval.length; i++) {
144 for (int j = 0; j < yval.length; j++) {
145 for (int k = 0; k < zval.length; k++) {
146 fval[i][j][k] = f.value(xval[i], yval[j], zval[k]);
147 }
148 }
149 }
150
151 TrivariateFunction tcf = new TricubicInterpolator().interpolate(xval,
152 yval,
153 zval,
154 fval);
155 double x, y, z;
156 double expected, result;
157
158 x = 4;
159 y = -3;
160 z = 0;
161 expected = f.value(x, y, z);
162 result = tcf.value(x, y, z);
163 assertEquals(expected, result, 1e-15, "On sample point");
164
165 x = 4.5;
166 y = -1.5;
167 z = -4.25;
168 expected = f.value(x, y, z);
169 result = tcf.value(x, y, z);
170 assertEquals(expected, result, 1e-14, "Half-way between sample points (middle of the patch)");
171 }
172
173
174
175
176
177
178
179
180 @Test
181 void testWave() {
182 double[] xval = new double[] {3, 4, 5, 6.5};
183 double[] yval = new double[] {-4, -3, -1, 2, 2.5};
184 double[] zval = new double[] {-12, -8, -5.5, -3, 0, 4};
185
186 final double a = 0.2;
187 final double omega = 0.5;
188 final double kx = 2;
189 final double ky = 1;
190
191
192 TrivariateFunction f = new TrivariateFunction() {
193 @Override
194 public double value(double x, double y, double z) {
195 return a * FastMath.cos(omega * z - kx * x - ky * y);
196 }
197 };
198
199 double[][][] fval = new double[xval.length][yval.length][zval.length];
200 for (int i = 0; i < xval.length; i++) {
201 for (int j = 0; j < yval.length; j++) {
202 for (int k = 0; k < zval.length; k++) {
203 fval[i][j][k] = f.value(xval[i], yval[j], zval[k]);
204 }
205 }
206 }
207
208 TrivariateFunction tcf = new TricubicInterpolator().interpolate(xval,
209 yval,
210 zval,
211 fval);
212
213 double x, y, z;
214 double expected, result;
215
216 x = 4;
217 y = -3;
218 z = 0;
219 expected = f.value(x, y, z);
220 result = tcf.value(x, y, z);
221 assertEquals(expected, result, 1e-14, "On sample point");
222
223 x = 4.5;
224 y = -1.5;
225 z = -4.25;
226 expected = f.value(x, y, z);
227 result = tcf.value(x, y, z);
228 assertEquals(expected, result, 1e-1, "Half-way between sample points (middle of the patch)");
229 }
230 }