1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.analysis.polynomials;
23
24 import org.hipparchus.analysis.differentiation.Gradient;
25 import org.hipparchus.analysis.differentiation.GradientField;
26 import org.hipparchus.analysis.interpolation.LinearInterpolator;
27 import org.hipparchus.exception.LocalizedCoreFormats;
28 import org.hipparchus.exception.MathIllegalArgumentException;
29 import org.hipparchus.exception.MathIllegalStateException;
30 import org.hipparchus.util.Binary64;
31 import org.junit.jupiter.api.BeforeEach;
32 import org.junit.jupiter.api.Test;
33
34 import java.lang.reflect.Array;
35 import java.util.Arrays;
36
37 import static org.junit.jupiter.api.Assertions.assertEquals;
38 import static org.junit.jupiter.api.Assertions.assertFalse;
39 import static org.junit.jupiter.api.Assertions.assertTrue;
40 import static org.junit.jupiter.api.Assertions.fail;
41
42
43
44
45
46 class FieldPolynomialSplineFunctionTest {
47
48
49 private double tolerance;
50
51
52
53
54
55
56
57
58
59
60
61 private FieldPolynomialFunction<Binary64>[] polynomials;
62
63
64 private Binary64[] knots;
65
66
67 protected PolynomialFunction dp =
68 new PolynomialFunction(new double[] {1d, 2d});
69
70
71 @Test
72 void testConstructor() {
73 FieldPolynomialSplineFunction<Binary64> spline =
74 new FieldPolynomialSplineFunction<>(knots, polynomials);
75 assertTrue(Arrays.equals(knots, spline.getKnots()));
76 assertEquals(1d, spline.getPolynomials()[0].getCoefficients()[2].getReal(), 0);
77 assertEquals(3, spline.getN());
78
79 try {
80 new FieldPolynomialSplineFunction<>(new Binary64[] { new Binary64(0) }, polynomials);
81 fail("Expecting MathIllegalArgumentException");
82 } catch (MathIllegalArgumentException ex) {
83
84 }
85
86 try {
87 new FieldPolynomialSplineFunction<>(new Binary64[] {
88 new Binary64(0), new Binary64(1), new Binary64(2),
89 new Binary64(3), new Binary64(4)
90 }, polynomials);
91 fail("Expecting MathIllegalArgumentException");
92 } catch (MathIllegalArgumentException ex) {
93
94 }
95
96 try {
97 new FieldPolynomialSplineFunction<>(new Binary64[] {
98 new Binary64(0), new Binary64(1), new Binary64(3), new Binary64(2)
99 }, polynomials);
100 fail("Expecting MathIllegalArgumentException");
101 } catch (MathIllegalArgumentException ex) {
102
103 }
104 }
105
106 @Test
107 void testValues() {
108 FieldPolynomialSplineFunction<Binary64> spline =
109 new FieldPolynomialSplineFunction<>(knots, polynomials);
110 FieldPolynomialSplineFunction<Binary64> dSpline = spline.polynomialSplineDerivative();
111
112
113
114
115
116
117 double x = -1;
118 int index = 0;
119 for (int i = 0; i < 10; i++) {
120 x += 0.25;
121 index = findKnot(knots, x);
122 assertEquals(polynomials[index].value(new Binary64(x).subtract(knots[index])).getReal(),
123 spline.value(x).getReal(),
124 tolerance,
125 "spline function evaluation failed for x=" + x);
126 assertEquals(dp.value(new Binary64(x).subtract(knots[index])).getReal(),
127 dSpline.value(x).getReal(),
128 tolerance,
129 "spline derivative evaluation failed for x=" + x);
130 }
131
132
133 for (int i = 0; i < 3; i++) {
134 assertEquals(polynomials[i].value(0).getReal(),
135 spline.value(knots[i]).getReal(),
136 tolerance,
137 "spline function evaluation failed for knot=" + knots[i].getReal());
138 assertEquals(dp.value(0),
139 dSpline.value(knots[i]).getReal(),
140 tolerance,
141 "spline function evaluation failed for knot=" + knots[i]);
142 }
143
144 try {
145 spline.value(-1.5);
146 fail("Expecting MathIllegalArgumentException");
147 } catch (MathIllegalArgumentException ex) {
148
149 }
150
151 try {
152 spline.value(2.5);
153 fail("Expecting MathIllegalArgumentException");
154 } catch (MathIllegalArgumentException ex) {
155
156 }
157 }
158
159 @Test
160 void testIsValidPoint() {
161 final FieldPolynomialSplineFunction<Binary64> spline =
162 new FieldPolynomialSplineFunction<>(knots, polynomials);
163 final Binary64 xMin = knots[0];
164 final Binary64 xMax = knots[knots.length - 1];
165
166 Binary64 x;
167
168 x = xMin;
169 assertTrue(spline.isValidPoint(x));
170
171 spline.value(x);
172
173 x = xMax;
174 assertTrue(spline.isValidPoint(x));
175
176 spline.value(x);
177
178 final Binary64 xRange = xMax.subtract(xMin);
179 x = xMin.add(xRange.divide(3.4));
180 assertTrue(spline.isValidPoint(x));
181
182 spline.value(x);
183
184 final Binary64 small = new Binary64(1e-8);
185 x = xMin.subtract(small);
186 assertFalse(spline.isValidPoint(x));
187
188 try {
189 spline.value(x);
190 fail("MathIllegalArgumentException expected");
191 } catch (MathIllegalArgumentException expected) {}
192 }
193
194
195
196
197
198 protected int findKnot(Binary64[] knots, double x) {
199 if (x < knots[0].getReal() || x >= knots[knots.length -1].getReal()) {
200 throw new MathIllegalArgumentException(LocalizedCoreFormats.OUT_OF_RANGE_SIMPLE,
201 x, knots[0], knots[knots.length -1]);
202 }
203 for (int i = 0; i < knots.length; i++) {
204 if (knots[i].getReal() > x) {
205 return i - 1;
206 }
207 }
208 throw new MathIllegalStateException(LocalizedCoreFormats.ILLEGAL_STATE);
209 }
210
211 private FieldPolynomialFunction<Binary64> buildD64(double...c) {
212 Binary64[] array = new Binary64[c.length];
213 for (int i = 0; i < c.length; ++i) {
214 array[i] = new Binary64(c[i]);
215 }
216 return new FieldPolynomialFunction<>(array);
217 }
218
219 @BeforeEach
220 @SuppressWarnings("unchecked")
221 void setUp() {
222 tolerance = 1.0e-12;
223 polynomials = (FieldPolynomialFunction<Binary64>[]) Array.newInstance(FieldPolynomialFunction.class, 3);
224 polynomials[0] = buildD64(0, 1, 1);
225 polynomials[1] = buildD64(2, 1, 1);
226 polynomials[2] = buildD64(4, 1, 1);
227 knots = new Binary64[] {
228 new Binary64(-1), new Binary64(0), new Binary64(1), new Binary64(2)
229 };
230 }
231
232 @Test
233 void testValueGradient() {
234
235
236 final int freeParameters = 1;
237 final GradientField field = GradientField.getField(freeParameters);
238 final Gradient zero = field.getZero();
239 final Gradient time1 = zero.add(1.0);
240 final Gradient time2 = zero.add(2.0);
241 final Gradient time3 = zero.add(4.0);
242 final Gradient x1 = zero.add(4.0);
243 final Gradient x2 = Gradient.variable(freeParameters, 0, -2.0);
244 final Gradient x3 = zero.add(0.0);
245 final Gradient[] times = new Gradient[] {time1, time2, time3};
246 final Gradient[] xs = new Gradient[] {x1, x2, x3};
247
248 final FieldPolynomialSplineFunction<Gradient> spline = new LinearInterpolator().interpolate(times, xs);
249 final Gradient actualEvaluation = spline.value(zero.add(3.));
250
251 final Gradient expectedEvaluation = Gradient.variable(freeParameters, 0, 0).multiply(0.5).add(-1.0);
252 assertEquals(expectedEvaluation, actualEvaluation);
253 }
254
255 }
256