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