001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math.analysis.polynomials;
018
019 // commons-math
020 import org.apache.commons.math.MathException;
021 import org.apache.commons.math.TestUtils;
022 // junit
023 import junit.framework.TestCase;
024
025 /**
026 * Tests the PolynomialFunction implementation of a UnivariateRealFunction.
027 *
028 * @version $Revision: 799857 $
029 * @author Matt Cliff <matt@mattcliff.com>
030 */
031 public final class PolynomialFunctionTest extends TestCase {
032
033 /** Error tolerance for tests */
034 protected double tolerance = 1.0e-12;
035
036 /**
037 * tests the value of a constant polynomial.
038 *
039 * <p>value of this is 2.5 everywhere.</p>
040 */
041 public void testConstants() throws MathException {
042 double[] c = { 2.5 };
043 PolynomialFunction f = new PolynomialFunction( c );
044
045 // verify that we are equal to c[0] at several (nonsymmetric) places
046 assertEquals( f.value( 0.0), c[0], tolerance );
047 assertEquals( f.value( -1.0), c[0], tolerance );
048 assertEquals( f.value( -123.5), c[0], tolerance );
049 assertEquals( f.value( 3.0), c[0], tolerance );
050 assertEquals( f.value( 456.89), c[0], tolerance );
051
052 assertEquals(f.degree(), 0);
053 assertEquals(f.derivative().value(0), 0, tolerance);
054
055 assertEquals(f.polynomialDerivative().derivative().value(0), 0, tolerance);
056 }
057
058 /**
059 * tests the value of a linear polynomial.
060 *
061 * <p>This will test the function f(x) = 3*x - 1.5</p>
062 * <p>This will have the values
063 * <tt>f(0.0) = -1.5, f(-1.0) = -4.5, f(-2.5) = -9.0,
064 * f(0.5) = 0.0, f(1.5) = 3.0</tt> and <tt>f(3.0) = 7.5</tt>
065 * </p>
066 */
067 public void testLinear() throws MathException {
068 double[] c = { -1.5, 3.0 };
069 PolynomialFunction f = new PolynomialFunction( c );
070
071 // verify that we are equal to c[0] when x=0
072 assertEquals( f.value( 0.0), c[0], tolerance );
073
074 // now check a few other places
075 assertEquals( -4.5, f.value( -1.0), tolerance );
076 assertEquals( -9.0, f.value( -2.5), tolerance );
077 assertEquals( 0.0, f.value( 0.5), tolerance );
078 assertEquals( 3.0, f.value( 1.5), tolerance );
079 assertEquals( 7.5, f.value( 3.0), tolerance );
080
081 assertEquals(f.degree(), 1);
082
083 assertEquals(f.polynomialDerivative().derivative().value(0), 0, tolerance);
084
085 }
086
087
088 /**
089 * Tests a second order polynomial.
090 * <p> This will test the function f(x) = 2x^2 - 3x -2 = (2x+1)(x-2)</p>
091 *
092 */
093 public void testQuadratic() {
094 double[] c = { -2.0, -3.0, 2.0 };
095 PolynomialFunction f = new PolynomialFunction( c );
096
097 // verify that we are equal to c[0] when x=0
098 assertEquals( f.value( 0.0), c[0], tolerance );
099
100 // now check a few other places
101 assertEquals( 0.0, f.value( -0.5), tolerance );
102 assertEquals( 0.0, f.value( 2.0), tolerance );
103 assertEquals( -2.0, f.value( 1.5), tolerance );
104 assertEquals( 7.0, f.value( -1.5), tolerance );
105 assertEquals( 265.5312, f.value( 12.34), tolerance );
106
107 }
108
109
110 /**
111 * This will test the quintic function
112 * f(x) = x^2(x-5)(x+3)(x-1) = x^5 - 3x^4 -13x^3 + 15x^2</p>
113 *
114 */
115 public void testQuintic() {
116 double[] c = { 0.0, 0.0, 15.0, -13.0, -3.0, 1.0 };
117 PolynomialFunction f = new PolynomialFunction( c );
118
119 // verify that we are equal to c[0] when x=0
120 assertEquals( f.value( 0.0), c[0], tolerance );
121
122 // now check a few other places
123 assertEquals( 0.0, f.value( 5.0), tolerance );
124 assertEquals( 0.0, f.value( 1.0), tolerance );
125 assertEquals( 0.0, f.value( -3.0), tolerance );
126 assertEquals( 54.84375, f.value( -1.5), tolerance );
127 assertEquals( -8.06637, f.value( 1.3), tolerance );
128
129 assertEquals(f.degree(), 5);
130
131 }
132
133
134 /**
135 * tests the firstDerivative function by comparison
136 *
137 * <p>This will test the functions
138 * <tt>f(x) = x^3 - 2x^2 + 6x + 3, g(x) = 3x^2 - 4x + 6</tt>
139 * and <tt>h(x) = 6x - 4</tt>
140 */
141 public void testfirstDerivativeComparison() throws MathException {
142 double[] f_coeff = { 3.0, 6.0, -2.0, 1.0 };
143 double[] g_coeff = { 6.0, -4.0, 3.0 };
144 double[] h_coeff = { -4.0, 6.0 };
145
146 PolynomialFunction f = new PolynomialFunction( f_coeff );
147 PolynomialFunction g = new PolynomialFunction( g_coeff );
148 PolynomialFunction h = new PolynomialFunction( h_coeff );
149
150 // compare f' = g
151 assertEquals( f.derivative().value(0.0), g.value(0.0), tolerance );
152 assertEquals( f.derivative().value(1.0), g.value(1.0), tolerance );
153 assertEquals( f.derivative().value(100.0), g.value(100.0), tolerance );
154 assertEquals( f.derivative().value(4.1), g.value(4.1), tolerance );
155 assertEquals( f.derivative().value(-3.25), g.value(-3.25), tolerance );
156
157 // compare g' = h
158 assertEquals( g.derivative().value(Math.PI), h.value(Math.PI), tolerance );
159 assertEquals( g.derivative().value(Math.E), h.value(Math.E), tolerance );
160
161 }
162
163 public void testString() {
164 PolynomialFunction p = new PolynomialFunction(new double[] { -5.0, 3.0, 1.0 });
165 checkPolynomial(p, "-5.0 + 3.0 x + x^2");
166 checkPolynomial(new PolynomialFunction(new double[] { 0.0, -2.0, 3.0 }),
167 "-2.0 x + 3.0 x^2");
168 checkPolynomial(new PolynomialFunction(new double[] { 1.0, -2.0, 3.0 }),
169 "1.0 - 2.0 x + 3.0 x^2");
170 checkPolynomial(new PolynomialFunction(new double[] { 0.0, 2.0, 3.0 }),
171 "2.0 x + 3.0 x^2");
172 checkPolynomial(new PolynomialFunction(new double[] { 1.0, 2.0, 3.0 }),
173 "1.0 + 2.0 x + 3.0 x^2");
174 checkPolynomial(new PolynomialFunction(new double[] { 1.0, 0.0, 3.0 }),
175 "1.0 + 3.0 x^2");
176 checkPolynomial(new PolynomialFunction(new double[] { 0.0 }),
177 "0");
178 }
179
180 public void testAddition() {
181
182 PolynomialFunction p1 = new PolynomialFunction(new double[] { -2.0, 1.0 });
183 PolynomialFunction p2 = new PolynomialFunction(new double[] { 2.0, -1.0, 0.0 });
184 checkNullPolynomial(p1.add(p2));
185
186 p2 = p1.add(p1);
187 checkPolynomial(p2, "-4.0 + 2.0 x");
188
189 p1 = new PolynomialFunction(new double[] { 1.0, -4.0, 2.0 });
190 p2 = new PolynomialFunction(new double[] { -1.0, 3.0, -2.0 });
191 p1 = p1.add(p2);
192 assertEquals(1, p1.degree());
193 checkPolynomial(p1, "-x");
194
195 }
196
197 public void testSubtraction() {
198
199 PolynomialFunction p1 = new PolynomialFunction(new double[] { -2.0, 1.0 });
200 checkNullPolynomial(p1.subtract(p1));
201
202 PolynomialFunction p2 = new PolynomialFunction(new double[] { -2.0, 6.0 });
203 p2 = p2.subtract(p1);
204 checkPolynomial(p2, "5.0 x");
205
206 p1 = new PolynomialFunction(new double[] { 1.0, -4.0, 2.0 });
207 p2 = new PolynomialFunction(new double[] { -1.0, 3.0, 2.0 });
208 p1 = p1.subtract(p2);
209 assertEquals(1, p1.degree());
210 checkPolynomial(p1, "2.0 - 7.0 x");
211
212 }
213
214 public void testMultiplication() {
215
216 PolynomialFunction p1 = new PolynomialFunction(new double[] { -3.0, 2.0 });
217 PolynomialFunction p2 = new PolynomialFunction(new double[] { 3.0, 2.0, 1.0 });
218 checkPolynomial(p1.multiply(p2), "-9.0 + x^2 + 2.0 x^3");
219
220 p1 = new PolynomialFunction(new double[] { 0.0, 1.0 });
221 p2 = p1;
222 for (int i = 2; i < 10; ++i) {
223 p2 = p2.multiply(p1);
224 checkPolynomial(p2, "x^" + i);
225 }
226
227 }
228
229 public void testSerial() {
230 PolynomialFunction p2 = new PolynomialFunction(new double[] { 3.0, 2.0, 1.0 });
231 assertEquals(p2, TestUtils.serializeAndRecover(p2));
232 }
233
234 public void checkPolynomial(PolynomialFunction p, String reference) {
235 assertEquals(reference, p.toString());
236 }
237
238 private void checkNullPolynomial(PolynomialFunction p) {
239 for (double coefficient : p.getCoefficients()) {
240 assertEquals(0.0, coefficient, 1.0e-15);
241 }
242 }
243
244 }