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