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.exception.LocalizedCoreFormats;
25 import org.hipparchus.exception.MathIllegalArgumentException;
26 import org.hipparchus.exception.MathIllegalStateException;
27 import org.hipparchus.util.Binary64;
28 import org.junit.jupiter.api.Test;
29
30 import java.util.Arrays;
31
32 import static org.junit.jupiter.api.Assertions.assertEquals;
33 import static org.junit.jupiter.api.Assertions.assertFalse;
34 import static org.junit.jupiter.api.Assertions.assertTrue;
35 import static org.junit.jupiter.api.Assertions.fail;
36
37
38
39
40
41 class PolynomialSplineFunctionTest {
42
43
44 protected double tolerance = 1.0e-12;
45
46
47
48
49
50
51
52
53
54
55
56 protected PolynomialFunction[] polynomials = {
57 new PolynomialFunction(new double[] {0d, 1d, 1d}),
58 new PolynomialFunction(new double[] {2d, 1d, 1d}),
59 new PolynomialFunction(new double[] {4d, 1d, 1d})
60 };
61
62
63 protected double[] knots = {-1, 0, 1, 2};
64
65
66 protected PolynomialFunction dp =
67 new PolynomialFunction(new double[] {1d, 2d});
68
69
70 @Test
71 void testConstructor() {
72 PolynomialSplineFunction spline =
73 new PolynomialSplineFunction(knots, polynomials);
74 assertTrue(Arrays.equals(knots, spline.getKnots()));
75 assertEquals(1d, spline.getPolynomials()[0].getCoefficients()[2], 0);
76 assertEquals(3, spline.getN());
77
78 try {
79 new PolynomialSplineFunction(new double[] {0}, polynomials);
80 fail("Expecting MathIllegalArgumentException");
81 } catch (MathIllegalArgumentException ex) {
82
83 }
84
85 try {
86 new PolynomialSplineFunction(new double[] {0,1,2,3,4}, polynomials);
87 fail("Expecting MathIllegalArgumentException");
88 } catch (MathIllegalArgumentException ex) {
89
90 }
91
92 try {
93 new PolynomialSplineFunction(new double[] {0,1, 3, 2}, polynomials);
94 fail("Expecting MathIllegalArgumentException");
95 } catch (MathIllegalArgumentException ex) {
96
97 }
98 }
99
100 @Test
101 void testValues() {
102 PolynomialSplineFunction spline =
103 new PolynomialSplineFunction(knots, polynomials);
104 PolynomialSplineFunction dSpline = spline.polynomialSplineDerivative();
105
106
107
108
109
110
111 double x = -1;
112 int index = 0;
113 for (int i = 0; i < 10; i++) {
114 x+=0.25;
115 index = findKnot(knots, x);
116 assertEquals(polynomials[index].value(x - knots[index]), spline.value(x), tolerance, "spline function evaluation failed for x=" + x);
117 assertEquals(dp.value(x - knots[index]), dSpline.value(x), tolerance, "spline derivative evaluation failed for x=" + x);
118 }
119
120
121 for (int i = 0; i < 3; i++) {
122 assertEquals(polynomials[i].value(0), spline.value(knots[i]), tolerance, "spline function evaluation failed for knot=" + knots[i]);
123 assertEquals(dp.value(0), dSpline.value(new Binary64(knots[i])).getReal(), tolerance, "spline function evaluation failed for knot=" + knots[i]);
124 }
125
126 try {
127 x = spline.value(-1.5);
128 fail("Expecting MathIllegalArgumentException");
129 } catch (MathIllegalArgumentException ex) {
130
131 }
132
133 try {
134 x = spline.value(2.5);
135 fail("Expecting MathIllegalArgumentException");
136 } catch (MathIllegalArgumentException ex) {
137
138 }
139 }
140
141 @Test
142 void testIsValidPoint() {
143 final PolynomialSplineFunction spline =
144 new PolynomialSplineFunction(knots, polynomials);
145 final double xMin = knots[0];
146 final double xMax = knots[knots.length - 1];
147
148 double x;
149
150 x = xMin;
151 assertTrue(spline.isValidPoint(x));
152
153 spline.value(x);
154
155 x = xMax;
156 assertTrue(spline.isValidPoint(x));
157
158 spline.value(x);
159
160 final double xRange = xMax - xMin;
161 x = xMin + xRange / 3.4;
162 assertTrue(spline.isValidPoint(x));
163
164 spline.value(x);
165
166 final double small = 1e-8;
167 x = xMin - small;
168 assertFalse(spline.isValidPoint(x));
169
170 try {
171 spline.value(x);
172 fail("MathIllegalArgumentException expected");
173 } catch (MathIllegalArgumentException expected) {}
174 }
175
176
177
178
179
180 protected int findKnot(double[] knots, double x) {
181 if (x < knots[0] || x >= knots[knots.length -1]) {
182 throw new MathIllegalArgumentException(LocalizedCoreFormats.OUT_OF_RANGE_SIMPLE,
183 x, knots[0], knots[knots.length -1]);
184 }
185 for (int i = 0; i < knots.length; i++) {
186 if (knots[i] > x) {
187 return i - 1;
188 }
189 }
190 throw new MathIllegalStateException(LocalizedCoreFormats.ILLEGAL_STATE);
191 }
192 }
193