View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.analysis.polynomials;
23  
24  import org.hipparchus.analysis.differentiation.DSFactory;
25  import org.hipparchus.analysis.differentiation.DerivativeStructure;
26  import org.hipparchus.exception.MathIllegalArgumentException;
27  import org.hipparchus.util.Binary64;
28  import org.junit.jupiter.api.Test;
29  
30  import static org.junit.jupiter.api.Assertions.assertEquals;
31  import static org.junit.jupiter.api.Assertions.fail;
32  
33  
34  /**
35   * Test case for Newton form of polynomial function.
36   * <p>
37   * The small tolerance number is used only to account for round-off errors.
38   *
39   */
40  final class PolynomialFunctionNewtonFormTest {
41  
42      /**
43       * Test of polynomial for the linear function.
44       */
45      @Test
46      void testLinearFunction() {
47          PolynomialFunctionNewtonForm p;
48          double[] coefficients;
49          double z;
50          double expected;
51          double result;
52          double tolerance = 1E-12;
53  
54          // p(x) = 1.5x - 4 = 2 + 1.5(x-4)
55          double[] a = { 2.0, 1.5 };
56          double[] c = { 4.0 };
57          p = new PolynomialFunctionNewtonForm(a, c);
58  
59          z = 2.0; expected = -1.0; result = p.value(z);
60          assertEquals(expected, result, tolerance);
61  
62          z = 4.5; expected = 2.75; result = p.value(z);
63          assertEquals(expected, result, tolerance);
64  
65          z = 6.0; expected = 5.0; result = p.value(new Binary64(z)).getReal();
66          assertEquals(expected, result, tolerance);
67  
68          assertEquals(1, p.degree());
69  
70          coefficients = p.getCoefficients();
71          assertEquals(2, coefficients.length);
72          assertEquals(-4.0, coefficients[0], tolerance);
73          assertEquals(1.5, coefficients[1], tolerance);
74      }
75  
76      /**
77       * Test of polynomial for the quadratic function.
78       */
79      @Test
80      void testQuadraticFunction() {
81          PolynomialFunctionNewtonForm p;
82          double[] coefficients;
83          double z;
84          double expected;
85          double result;
86          double tolerance = 1E-12;
87  
88          // p(x) = 2x^2 + 5x - 3 = 4 + 3(x-1) + 2(x-1)(x+2)
89          double[] a = { 4.0, 3.0, 2.0 };
90          double[] c = { 1.0, -2.0 };
91          p = new PolynomialFunctionNewtonForm(a, c);
92  
93          z = 1.0; expected = 4.0; result = p.value(z);
94          assertEquals(expected, result, tolerance);
95  
96          z = 2.5; expected = 22.0; result = p.value(z);
97          assertEquals(expected, result, tolerance);
98  
99          z = -2.0; expected = -5.0; result = p.value(z);
100         assertEquals(expected, result, tolerance);
101 
102         assertEquals(2, p.degree());
103 
104         coefficients = p.getCoefficients();
105         assertEquals(3, coefficients.length);
106         assertEquals(-3.0, coefficients[0], tolerance);
107         assertEquals(5.0, coefficients[1], tolerance);
108         assertEquals(2.0, coefficients[2], tolerance);
109     }
110 
111     /**
112      * Test of polynomial for the quintic function.
113      */
114     @Test
115     void testQuinticFunction() {
116         PolynomialFunctionNewtonForm p;
117         double[] coefficients;
118         double z;
119         double expected;
120         double result;
121         double tolerance = 1E-12;
122 
123         // p(x) = x^5 - x^4 - 7x^3 + x^2 + 6x
124         //      = 6x - 6x^2 -6x^2(x-1) + x^2(x-1)(x+1) + x^2(x-1)(x+1)(x-2)
125         double[] a = { 0.0, 6.0, -6.0, -6.0, 1.0, 1.0 };
126         double[] c = { 0.0, 0.0, 1.0, -1.0, 2.0 };
127         p = new PolynomialFunctionNewtonForm(a, c);
128 
129         z = 0.0; expected = 0.0; result = p.value(z);
130         assertEquals(expected, result, tolerance);
131 
132         z = -2.0; expected = 0.0; result = p.value(z);
133         assertEquals(expected, result, tolerance);
134 
135         z = 4.0; expected = 360.0; result = p.value(z);
136         assertEquals(expected, result, tolerance);
137 
138         assertEquals(5, p.degree());
139 
140         coefficients = p.getCoefficients();
141         assertEquals(6, coefficients.length);
142         assertEquals(0.0, coefficients[0], tolerance);
143         assertEquals(6.0, coefficients[1], tolerance);
144         assertEquals(1.0, coefficients[2], tolerance);
145         assertEquals(-7.0, coefficients[3], tolerance);
146         assertEquals(-1.0, coefficients[4], tolerance);
147         assertEquals(1.0, coefficients[5], tolerance);
148     }
149 
150     /**
151      * Test for derivatives.
152      */
153     @Test
154     void testDerivative() {
155 
156         // x^3 = 0 * [1] + 1 * [x] + 3 * [x(x-1)] + 1 * [x(x-1)(x-2)]
157         PolynomialFunctionNewtonForm p =
158                 new PolynomialFunctionNewtonForm(new double[] { 0, 1, 3, 1 },
159                                                  new double[] { 0, 1, 2 });
160 
161         double eps = 2.0e-14;
162         DSFactory factory = new DSFactory(1, 4);
163         for (double t = 0.0; t < 10.0; t += 0.1) {
164             DerivativeStructure x = factory.variable(0, t);
165             DerivativeStructure y = p.value(x);
166             assertEquals(t * t * t,   y.getValue(),              eps * t * t * t);
167             assertEquals(3.0 * t * t, y.getPartialDerivative(1), eps * 3.0 * t * t);
168             assertEquals(6.0 * t,     y.getPartialDerivative(2), eps * 6.0 * t);
169             assertEquals(6.0,         y.getPartialDerivative(3), eps * 6.0);
170             assertEquals(0.0,         y.getPartialDerivative(4), eps);
171         }
172 
173     }
174 
175     /**
176      * Test of parameters for the polynomial.
177      */
178     @Test
179     void testParameters() {
180 
181         try {
182             // bad input array length
183             double[] a = { 1.0 };
184             double[] c = { 2.0 };
185             new PolynomialFunctionNewtonForm(a, c);
186             fail("Expecting MathIllegalArgumentException - bad input array length");
187         } catch (MathIllegalArgumentException ex) {
188             // expected
189         }
190         try {
191             // mismatch input arrays
192             double[] a = { 1.0, 2.0, 3.0, 4.0 };
193             double[] c = { 4.0, 3.0, 2.0, 1.0 };
194             new PolynomialFunctionNewtonForm(a, c);
195             fail("Expecting MathIllegalArgumentException - mismatch input arrays");
196         } catch (MathIllegalArgumentException ex) {
197             // expected
198         }
199     }
200 }