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.jupiter.api.Test;
29  
30  import static org.junit.jupiter.api.Assertions.assertEquals;
31  import static org.junit.jupiter.api.Assertions.fail;
32  
33  /**
34   * Test case for the piecewise bicubic interpolator.
35   */
36  final class PiecewiseBicubicSplineInterpolatorTest {
37      /**
38       * Test preconditions.
39       */
40      @Test
41      void testPreconditions() {
42          double[] xval = new double[] { 3, 4, 5, 6.5, 7.5 };
43          double[] yval = new double[] { -4, -3, -1, 2.5, 3.5 };
44          double[][] zval = new double[xval.length][yval.length];
45  
46          BivariateGridInterpolator interpolator = new PiecewiseBicubicSplineInterpolator();
47  
48          try {
49              interpolator.interpolate( null, yval, zval );
50              fail( "Failed to detect x null pointer" );
51          } catch ( NullArgumentException iae ) {
52              // Expected.
53          }
54  
55          try {
56              interpolator.interpolate( xval, null, zval );
57              fail( "Failed to detect y null pointer" );
58          } catch ( NullArgumentException iae ) {
59              // Expected.
60          }
61  
62          try {
63              interpolator.interpolate( xval, yval, null );
64              fail( "Failed to detect z null pointer" );
65          } catch ( NullArgumentException iae ) {
66              // Expected.
67          }
68  
69          try {
70              double[] xval1 = { 0.0, 1.0, 2.0, 3.0 };
71              interpolator.interpolate( xval1, yval, zval );
72              fail( "Failed to detect insufficient x data" );
73          } catch ( MathIllegalArgumentException iae ) {
74              // Expected.
75          }
76  
77          try  {
78              double[] yval1 = { 0.0, 1.0, 2.0, 3.0 };
79              interpolator.interpolate( xval, yval1, zval );
80              fail( "Failed to detect insufficient y data" );
81          } catch ( MathIllegalArgumentException iae ) {
82              // Expected.
83          }
84  
85          try {
86              double[][] zval1 = new double[4][4];
87              interpolator.interpolate( xval, yval, zval1 );
88              fail( "Failed to detect insufficient z data" );
89          } catch ( MathIllegalArgumentException iae ) {
90              // Expected.
91          }
92  
93          try {
94              double[] xval1 = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
95              interpolator.interpolate( xval1, yval, zval );
96              fail( "Failed to detect data set array with different sizes." );
97          } catch ( MathIllegalArgumentException iae ) {
98              // Expected.
99          }
100 
101         try {
102             double[] yval1 = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
103             interpolator.interpolate( xval, yval1, zval );
104             fail( "Failed to detect data set array with different sizes." );
105         } catch ( MathIllegalArgumentException iae ) {
106             // Expected.
107         }
108 
109         // X values not sorted.
110         try {
111             double[] xval1 = { 0.0, 1.0, 0.5, 7.0, 3.5 };
112             interpolator.interpolate( xval1, yval, zval );
113             fail( "Failed to detect unsorted x arguments." );
114         } catch ( MathIllegalArgumentException iae ) {
115             // Expected.
116         }
117 
118         // Y values not sorted.
119         try {
120             double[] yval1 = { 0.0, 1.0, 1.5, 0.0, 3.0 };
121             interpolator.interpolate( xval, yval1, zval );
122             fail( "Failed to detect unsorted y arguments." );
123         } catch ( MathIllegalArgumentException iae ) {
124             // Expected.
125         }
126     }
127 
128     /**
129      * Interpolating a plane.
130      * <p>
131      * z = 2 x - 3 y + 5
132      */
133     @Test
134     void testInterpolation1() {
135         final int sz = 21;
136         double[] xval = new double[sz];
137         double[] yval = new double[sz];
138         // Coordinate values
139         final double delta = 1d / (sz - 1);
140         for ( int i = 0; i < sz; i++ ){
141             xval[i] = -1 + 15 * i * delta;
142             yval[i] = -20 + 30 * i * delta;
143         }
144 
145         // Function values
146         BivariateFunction f = new BivariateFunction() {
147                 @Override
148                 public double value( double x, double y ) {
149                     return 2 * x - 3 * y + 5;
150                 }
151             };
152         double[][] zval = new double[xval.length][yval.length];
153         for ( int i = 0; i < xval.length; i++ ) {
154             for ( int j = 0; j < yval.length; j++ ) {
155                 zval[i][j] = f.value(xval[i], yval[j]);
156             }
157         }
158 
159         BivariateGridInterpolator interpolator = new PiecewiseBicubicSplineInterpolator();
160         BivariateFunction p = interpolator.interpolate(xval, yval, zval);
161         double x, y;
162 
163         final RandomDataGenerator gen = new RandomDataGenerator(1234567L);
164         final int numSamples = 50;
165         final double tol = 2e-14;
166         for ( int i = 0; i < numSamples; i++ ) {
167             x = gen.nextUniform(xval[0], xval[xval.length - 1]);
168             for ( int j = 0; j < numSamples; j++ ) {
169                 y = gen.nextUniform(yval[0], yval[yval.length - 1]);
170 //                 System.out.println(x + " " + y + " " + f.value(x, y) + " " + p.value(x, y));
171                 assertEquals(f.value(x, y),  p.value(x, y), tol);
172             }
173 //             System.out.println();
174         }
175     }
176 
177     /**
178      * Interpolating a paraboloid.
179      * <p>
180      * z = 2 x<sup>2</sup> - 3 y<sup>2</sup> + 4 x y - 5
181      */
182     @Test
183     void testInterpolation2() {
184         final int sz = 21;
185         double[] xval = new double[sz];
186         double[] yval = new double[sz];
187         // Coordinate values
188         final double delta = 1d / (sz - 1);
189         for ( int i = 0; i < sz; i++ ) {
190             xval[i] = -1 + 15 * i * delta;
191             yval[i] = -20 + 30 * i * delta;
192         }
193 
194         // Function values
195         BivariateFunction f = new BivariateFunction() {
196                 @Override
197                 public double value( double x, double y ) {
198                     return 2 * x * x - 3 * y * y + 4 * x * y - 5;
199                 }
200             };
201         double[][] zval = new double[xval.length][yval.length];
202         for ( int i = 0; i < xval.length; i++ ) {
203             for ( int j = 0; j < yval.length; j++ ) {
204                 zval[i][j] = f.value(xval[i], yval[j]);
205             }
206         }
207 
208         BivariateGridInterpolator interpolator = new PiecewiseBicubicSplineInterpolator();
209         BivariateFunction p = interpolator.interpolate(xval, yval, zval);
210         double x, y;
211 
212         final RandomDataGenerator gen = new RandomDataGenerator(1234567L);
213         final int numSamples = 50;
214         final double tol = 5e-13;
215         for ( int i = 0; i < numSamples; i++ ) {
216             x = gen.nextUniform(xval[0], xval[xval.length - 1]);
217             for ( int j = 0; j < numSamples; j++ ) {
218                 y = gen.nextUniform(yval[0], yval[yval.length - 1]);
219 //                 System.out.println(x + " " + y + " " + f.value(x, y) + " " + p.value(x, y));
220                 assertEquals(f.value(x, y),  p.value(x, y), tol);
221             }
222 //             System.out.println();
223         }
224     }
225 }