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 }