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