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 }