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.Assert;
29  import org.junit.Test;
30  
31  
32  /**
33   * Test case for Newton form of polynomial function.
34   * <p>
35   * The small tolerance number is used only to account for round-off errors.
36   *
37   */
38  public final class PolynomialFunctionNewtonFormTest {
39  
40      /**
41       * Test of polynomial for the linear function.
42       */
43      @Test
44      public void testLinearFunction() {
45          PolynomialFunctionNewtonForm p;
46          double[] coefficients;
47          double z;
48          double expected;
49          double result;
50          double tolerance = 1E-12;
51  
52          // p(x) = 1.5x - 4 = 2 + 1.5(x-4)
53          double[] a = { 2.0, 1.5 };
54          double[] c = { 4.0 };
55          p = new PolynomialFunctionNewtonForm(a, c);
56  
57          z = 2.0; expected = -1.0; result = p.value(z);
58          Assert.assertEquals(expected, result, tolerance);
59  
60          z = 4.5; expected = 2.75; result = p.value(z);
61          Assert.assertEquals(expected, result, tolerance);
62  
63          z = 6.0; expected = 5.0; result = p.value(new Binary64(z)).getReal();
64          Assert.assertEquals(expected, result, tolerance);
65  
66          Assert.assertEquals(1, p.degree());
67  
68          coefficients = p.getCoefficients();
69          Assert.assertEquals(2, coefficients.length);
70          Assert.assertEquals(-4.0, coefficients[0], tolerance);
71          Assert.assertEquals(1.5, coefficients[1], tolerance);
72      }
73  
74      /**
75       * Test of polynomial for the quadratic function.
76       */
77      @Test
78      public void testQuadraticFunction() {
79          PolynomialFunctionNewtonForm p;
80          double[] coefficients;
81          double z;
82          double expected;
83          double result;
84          double tolerance = 1E-12;
85  
86          // p(x) = 2x^2 + 5x - 3 = 4 + 3(x-1) + 2(x-1)(x+2)
87          double[] a = { 4.0, 3.0, 2.0 };
88          double[] c = { 1.0, -2.0 };
89          p = new PolynomialFunctionNewtonForm(a, c);
90  
91          z = 1.0; expected = 4.0; result = p.value(z);
92          Assert.assertEquals(expected, result, tolerance);
93  
94          z = 2.5; expected = 22.0; result = p.value(z);
95          Assert.assertEquals(expected, result, tolerance);
96  
97          z = -2.0; expected = -5.0; result = p.value(z);
98          Assert.assertEquals(expected, result, tolerance);
99  
100         Assert.assertEquals(2, p.degree());
101 
102         coefficients = p.getCoefficients();
103         Assert.assertEquals(3, coefficients.length);
104         Assert.assertEquals(-3.0, coefficients[0], tolerance);
105         Assert.assertEquals(5.0, coefficients[1], tolerance);
106         Assert.assertEquals(2.0, coefficients[2], tolerance);
107     }
108 
109     /**
110      * Test of polynomial for the quintic function.
111      */
112     @Test
113     public void testQuinticFunction() {
114         PolynomialFunctionNewtonForm p;
115         double[] coefficients;
116         double z;
117         double expected;
118         double result;
119         double tolerance = 1E-12;
120 
121         // p(x) = x^5 - x^4 - 7x^3 + x^2 + 6x
122         //      = 6x - 6x^2 -6x^2(x-1) + x^2(x-1)(x+1) + x^2(x-1)(x+1)(x-2)
123         double[] a = { 0.0, 6.0, -6.0, -6.0, 1.0, 1.0 };
124         double[] c = { 0.0, 0.0, 1.0, -1.0, 2.0 };
125         p = new PolynomialFunctionNewtonForm(a, c);
126 
127         z = 0.0; expected = 0.0; result = p.value(z);
128         Assert.assertEquals(expected, result, tolerance);
129 
130         z = -2.0; expected = 0.0; result = p.value(z);
131         Assert.assertEquals(expected, result, tolerance);
132 
133         z = 4.0; expected = 360.0; result = p.value(z);
134         Assert.assertEquals(expected, result, tolerance);
135 
136         Assert.assertEquals(5, p.degree());
137 
138         coefficients = p.getCoefficients();
139         Assert.assertEquals(6, coefficients.length);
140         Assert.assertEquals(0.0, coefficients[0], tolerance);
141         Assert.assertEquals(6.0, coefficients[1], tolerance);
142         Assert.assertEquals(1.0, coefficients[2], tolerance);
143         Assert.assertEquals(-7.0, coefficients[3], tolerance);
144         Assert.assertEquals(-1.0, coefficients[4], tolerance);
145         Assert.assertEquals(1.0, coefficients[5], tolerance);
146     }
147 
148     /**
149      * Test for derivatives.
150      */
151     @Test
152     public void testDerivative() {
153 
154         // x^3 = 0 * [1] + 1 * [x] + 3 * [x(x-1)] + 1 * [x(x-1)(x-2)]
155         PolynomialFunctionNewtonForm p =
156                 new PolynomialFunctionNewtonForm(new double[] { 0, 1, 3, 1 },
157                                                  new double[] { 0, 1, 2 });
158 
159         double eps = 2.0e-14;
160         DSFactory factory = new DSFactory(1, 4);
161         for (double t = 0.0; t < 10.0; t += 0.1) {
162             DerivativeStructure x = factory.variable(0, t);
163             DerivativeStructure y = p.value(x);
164             Assert.assertEquals(t * t * t,   y.getValue(),              eps * t * t * t);
165             Assert.assertEquals(3.0 * t * t, y.getPartialDerivative(1), eps * 3.0 * t * t);
166             Assert.assertEquals(6.0 * t,     y.getPartialDerivative(2), eps * 6.0 * t);
167             Assert.assertEquals(6.0,         y.getPartialDerivative(3), eps * 6.0);
168             Assert.assertEquals(0.0,         y.getPartialDerivative(4), eps);
169         }
170 
171     }
172 
173     /**
174      * Test of parameters for the polynomial.
175      */
176     @Test
177     public void testParameters() {
178 
179         try {
180             // bad input array length
181             double[] a = { 1.0 };
182             double[] c = { 2.0 };
183             new PolynomialFunctionNewtonForm(a, c);
184             Assert.fail("Expecting MathIllegalArgumentException - bad input array length");
185         } catch (MathIllegalArgumentException ex) {
186             // expected
187         }
188         try {
189             // mismatch input arrays
190             double[] a = { 1.0, 2.0, 3.0, 4.0 };
191             double[] c = { 4.0, 3.0, 2.0, 1.0 };
192             new PolynomialFunctionNewtonForm(a, c);
193             Assert.fail("Expecting MathIllegalArgumentException - mismatch input arrays");
194         } catch (MathIllegalArgumentException ex) {
195             // expected
196         }
197     }
198 }