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 java.io.Serializable;
20
21 import org.hipparchus.CalculusFieldElement;
22 import org.hipparchus.analysis.BivariateFunction;
23 import org.hipparchus.analysis.FieldBivariateFunction;
24 import org.hipparchus.exception.MathIllegalArgumentException;
25
26
27
28
29
30
31
32
33 public class BilinearInterpolatingFunction implements BivariateFunction, FieldBivariateFunction, Serializable {
34
35
36 private static final long serialVersionUID = 20180926L;
37
38
39 private final GridAxis xGrid;
40
41
42 private final GridAxis yGrid;
43
44
45 private final int ySize;
46
47
48 private final double[] fVal;
49
50
51
52
53
54
55
56
57
58
59
60 public BilinearInterpolatingFunction(final double[] xVal, final double[] yVal,
61 final double[][] fVal)
62 throws MathIllegalArgumentException {
63 this.xGrid = new GridAxis(xVal, 2);
64 this.yGrid = new GridAxis(yVal, 2);
65 this.ySize = yVal.length;
66 this.fVal = new double[xVal.length * ySize];
67 int k = 0;
68 for (int i = 0; i < xVal.length; ++i) {
69 final double[] fi = fVal[i];
70 for (int j = 0; j < ySize; ++j) {
71 this.fVal[k++] = fi[j];
72 }
73 }
74 }
75
76
77
78
79 public double getXInf() {
80 return xGrid.node(0);
81 }
82
83
84
85
86 public double getXSup() {
87 return xGrid.node(xGrid.size() - 1);
88 }
89
90
91
92
93 public double getYInf() {
94 return yGrid.node(0);
95 }
96
97
98
99
100 public double getYSup() {
101 return yGrid.node(yGrid.size() - 1);
102 }
103
104
105 @Override
106 public double value(final double x, final double y) {
107
108
109 final int i = xGrid.interpolationIndex(x);
110 final int j = yGrid.interpolationIndex(y);
111 final double x0 = xGrid.node(i);
112 final double x1 = xGrid.node(i + 1);
113 final double y0 = yGrid.node(j);
114 final double y1 = yGrid.node(j + 1);
115
116
117 final int k0 = i * ySize + j;
118 final int k1 = k0 + ySize;
119 final double z00 = fVal[k0];
120 final double z01 = fVal[k0 + 1];
121 final double z10 = fVal[k1];
122 final double z11 = fVal[k1 + 1];
123
124
125 final double dx0 = x - x0;
126 final double dx1 = x1 - x;
127 final double dx10 = x1 - x0;
128 final double dy0 = y - y0;
129 final double dy1 = y1 - y;
130 final double dy10 = y1 - y0;
131 return (dx0 * (dy0 * z11 + dy1 * z10) + dx1 * (dy0 * z01 + dy1 * z00)) /
132 (dx10 * dy10);
133
134 }
135
136
137
138
139 @Override
140 public <T extends CalculusFieldElement<T>> T value(T x, T y) {
141
142
143 final int i = xGrid.interpolationIndex(x.getReal());
144 final int j = yGrid.interpolationIndex(y.getReal());
145 final double x0 = xGrid.node(i);
146 final double x1 = xGrid.node(i + 1);
147 final double y0 = yGrid.node(j);
148 final double y1 = yGrid.node(j + 1);
149
150
151 final int k0 = i * ySize + j;
152 final int k1 = k0 + ySize;
153 final double z00 = fVal[k0];
154 final double z01 = fVal[k0 + 1];
155 final double z10 = fVal[k1];
156 final double z11 = fVal[k1 + 1];
157
158
159 final T dx0 = x.subtract(x0);
160 final T mdx1 = x.subtract(x1);
161 final double dx10 = x1 - x0;
162 final T dy0 = y.subtract(y0);
163 final T mdy1 = y.subtract(y1);
164 final double dy10 = y1 - y0;
165 return dy0.multiply(z11).subtract(mdy1.multiply(z10)).multiply(dx0).
166 subtract(dy0.multiply(z01).subtract(mdy1.multiply(z00)).multiply(mdx1)).
167 divide(dx10 * dy10);
168
169 }
170
171 }