View Javadoc
1   /*
2    * Licensed to the Hipparchus project 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 Hipparchus project 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  package org.hipparchus.analysis.interpolation;
18  
19  import org.hipparchus.analysis.CalculusFieldBivariateFunction;
20  import org.hipparchus.analysis.differentiation.UnivariateDerivative1;
21  import org.hipparchus.random.RandomVectorGenerator;
22  import org.hipparchus.random.SobolSequenceGenerator;
23  import org.hipparchus.util.FastMath;
24  import org.junit.jupiter.api.Test;
25  
26  import static org.junit.jupiter.api.Assertions.assertEquals;
27  
28  /**
29   * Test case for the field bilinear function.
30   */
31  final class FieldBilinearInterpolatingFunctionTest {
32  
33      @Test
34      void testConstant() {
35  
36          double xMin = 0.0;
37          double xMax = 7.0;
38          int    nx   = 15;
39          UnivariateDerivative1[] xVal = createLinearGrid(xMin, xMax, nx, 1.0);
40  
41          double yMin = -5.0;
42          double yMax =  5.0;
43          int    ny   = 11;
44          UnivariateDerivative1[] yVal = createLinearGrid(yMin, yMax, ny, 2.0);
45  
46          CalculusFieldBivariateFunction<UnivariateDerivative1>     f  = (x, y) -> new UnivariateDerivative1(3.5, 1.0);
47          FieldBilinearInterpolatingFunction<UnivariateDerivative1> bif = createInterpolatingFunction(xVal, yVal, f);
48  
49          assertEquals(xMin, bif.getXInf().getValue(),           1.0e-15);
50          assertEquals(1.0,  bif.getXInf().getFirstDerivative(), 1.0e-15);
51          assertEquals(xMax, bif.getXSup().getValue(),           1.0e-15);
52          assertEquals(1.0,  bif.getXSup().getFirstDerivative(), 1.0e-15);
53          assertEquals(yMin, bif.getYInf().getValue(),           1.0e-15);
54          assertEquals(2.0,  bif.getYInf().getFirstDerivative(), 1.0e-15);
55          assertEquals(yMax, bif.getYSup().getValue(),           1.0e-15);
56          assertEquals(2.0,  bif.getYSup().getFirstDerivative(), 1.0e-15);
57  
58          checkInterpolationAtNodes(xVal, yVal, bif, f, 1.0e-15, 1.0e-15);
59          checkInterpolationRandom(new SobolSequenceGenerator(2), xMin, xMax, yMin, yMax, bif, f, 1.0e-15, 1.0e-15);
60  
61      }
62  
63      @Test
64      void testLinear() {
65  
66          double xMin = -5.0;
67          double xMax =  5.0;
68          int    nx   = 11;
69          UnivariateDerivative1[] xVal = createLinearGrid(xMin, xMax, nx, 1.0);
70  
71          double yMin = 0.0;
72          double yMax = 7.0;
73          int    ny   = 15;
74          UnivariateDerivative1[] yVal = createLinearGrid(yMin, yMax, ny, 2.0);
75  
76          CalculusFieldBivariateFunction<UnivariateDerivative1> f = (x, y) -> x.multiply(2).subtract(y);
77          FieldBilinearInterpolatingFunction<UnivariateDerivative1> bif = createInterpolatingFunction(xVal, yVal, f);
78  
79          assertEquals(xMin, bif.getXInf().getValue(),           1.0e-15);
80          assertEquals(1.0,  bif.getXInf().getFirstDerivative(), 1.0e-15);
81          assertEquals(xMax, bif.getXSup().getValue(),           1.0e-15);
82          assertEquals(1.0,  bif.getXSup().getFirstDerivative(), 1.0e-15);
83          assertEquals(yMin, bif.getYInf().getValue(),           1.0e-15);
84          assertEquals(2.0,  bif.getYInf().getFirstDerivative(), 1.0e-15);
85          assertEquals(yMax, bif.getYSup().getValue(),           1.0e-15);
86          assertEquals(2.0,  bif.getYSup().getFirstDerivative(), 1.0e-15);
87  
88          checkInterpolationAtNodes(xVal, yVal, bif, f, 1.0e-15, 1.0e-15);
89          checkInterpolationRandom(new SobolSequenceGenerator(2), xMin, xMax, yMin, yMax, bif, f, 1.0e-15, 1.0e-15);
90  
91      }
92  
93      @Test
94      void testQuadratic() {
95  
96          double xMin = -5.0;
97          double xMax =  5.0;
98          int    nx   = 11;
99          UnivariateDerivative1[] xVal = createLinearGrid(xMin, xMax, nx, 1.0);
100 
101         double yMin = 0.0;
102         double yMax = 7.0;
103         int    ny   = 15;
104         UnivariateDerivative1[] yVal = createLinearGrid(yMin, yMax, ny, 2.0);
105 
106         CalculusFieldBivariateFunction<UnivariateDerivative1> f = (x, y) -> x.multiply(3).subtract(2).multiply(y.multiply(-0.5).add(6));
107         FieldBilinearInterpolatingFunction<UnivariateDerivative1> bif = createInterpolatingFunction(xVal, yVal, f);
108 
109         assertEquals(xMin, bif.getXInf().getValue(),           1.0e-15);
110         assertEquals(1.0,  bif.getXInf().getFirstDerivative(), 1.0e-15);
111         assertEquals(xMax, bif.getXSup().getValue(),           1.0e-15);
112         assertEquals(1.0,  bif.getXSup().getFirstDerivative(), 1.0e-15);
113         assertEquals(yMin, bif.getYInf().getValue(),           1.0e-15);
114         assertEquals(2.0,  bif.getYInf().getFirstDerivative(), 1.0e-15);
115         assertEquals(yMax, bif.getYSup().getValue(),           1.0e-15);
116         assertEquals(2.0,  bif.getYSup().getFirstDerivative(), 1.0e-15);
117 
118         checkInterpolationAtNodes(xVal, yVal, bif, f, 1.0e-15, 1.0e-15);
119         checkInterpolationRandom(new SobolSequenceGenerator(2), xMin, xMax, yMin, yMax, bif, f, 1.0e-15, 1.0e-15);
120 
121     }
122 
123     @Test
124     void testSinCos() {
125         doTestSinCos(  10,   10, 1.8e-2, 8.3e-2);
126         doTestSinCos( 100,  100, 1.5e-4, 7.6e-3);
127         doTestSinCos(1000, 1000, 1.4e-6, 7.6e-4);
128     }
129 
130     private void doTestSinCos(final int nx, final int ny, final double tol0, final double tol1) {
131         double xMin = -1.0;
132         double xMax =  2.0;
133         UnivariateDerivative1[] xVal = createLinearGrid(xMin, xMax, nx, 1.0);
134 
135         double yMin = 0.0;
136         double yMax = 1.5;
137         UnivariateDerivative1[] yVal = createLinearGrid(yMin, yMax, ny, 2.0);
138 
139         CalculusFieldBivariateFunction<UnivariateDerivative1> f = (x, y) -> FastMath.sin(x).multiply(FastMath.cos(y));
140         FieldBilinearInterpolatingFunction<UnivariateDerivative1> bif = createInterpolatingFunction(xVal, yVal, f);
141 
142         assertEquals(xMin, bif.getXInf().getValue(),           1.0e-15);
143         assertEquals(1.0,  bif.getXInf().getFirstDerivative(), 1.0e-15);
144         assertEquals(xMax, bif.getXSup().getValue(),           1.0e-15);
145         assertEquals(1.0,  bif.getXSup().getFirstDerivative(), 1.0e-15);
146         assertEquals(yMin, bif.getYInf().getValue(),           1.0e-15);
147         assertEquals(2.0,  bif.getYInf().getFirstDerivative(), 1.0e-15);
148         assertEquals(yMax, bif.getYSup().getValue(),           1.0e-15);
149         assertEquals(2.0,  bif.getYSup().getFirstDerivative(), 1.0e-15);
150 
151         checkInterpolationAtNodes(xVal, yVal, bif, f, 1.0e-15, 1.0e-15);
152         checkInterpolationRandom(new SobolSequenceGenerator(2), xMin, xMax, yMin, yMax, bif, f, tol0, tol1);
153 
154     }
155 
156     private UnivariateDerivative1[] createLinearGrid(final double min, final double max, final int n,
157                                                      final double derivative) {
158         final UnivariateDerivative1[] grid = new UnivariateDerivative1[n];
159         for (int i = 0; i < n; ++i) {
160             grid[i] = new UnivariateDerivative1(((n - 1 - i) * min + i * max) / (n - 1), derivative);
161         }
162         return grid;
163     }
164 
165     private FieldBilinearInterpolatingFunction<UnivariateDerivative1>
166     createInterpolatingFunction(UnivariateDerivative1[] xVal, UnivariateDerivative1[] yVal,
167                                 CalculusFieldBivariateFunction<UnivariateDerivative1> f) {
168         final UnivariateDerivative1[][] fVal = new UnivariateDerivative1[xVal.length][yVal.length];
169         for (int i = 0; i < xVal.length; ++i) {
170             for (int j = 0; j < yVal.length; ++j) {
171                 fVal[i][j] = f.value(xVal[i], yVal[j]);
172             }
173         }
174         return new FieldBilinearInterpolator<UnivariateDerivative1>().interpolate(xVal, yVal, fVal);
175     }
176 
177     private void checkInterpolationAtNodes(final UnivariateDerivative1[] xVal,
178                                            final UnivariateDerivative1[] yVal,
179                                            final FieldBilinearInterpolatingFunction<UnivariateDerivative1> bif,
180                                            final CalculusFieldBivariateFunction<UnivariateDerivative1> f,
181                                            final double tol0, final double tol1) {
182         for (final UnivariateDerivative1 x : xVal) {
183             for (final UnivariateDerivative1 y : yVal) {
184                 assertEquals(f.value(x, y).getValue(), bif.value(x, y).getValue(), tol0);
185                 assertEquals(f.value(x, y).getFirstDerivative(), bif.value(x, y).getFirstDerivative(), tol1);
186             }
187         }
188     }
189 
190     private void checkInterpolationRandom(final RandomVectorGenerator random,
191                                           final double xMin, final double xMax,
192                                           final double yMin, final double yMax,
193                                           final FieldBilinearInterpolatingFunction<UnivariateDerivative1> bif,
194                                           final CalculusFieldBivariateFunction<UnivariateDerivative1> f,
195                                           final double tol0, final double tol1) {
196         double maxError0 = 0.0;
197         double maxError1 = 0.0;
198         for (int i = 0; i < 10000; ++i) {
199 
200             final double[] v = random.nextVector();
201 
202             final UnivariateDerivative1 x = new UnivariateDerivative1(xMin + v[0] * (xMax - xMin), 1.0);
203             final UnivariateDerivative1 y = new UnivariateDerivative1(yMin + v[1] * (yMax - yMin), 1.0);
204             final UnivariateDerivative1 delta = f.value(x, y).subtract(bif.value(x, y));
205             maxError0 = FastMath.max(maxError0, FastMath.abs(delta.getValue()));
206             maxError1 = FastMath.max(maxError1, FastMath.abs(delta.getFirstDerivative()));
207 
208         }
209 
210         assertEquals(0.0, maxError0, tol0);
211         assertEquals(0.0, maxError1, tol1);
212 
213     }
214 
215 }