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    *      http://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  package org.apache.commons.math4.legacy.analysis.polynomials;
18  
19  import org.apache.commons.math4.core.jdkmath.JdkMath;
20  import org.junit.Assert;
21  import org.junit.Test;
22  
23  /**
24   * Tests the PolynomialFunction implementation of a UnivariateFunction.
25   *
26   */
27  public final class PolynomialFunctionTest {
28      /** Error tolerance for tests */
29      protected double tolerance = 1e-12;
30  
31      /**
32       * tests the value of a constant polynomial.
33       *
34       * <p>value of this is 2.5 everywhere.</p>
35       */
36      @Test
37      public void testConstants() {
38          double[] c = { 2.5 };
39          PolynomialFunction f = new PolynomialFunction(c);
40  
41          // verify that we are equal to c[0] at several (nonsymmetric) places
42          Assert.assertEquals(f.value(0), c[0], tolerance);
43          Assert.assertEquals(f.value(-1), c[0], tolerance);
44          Assert.assertEquals(f.value(-123.5), c[0], tolerance);
45          Assert.assertEquals(f.value(3), c[0], tolerance);
46          Assert.assertEquals(f.value(456.89), c[0], tolerance);
47  
48          Assert.assertEquals(f.degree(), 0);
49          Assert.assertEquals(f.polynomialDerivative().value(0), 0, tolerance);
50  
51          Assert.assertEquals(f.polynomialDerivative().polynomialDerivative().value(0), 0, tolerance);
52      }
53  
54      /**
55       * tests the value of a linear polynomial.
56       *
57       * <p>This will test the function f(x) = 3*x - 1.5</p>
58       * <p>This will have the values
59       *  <code>f(0) = -1.5, f(-1) = -4.5, f(-2.5) = -9,
60       *      f(0.5) = 0, f(1.5) = 3</code> and {@code f(3) = 7.5}
61       * </p>
62       */
63      @Test
64      public void testLinear() {
65          double[] c = { -1.5, 3 };
66          PolynomialFunction f = new PolynomialFunction(c);
67  
68          // verify that we are equal to c[0] when x=0
69          Assert.assertEquals(f.value(0), c[0], tolerance);
70  
71          // now check a few other places
72          Assert.assertEquals(-4.5, f.value(-1), tolerance);
73          Assert.assertEquals(-9, f.value(-2.5), tolerance);
74          Assert.assertEquals(0, f.value(0.5), tolerance);
75          Assert.assertEquals(3, f.value(1.5), tolerance);
76          Assert.assertEquals(7.5, f.value(3), tolerance);
77  
78          Assert.assertEquals(f.degree(), 1);
79  
80          Assert.assertEquals(f.polynomialDerivative().polynomialDerivative().value(0), 0, tolerance);
81      }
82  
83      /**
84       * Tests a second order polynomial.
85       * <p> This will test the function f(x) = 2x^2 - 3x -2 = (2x+1)(x-2)</p>
86       */
87      @Test
88      public void testQuadratic() {
89          double[] c = { -2, -3, 2 };
90          PolynomialFunction f = new PolynomialFunction(c);
91  
92          // verify that we are equal to c[0] when x=0
93          Assert.assertEquals(f.value(0), c[0], tolerance);
94  
95          // now check a few other places
96          Assert.assertEquals(0, f.value(-0.5), tolerance);
97          Assert.assertEquals(0, f.value(2), tolerance);
98          Assert.assertEquals(-2, f.value(1.5), tolerance);
99          Assert.assertEquals(7, f.value(-1.5), tolerance);
100         Assert.assertEquals(265.5312, f.value(12.34), tolerance);
101     }
102 
103     /**
104      * This will test the quintic function
105      *   f(x) = x^2(x-5)(x+3)(x-1) = x^5 - 3x^4 -13x^3 + 15x^2</p>
106      */
107     @Test
108     public void testQuintic() {
109         double[] c = { 0, 0, 15, -13, -3, 1 };
110         PolynomialFunction f = new PolynomialFunction(c);
111 
112         // verify that we are equal to c[0] when x=0
113         Assert.assertEquals(f.value(0), c[0], tolerance);
114 
115         // now check a few other places
116         Assert.assertEquals(0, f.value(5), tolerance);
117         Assert.assertEquals(0, f.value(1), tolerance);
118         Assert.assertEquals(0, f.value(-3), tolerance);
119         Assert.assertEquals(54.84375, f.value(-1.5), tolerance);
120         Assert.assertEquals(-8.06637, f.value(1.3), tolerance);
121 
122         Assert.assertEquals(f.degree(), 5);
123     }
124 
125     /**
126      * tests the firstDerivative function by comparison
127      *
128      * <p>This will test the functions
129      * {@code f(x) = x^3 - 2x^2 + 6x + 3, g(x) = 3x^2 - 4x + 6}
130      * and {@code h(x) = 6x - 4}
131      */
132     @Test
133     public void testfirstDerivativeComparison() {
134         double[] f_coeff = { 3, 6, -2, 1 };
135         double[] g_coeff = { 6, -4, 3 };
136         double[] h_coeff = { -4, 6 };
137 
138         PolynomialFunction f = new PolynomialFunction(f_coeff);
139         PolynomialFunction g = new PolynomialFunction(g_coeff);
140         PolynomialFunction h = new PolynomialFunction(h_coeff);
141 
142         // compare f' = g
143         Assert.assertEquals(f.polynomialDerivative().value(0), g.value(0), tolerance);
144         Assert.assertEquals(f.polynomialDerivative().value(1), g.value(1), tolerance);
145         Assert.assertEquals(f.polynomialDerivative().value(100), g.value(100), tolerance);
146         Assert.assertEquals(f.polynomialDerivative().value(4.1), g.value(4.1), tolerance);
147         Assert.assertEquals(f.polynomialDerivative().value(-3.25), g.value(-3.25), tolerance);
148 
149         // compare g' = h
150         Assert.assertEquals(g.polynomialDerivative().value(JdkMath.PI), h.value(JdkMath.PI), tolerance);
151         Assert.assertEquals(g.polynomialDerivative().value(JdkMath.E),  h.value(JdkMath.E),  tolerance);
152     }
153 
154     @Test
155     public void testString() {
156         PolynomialFunction p = new PolynomialFunction(new double[] { -5, 3, 1 });
157         checkPolynomial(p, "-5 + 3 x + x^2");
158         checkPolynomial(new PolynomialFunction(new double[] { 0, -2, 3 }),
159                         "-2 x + 3 x^2");
160         checkPolynomial(new PolynomialFunction(new double[] { 1, -2, 3 }),
161                       "1 - 2 x + 3 x^2");
162         checkPolynomial(new PolynomialFunction(new double[] { 0,  2, 3 }),
163                        "2 x + 3 x^2");
164         checkPolynomial(new PolynomialFunction(new double[] { 1,  2, 3 }),
165                      "1 + 2 x + 3 x^2");
166         checkPolynomial(new PolynomialFunction(new double[] { 1,  0, 3 }),
167                      "1 + 3 x^2");
168         checkPolynomial(new PolynomialFunction(new double[] { 0 }),
169                      "0");
170     }
171 
172     @Test
173     public void testAddition() {
174         PolynomialFunction p1 = new PolynomialFunction(new double[] { -2, 1 });
175         PolynomialFunction p2 = new PolynomialFunction(new double[] { 2, -1, 0 });
176         checkNullPolynomial(p1.add(p2));
177 
178         p2 = p1.add(p1);
179         checkPolynomial(p2, "-4 + 2 x");
180 
181         p1 = new PolynomialFunction(new double[] { 1, -4, 2 });
182         p2 = new PolynomialFunction(new double[] { -1, 3, -2 });
183         p1 = p1.add(p2);
184         Assert.assertEquals(1, p1.degree());
185         checkPolynomial(p1, "-x");
186     }
187 
188     @Test
189     public void testSubtraction() {
190         PolynomialFunction p1 = new PolynomialFunction(new double[] { -2, 1 });
191         checkNullPolynomial(p1.subtract(p1));
192 
193         PolynomialFunction p2 = new PolynomialFunction(new double[] { -2, 6 });
194         p2 = p2.subtract(p1);
195         checkPolynomial(p2, "5 x");
196 
197         p1 = new PolynomialFunction(new double[] { 1, -4, 2 });
198         p2 = new PolynomialFunction(new double[] { -1, 3, 2 });
199         p1 = p1.subtract(p2);
200         Assert.assertEquals(1, p1.degree());
201         checkPolynomial(p1, "2 - 7 x");
202     }
203 
204     @Test
205     public void testMultiplication() {
206         PolynomialFunction p1 = new PolynomialFunction(new double[] { -3, 2 });
207         PolynomialFunction p2 = new PolynomialFunction(new double[] { 3, 2, 1 });
208         checkPolynomial(p1.multiply(p2), "-9 + x^2 + 2 x^3");
209 
210         p1 = new PolynomialFunction(new double[] { 0, 1 });
211         p2 = p1;
212         for (int i = 2; i < 10; ++i) {
213             p2 = p2.multiply(p1);
214             checkPolynomial(p2, "x^" + i);
215         }
216     }
217 
218     /**
219      * tests the firstDerivative function by comparison
220      *
221      * <p>This will test the functions
222      * {@code f(x) = x^3 - 2x^2 + 6x + 3, g(x) = 3x^2 - 4x + 6}
223      * and {@code h(x) = 6x - 4}
224      */
225     @Test
226     public void testMath341() {
227         double[] f_coeff = { 3, 6, -2, 1 };
228         double[] g_coeff = { 6, -4, 3 };
229         double[] h_coeff = { -4, 6 };
230 
231         PolynomialFunction f = new PolynomialFunction(f_coeff);
232         PolynomialFunction g = new PolynomialFunction(g_coeff);
233         PolynomialFunction h = new PolynomialFunction(h_coeff);
234 
235         // compare f' = g
236         Assert.assertEquals(f.polynomialDerivative().value(0), g.value(0), tolerance);
237         Assert.assertEquals(f.polynomialDerivative().value(1), g.value(1), tolerance);
238         Assert.assertEquals(f.polynomialDerivative().value(100), g.value(100), tolerance);
239         Assert.assertEquals(f.polynomialDerivative().value(4.1), g.value(4.1), tolerance);
240         Assert.assertEquals(f.polynomialDerivative().value(-3.25), g.value(-3.25), tolerance);
241 
242         // compare g' = h
243         Assert.assertEquals(g.polynomialDerivative().value(JdkMath.PI), h.value(JdkMath.PI), tolerance);
244         Assert.assertEquals(g.polynomialDerivative().value(JdkMath.E),  h.value(JdkMath.E),  tolerance);
245     }
246 
247     public void checkPolynomial(PolynomialFunction p, String reference) {
248         Assert.assertEquals(reference, p.toString());
249     }
250 
251     private void checkNullPolynomial(PolynomialFunction p) {
252         for (double coefficient : p.getCoefficients()) {
253             Assert.assertEquals(0, coefficient, 1e-15);
254         }
255     }
256 }