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.CalculusFieldElement;
25 import org.hipparchus.analysis.differentiation.DSFactory;
26 import org.hipparchus.analysis.differentiation.DerivativeStructure;
27 import org.hipparchus.analysis.differentiation.Gradient;
28 import org.hipparchus.analysis.differentiation.UnivariateDerivative1;
29 import org.hipparchus.analysis.differentiation.UnivariateDerivative2;
30 import org.hipparchus.complex.Complex;
31 import org.hipparchus.exception.MathIllegalArgumentException;
32 import org.hipparchus.random.RandomDataGenerator;
33 import org.hipparchus.util.Binary64;
34 import org.hipparchus.util.FastMath;
35 import org.junit.jupiter.api.Test;
36
37 import static org.junit.jupiter.api.Assertions.assertEquals;
38 import static org.junit.jupiter.api.Assertions.assertThrows;
39
40
41
42
43
44 final class FieldPolynomialFunctionTest {
45
46 protected double tolerance = 1e-12;
47
48
49
50
51
52
53 @Test
54 void testConstants() {
55 double c0 = 2.5;
56 FieldPolynomialFunction<Binary64> f = buildD64(c0);
57
58
59 assertEquals(c0, f.value(0).getReal(), tolerance);
60 assertEquals(c0, f.value(-1).getReal(), tolerance);
61 assertEquals(c0, f.value(-123.5).getReal(), tolerance);
62 assertEquals(c0, f.value(3).getReal(), tolerance);
63 assertEquals(c0, f.value(new Binary64(456.89)).getReal(), tolerance);
64
65 assertEquals(0, f.degree());
66 assertEquals(0, f.polynomialDerivative().value(0).getReal(), tolerance);
67
68 assertEquals(0, f.polynomialDerivative().polynomialDerivative().value(0).getReal(), tolerance);
69 }
70
71
72
73
74
75
76
77
78
79
80 @Test
81 void testLinear() {
82 FieldPolynomialFunction<Binary64> f = buildD64(-1.5, 3);
83
84
85 assertEquals(-1.5, f.value(new Binary64(0)).getReal(), tolerance);
86
87
88 assertEquals(-4.5, f.value(new Binary64(-1)).getReal(), tolerance);
89 assertEquals(-9, f.value(new Binary64(-2.5)).getReal(), tolerance);
90 assertEquals(0, f.value(new Binary64(0.5)).getReal(), tolerance);
91 assertEquals(3, f.value(new Binary64(1.5)).getReal(), tolerance);
92 assertEquals(7.5, f.value(new Binary64(3)).getReal(), tolerance);
93
94 assertEquals(1, f.degree());
95
96 assertEquals(0, f.polynomialDerivative().polynomialDerivative().value(0).getReal(), tolerance);
97 }
98
99
100
101
102
103 @Test
104 void testQuadratic() {
105 FieldPolynomialFunction<Binary64> f = buildD64(-2, -3, 2);
106
107
108 assertEquals(-2, f.value(0).getReal(), tolerance);
109
110
111 assertEquals(0, f.value(-0.5).getReal(), tolerance);
112 assertEquals(0, f.value(2).getReal(), tolerance);
113 assertEquals(-2, f.value(1.5).getReal(), tolerance);
114 assertEquals(7, f.value(-1.5).getReal(), tolerance);
115 assertEquals(265.5312, f.value(12.34).getReal(), tolerance);
116 }
117
118
119
120
121
122 @Test
123 void testQuintic() {
124 FieldPolynomialFunction<Binary64> f = buildD64(0, 0, 15, -13, -3, 1);
125
126
127 assertEquals(0, f.value(0).getReal(), tolerance);
128
129
130 assertEquals(0, f.value(5).getReal(), tolerance);
131 assertEquals(0, f.value(1).getReal(), tolerance);
132 assertEquals(0, f.value(-3).getReal(), tolerance);
133 assertEquals(54.84375, f.value(-1.5).getReal(), tolerance);
134 assertEquals(-8.06637, f.value(1.3).getReal(), tolerance);
135
136 assertEquals(5, f.degree());
137 }
138
139
140
141
142
143
144
145
146 @Test
147 void testfirstDerivativeComparison() {
148 double[] f_coeff = { 3, 6, -2, 1 };
149 double[] g_coeff = { 6, -4, 3 };
150 double[] h_coeff = { -4, 6 };
151
152 FieldPolynomialFunction<Binary64> f = buildD64(f_coeff);
153 FieldPolynomialFunction<Binary64> g = buildD64(g_coeff);
154 FieldPolynomialFunction<Binary64> h = buildD64(h_coeff);
155
156
157 assertEquals(f.polynomialDerivative().value(0).getReal(), g.value(0).getReal(), tolerance);
158 assertEquals(f.polynomialDerivative().value(1).getReal(), g.value(1).getReal(), tolerance);
159 assertEquals(f.polynomialDerivative().value(100).getReal(), g.value(100).getReal(), tolerance);
160 assertEquals(f.polynomialDerivative().value(4.1).getReal(), g.value(4.1).getReal(), tolerance);
161 assertEquals(f.polynomialDerivative().value(-3.25).getReal(), g.value(-3.25).getReal(), tolerance);
162
163
164 assertEquals(g.polynomialDerivative().value(FastMath.PI).getReal(), h.value(FastMath.PI).getReal(), tolerance);
165 assertEquals(g.polynomialDerivative().value(FastMath.E).getReal(), h.value(FastMath.E).getReal(), tolerance);
166 }
167
168 @Test
169 void testAddition() {
170 FieldPolynomialFunction<Binary64> p1 = buildD64( -2, 1 );
171 FieldPolynomialFunction<Binary64> p2 = buildD64( 2, -1, 0 );
172 checkNullPolynomial(p1.add(p2));
173
174 p2 = p1.add(p1);
175 checkCoeffs(Double.MIN_VALUE, p2, -4, 2);
176
177 p1 = buildD64( 1, -4, 2 );
178 p2 = buildD64( -1, 3, -2 );
179 p1 = p1.add(p2);
180 assertEquals(1, p1.degree());
181 checkCoeffs(Double.MIN_VALUE, p1, 0, -1);
182 }
183
184 @Test
185 void testSubtraction() {
186 FieldPolynomialFunction<Binary64> p1 = buildD64( -2, 1 );
187 checkNullPolynomial(p1.subtract(p1));
188
189 FieldPolynomialFunction<Binary64> p2 = buildD64( -2, 6 );
190 p2 = p2.subtract(p1);
191 checkCoeffs(Double.MIN_VALUE, p2, 0, 5);
192
193 p1 = buildD64( 1, -4, 2 );
194 p2 = buildD64( -1, 3, 2 );
195 p1 = p1.subtract(p2);
196 assertEquals(1, p1.degree());
197 checkCoeffs(Double.MIN_VALUE, p1, 2, -7);
198 }
199
200 @Test
201 void testMultiplication() {
202 FieldPolynomialFunction<Binary64> p1 = buildD64( -3, 2 );
203 FieldPolynomialFunction<Binary64> p2 = buildD64( 3, 2, 1 );
204 checkCoeffs(Double.MIN_VALUE, p1.multiply(p2), -9, 0, 1, 2);
205
206 p1 = buildD64( 0, 1 );
207 p2 = p1;
208 for (int i = 2; i < 10; ++i) {
209 p2 = p2.multiply(p1);
210 double[] c = new double[i + 1];
211 c[i] = 1;
212 checkCoeffs(Double.MIN_VALUE, p2, c);
213 }
214 }
215
216
217
218
219
220
221
222
223 @Test
224 void testMath341() {
225 double[] f_coeff = { 3, 6, -2, 1 };
226 double[] g_coeff = { 6, -4, 3 };
227 double[] h_coeff = { -4, 6 };
228
229 FieldPolynomialFunction<Binary64> f = buildD64(f_coeff);
230 FieldPolynomialFunction<Binary64> g = buildD64(g_coeff);
231 FieldPolynomialFunction<Binary64> h = buildD64(h_coeff);
232
233
234 assertEquals(f.polynomialDerivative().value(0).getReal(), g.value(0).getReal(), tolerance);
235 assertEquals(f.polynomialDerivative().value(1).getReal(), g.value(1).getReal(), tolerance);
236 assertEquals(f.polynomialDerivative().value(100).getReal(), g.value(100).getReal(), tolerance);
237 assertEquals(f.polynomialDerivative().value(4.1).getReal(), g.value(4.1).getReal(), tolerance);
238 assertEquals(f.polynomialDerivative().value(-3.25).getReal(), g.value(-3.25).getReal(), tolerance);
239
240
241 assertEquals(g.polynomialDerivative().value(FastMath.PI).getReal(), h.value(FastMath.PI).getReal(), tolerance);
242 assertEquals(g.polynomialDerivative().value(FastMath.E).getReal(), h.value(FastMath.E).getReal(), tolerance);
243 }
244
245 @Test
246 void testAntiDerivative() {
247
248 final double[] coeff = {1, 2, 3};
249 final FieldPolynomialFunction<Binary64> p = buildD64(coeff);
250
251 checkCoeffs(Double.MIN_VALUE, p.antiDerivative(), 0, 1, 1, 1);
252 }
253
254 @Test
255 void testAntiDerivativeConstant() {
256 final double[] coeff = {2};
257 final FieldPolynomialFunction<Binary64> p = buildD64(coeff);
258 checkCoeffs(Double.MIN_VALUE, p.antiDerivative(), 0, 2);
259 }
260
261 @Test
262 void testAntiDerivativeZero() {
263 final double[] coeff = {0};
264 final FieldPolynomialFunction<Binary64> p = buildD64(coeff);
265 checkCoeffs(Double.MIN_VALUE, p.antiDerivative(), 0);
266 }
267
268 @Test
269 void testAntiDerivativeRandom() {
270 final RandomDataGenerator ran = new RandomDataGenerator(1000);
271 double[] coeff = null;
272 FieldPolynomialFunction<Binary64> p = null;
273 int d = 0;
274 for (int i = 0; i < 20; i++) {
275 d = ran.nextInt(1, 50);
276 coeff = new double[d];
277 for (int j = 0; j < d; j++) {
278 coeff[j] = ran.nextUniform(-100, 1000);
279 }
280 p = buildD64(coeff);
281 checkInverseDifferentiation(p);
282 }
283 }
284
285 @Test
286 void testIntegrate() {
287
288 final double[] coeff = {0, 0, -1};
289 final FieldPolynomialFunction<Binary64> p = buildD64(coeff);
290 assertEquals(-2d/3d, p.integrate(-1, 1).getReal(),Double.MIN_VALUE);
291
292
293 final FieldPolynomialFunction<Binary64> p2 = buildD64(0, 1).
294 multiply(buildD64(-1, 1)).
295 multiply(buildD64(1, 1));
296 assertEquals(0, p2.integrate(-1, 1).getReal(), Double.MIN_VALUE);
297 }
298
299 @Test
300 void testIntegrateInfiniteBounds() {
301 assertThrows(MathIllegalArgumentException.class, () -> {
302 final FieldPolynomialFunction<Binary64> p = buildD64(1);
303 p.integrate(0, Double.POSITIVE_INFINITY);
304 });
305 }
306
307 @Test
308 void testIntegrateBadInterval() {
309 assertThrows(MathIllegalArgumentException.class, () -> {
310 final FieldPolynomialFunction<Binary64> p = buildD64(1);
311 p.integrate(0, -1);
312 });
313 }
314
315 @Test
316 void testIssue259WithComplex() {
317 final double nonZeroParameterForQuadraticCoeff = -1.;
318 final Complex[] coefficients = buildImaginaryCoefficients(1., 2., nonZeroParameterForQuadraticCoeff);
319 templateIssue259DisappearingCoefficients(coefficients);
320 }
321
322 @Test
323 void testIssue259WithGradient() {
324 final double nonZeroParameterForQuadraticCoeff = -1.;
325 final Gradient[] coefficients = buildUnivariateGradientCoefficients(1.,2., nonZeroParameterForQuadraticCoeff);
326 templateIssue259DisappearingCoefficients(coefficients);
327 }
328
329 @Test
330 void testIssue259WithDerivativeStructure() {
331 final double nonZeroParameterForQuadraticCoeff = -1.;
332 final DerivativeStructure[] coefficients = buildUnivariateDSCoefficients(1.,2., nonZeroParameterForQuadraticCoeff);
333 templateIssue259DisappearingCoefficients(coefficients);
334 }
335
336 @Test
337 void testIssue259WithUnivariateDerivative1() {
338 final double nonZeroParameterForQuadraticCoeff = -1.;
339 final UnivariateDerivative1[] coefficients = buildUnivariateDerivative1Coefficients(1.,2., nonZeroParameterForQuadraticCoeff);
340 templateIssue259DisappearingCoefficients(coefficients);
341 }
342
343 @Test
344 void testIssue259WithUnivariateDerivative2() {
345 final double nonZeroParameterForQuadraticCoeff = -1.;
346 final UnivariateDerivative2[] coefficients = buildUnivariateDerivative2Coefficients(1.,2., nonZeroParameterForQuadraticCoeff);
347 templateIssue259DisappearingCoefficients(coefficients);
348 }
349
350 private <T extends CalculusFieldElement<T>> void templateIssue259DisappearingCoefficients(T[] coefficients) {
351 final FieldPolynomialFunction<T> polynomialFunction = new FieldPolynomialFunction<>(coefficients);
352 assertEquals(coefficients.length, polynomialFunction.getCoefficients().length);
353 for (int i = 0; i < coefficients.length; i++) {
354 assertEquals(coefficients[i], polynomialFunction.getCoefficients()[i]);
355 }
356 }
357
358 private <T extends CalculusFieldElement<T>> void checkInverseDifferentiation(FieldPolynomialFunction<T> p) {
359 final T[] c0 = p.getCoefficients();
360 final T[] c1 = p.antiDerivative().polynomialDerivative().getCoefficients();
361 assertEquals(c0.length, c1.length);
362 for (int i = 0; i < c0.length; ++i) {
363 assertEquals(c0[i].getReal(), c1[i].getReal(), 1e-12);
364 }
365 }
366
367 private <T extends CalculusFieldElement<T>> void checkCoeffs(final double tolerance, final FieldPolynomialFunction<T> p,
368 final double... ref) {
369 final T[] c = p.getCoefficients();
370 assertEquals(ref.length, c.length);
371 for (int i = 0; i < ref.length; ++i) {
372 assertEquals(ref[i], c[i].getReal(), tolerance);
373 }
374 }
375
376 private <T extends CalculusFieldElement<T>> void checkNullPolynomial(FieldPolynomialFunction<T> p) {
377 for (T coefficient : p.getCoefficients()) {
378 assertEquals(0, coefficient.getReal(), 1e-15);
379 }
380 }
381
382 private FieldPolynomialFunction<Binary64> buildD64(double...c) {
383 Binary64[] array = new Binary64[c.length];
384 for (int i = 0; i < c.length; ++i) {
385 array[i] = new Binary64(c[i]);
386 }
387 return new FieldPolynomialFunction<>(array);
388 }
389
390 private Complex[] buildImaginaryCoefficients(double...c) {
391 Complex[] array = new Complex[c.length];
392 for (int i = 0; i < c.length; ++i) {
393 array[i] = new Complex(0., c[i]);
394 }
395 return array;
396 }
397
398 private DerivativeStructure[] buildUnivariateDSCoefficients(double...c) {
399 DerivativeStructure[] array = new DerivativeStructure[c.length];
400 final DSFactory factory = new DSFactory(1, 1);
401 for (int i = 0; i < c.length; ++i) {
402 array[i] = factory.variable(0, 0.).multiply(c[i]);
403 }
404 return array;
405 }
406
407 private Gradient[] buildUnivariateGradientCoefficients(double...c) {
408 Gradient[] array = new Gradient[c.length];
409 for (int i = 0; i < c.length; ++i) {
410 array[i] = Gradient.variable(1, 0, 0.).multiply(c[i]);
411 }
412 return array;
413 }
414
415 private UnivariateDerivative1[] buildUnivariateDerivative1Coefficients(double...c) {
416 UnivariateDerivative1[] array = new UnivariateDerivative1[c.length];
417 for (int i = 0; i < c.length; ++i) {
418 array[i] = new UnivariateDerivative1(0., c[i]);
419 }
420 return array;
421 }
422
423 private UnivariateDerivative2[] buildUnivariateDerivative2Coefficients(double...c) {
424 UnivariateDerivative2[] array = new UnivariateDerivative2[c.length];
425 for (int i = 0; i < c.length; ++i) {
426 array[i] = new UnivariateDerivative2(0., c[i], 0.);
427 }
428 return array;
429 }
430
431 }