View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.analysis.interpolation;
23  
24  import org.hipparchus.analysis.BivariateFunction;
25  import org.hipparchus.exception.MathIllegalArgumentException;
26  import org.hipparchus.exception.NullArgumentException;
27  import org.hipparchus.random.RandomDataGenerator;
28  import org.junit.Assert;
29  import org.junit.Test;
30  
31  /**
32   * Test case for the piecewise bicubic interpolator.
33   */
34  public final class PiecewiseBicubicSplineInterpolatorTest {
35      /**
36       * Test preconditions.
37       */
38      @Test
39      public void testPreconditions() {
40          double[] xval = new double[] { 3, 4, 5, 6.5, 7.5 };
41          double[] yval = new double[] { -4, -3, -1, 2.5, 3.5 };
42          double[][] zval = new double[xval.length][yval.length];
43  
44          BivariateGridInterpolator interpolator = new PiecewiseBicubicSplineInterpolator();
45  
46          try {
47              interpolator.interpolate( null, yval, zval );
48              Assert.fail( "Failed to detect x null pointer" );
49          } catch ( NullArgumentException iae ) {
50              // Expected.
51          }
52  
53          try {
54              interpolator.interpolate( xval, null, zval );
55              Assert.fail( "Failed to detect y null pointer" );
56          } catch ( NullArgumentException iae ) {
57              // Expected.
58          }
59  
60          try {
61              interpolator.interpolate( xval, yval, null );
62              Assert.fail( "Failed to detect z null pointer" );
63          } catch ( NullArgumentException iae ) {
64              // Expected.
65          }
66  
67          try {
68              double[] xval1 = { 0.0, 1.0, 2.0, 3.0 };
69              interpolator.interpolate( xval1, yval, zval );
70              Assert.fail( "Failed to detect insufficient x data" );
71          } catch ( MathIllegalArgumentException iae ) {
72              // Expected.
73          }
74  
75          try  {
76              double[] yval1 = { 0.0, 1.0, 2.0, 3.0 };
77              interpolator.interpolate( xval, yval1, zval );
78              Assert.fail( "Failed to detect insufficient y data" );
79          } catch ( MathIllegalArgumentException iae ) {
80              // Expected.
81          }
82  
83          try {
84              double[][] zval1 = new double[4][4];
85              interpolator.interpolate( xval, yval, zval1 );
86              Assert.fail( "Failed to detect insufficient z data" );
87          } catch ( MathIllegalArgumentException iae ) {
88              // Expected.
89          }
90  
91          try {
92              double[] xval1 = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
93              interpolator.interpolate( xval1, yval, zval );
94              Assert.fail( "Failed to detect data set array with different sizes." );
95          } catch ( MathIllegalArgumentException iae ) {
96              // Expected.
97          }
98  
99          try {
100             double[] yval1 = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
101             interpolator.interpolate( xval, yval1, zval );
102             Assert.fail( "Failed to detect data set array with different sizes." );
103         } catch ( MathIllegalArgumentException iae ) {
104             // Expected.
105         }
106 
107         // X values not sorted.
108         try {
109             double[] xval1 = { 0.0, 1.0, 0.5, 7.0, 3.5 };
110             interpolator.interpolate( xval1, yval, zval );
111             Assert.fail( "Failed to detect unsorted x arguments." );
112         } catch ( MathIllegalArgumentException iae ) {
113             // Expected.
114         }
115 
116         // Y values not sorted.
117         try {
118             double[] yval1 = { 0.0, 1.0, 1.5, 0.0, 3.0 };
119             interpolator.interpolate( xval, yval1, zval );
120             Assert.fail( "Failed to detect unsorted y arguments." );
121         } catch ( MathIllegalArgumentException iae ) {
122             // Expected.
123         }
124     }
125 
126     /**
127      * Interpolating a plane.
128      * <p>
129      * z = 2 x - 3 y + 5
130      */
131     @Test
132     public void testInterpolation1() {
133         final int sz = 21;
134         double[] xval = new double[sz];
135         double[] yval = new double[sz];
136         // Coordinate values
137         final double delta = 1d / (sz - 1);
138         for ( int i = 0; i < sz; i++ ){
139             xval[i] = -1 + 15 * i * delta;
140             yval[i] = -20 + 30 * i * delta;
141         }
142 
143         // Function values
144         BivariateFunction f = new BivariateFunction() {
145                 @Override
146                 public double value( double x, double y ) {
147                     return 2 * x - 3 * y + 5;
148                 }
149             };
150         double[][] zval = new double[xval.length][yval.length];
151         for ( int i = 0; i < xval.length; i++ ) {
152             for ( int j = 0; j < yval.length; j++ ) {
153                 zval[i][j] = f.value(xval[i], yval[j]);
154             }
155         }
156 
157         BivariateGridInterpolator interpolator = new PiecewiseBicubicSplineInterpolator();
158         BivariateFunction p = interpolator.interpolate(xval, yval, zval);
159         double x, y;
160 
161         final RandomDataGenerator gen = new RandomDataGenerator(1234567L);
162         final int numSamples = 50;
163         final double tol = 2e-14;
164         for ( int i = 0; i < numSamples; i++ ) {
165             x = gen.nextUniform(xval[0], xval[xval.length - 1]);
166             for ( int j = 0; j < numSamples; j++ ) {
167                 y = gen.nextUniform(yval[0], yval[yval.length - 1]);
168 //                 System.out.println(x + " " + y + " " + f.value(x, y) + " " + p.value(x, y));
169                 Assert.assertEquals(f.value(x, y),  p.value(x, y), tol);
170             }
171 //             System.out.println();
172         }
173     }
174 
175     /**
176      * Interpolating a paraboloid.
177      * <p>
178      * z = 2 x<sup>2</sup> - 3 y<sup>2</sup> + 4 x y - 5
179      */
180     @Test
181     public void testInterpolation2() {
182         final int sz = 21;
183         double[] xval = new double[sz];
184         double[] yval = new double[sz];
185         // Coordinate values
186         final double delta = 1d / (sz - 1);
187         for ( int i = 0; i < sz; i++ ) {
188             xval[i] = -1 + 15 * i * delta;
189             yval[i] = -20 + 30 * i * delta;
190         }
191 
192         // Function values
193         BivariateFunction f = new BivariateFunction() {
194                 @Override
195                 public double value( double x, double y ) {
196                     return 2 * x * x - 3 * y * y + 4 * x * y - 5;
197                 }
198             };
199         double[][] zval = new double[xval.length][yval.length];
200         for ( int i = 0; i < xval.length; i++ ) {
201             for ( int j = 0; j < yval.length; j++ ) {
202                 zval[i][j] = f.value(xval[i], yval[j]);
203             }
204         }
205 
206         BivariateGridInterpolator interpolator = new PiecewiseBicubicSplineInterpolator();
207         BivariateFunction p = interpolator.interpolate(xval, yval, zval);
208         double x, y;
209 
210         final RandomDataGenerator gen = new RandomDataGenerator(1234567L);
211         final int numSamples = 50;
212         final double tol = 5e-13;
213         for ( int i = 0; i < numSamples; i++ ) {
214             x = gen.nextUniform(xval[0], xval[xval.length - 1]);
215             for ( int j = 0; j < numSamples; j++ ) {
216                 y = gen.nextUniform(yval[0], yval[yval.length - 1]);
217 //                 System.out.println(x + " " + y + " " + f.value(x, y) + " " + p.value(x, y));
218                 Assert.assertEquals(f.value(x, y),  p.value(x, y), tol);
219             }
220 //             System.out.println();
221         }
222     }
223 }