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 }