1 /* 2 * Copyright 2003-2004 The Apache Software Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.apache.commons.math.analysis; 17 18 import java.io.Serializable; 19 20 /** 21 * Immutable representation of a real polynomial function with real coefficients. 22 * <p> 23 * <a href="http://mathworld.wolfram.com/HornersMethod.html">Horner's Method</a> 24 * is used to evaluate the function. 25 * 26 * @version $Revision: 348519 $ $Date: 2005-11-23 12:12:18 -0700 (Wed, 23 Nov 2005) $ 27 */ 28 public class PolynomialFunction implements DifferentiableUnivariateRealFunction, Serializable { 29 30 /** Serializable version identifier */ 31 private static final long serialVersionUID = 3322454535052136809L; 32 33 /** 34 * The coefficients of the polynomial, ordered by degree -- i.e., 35 * coefficients[0] is the constant term and coefficients[n] is the 36 * coefficient of x^n where n is the degree of the polynomial. 37 */ 38 private double coefficients[]; 39 40 /** 41 * Construct a polynomial with the given coefficients. The first element 42 * of the coefficients array is the constant term. Higher degree 43 * coefficients follow in sequence. The degree of the resulting polynomial 44 * is the length of the array minus 1. 45 * <p> 46 * The constructor makes a copy of the input array and assigns the copy to 47 * the coefficients property. 48 * 49 * @param c polynominal coefficients 50 * @throws NullPointerException if c is null 51 * @throws IllegalArgumentException if c is empty 52 */ 53 public PolynomialFunction(double c[]) { 54 super(); 55 if (c.length < 1) { 56 throw new IllegalArgumentException("Polynomial coefficient array must have postive length."); 57 } 58 this.coefficients = new double[c.length]; 59 System.arraycopy(c, 0, this.coefficients, 0, c.length); 60 } 61 62 /** 63 * Compute the value of the function for the given argument. 64 * <p> 65 * The value returned is <br> 66 * <code>coefficients[n] * x^n + ... + coefficients[1] * x + coefficients[0]</code> 67 * 68 * @param x the argument for which the function value should be computed 69 * @return the value of the polynomial at the given point 70 * @see UnivariateRealFunction#value(double) 71 */ 72 public double value(double x) { 73 return evaluate(coefficients, x); 74 } 75 76 77 /** 78 * Returns the degree of the polynomial 79 * 80 * @return the degree of the polynomial 81 */ 82 public int degree() { 83 return coefficients.length - 1; 84 } 85 86 /** 87 * Returns a copy of the coefficients array. 88 * <p> 89 * Changes made to the returned copy will not affect the coefficients of 90 * the polynomial. 91 * 92 * @return a fresh copy of the coefficients array 93 */ 94 public double[] getCoefficients() { 95 double[] out = new double[coefficients.length]; 96 System.arraycopy(coefficients,0, out, 0, coefficients.length); 97 return out; 98 } 99 100 /** 101 * Uses Horner's Method to evaluate the polynomial with the given coefficients at 102 * the argument. 103 * 104 * @param coefficients the coefficients of the polynomial to evaluate 105 * @param argument the input value 106 * @return the value of the polynomial 107 * @throws IllegalArgumentException if coefficients is empty 108 * @throws NullPointerException if coefficients is null 109 */ 110 protected static double evaluate(double[] coefficients, double argument) { 111 int n = coefficients.length; 112 if (n < 1) { 113 throw new IllegalArgumentException("Coefficient array must have positive length for evaluation"); 114 } 115 double result = coefficients[n - 1]; 116 for (int j = n -2; j >=0; j--) { 117 result = argument * result + coefficients[j]; 118 } 119 return result; 120 } 121 122 /** 123 * Returns the coefficients of the derivative of the polynomial with the given coefficients. 124 * 125 * @param coefficients the coefficients of the polynomial to differentiate 126 * @return the coefficients of the derivative or null if coefficients has length 1. 127 * @throws IllegalArgumentException if coefficients is empty 128 * @throws NullPointerException if coefficients is null 129 */ 130 protected static double[] differentiate(double[] coefficients) { 131 int n = coefficients.length; 132 if (n < 1) { 133 throw new IllegalArgumentException("Coefficient array must have positive length for differentiation"); 134 } 135 if (n == 1) { 136 return new double[]{0}; 137 } 138 double[] result = new double[n - 1]; 139 for (int i = n - 1; i > 0; i--) { 140 result[i - 1] = (double) i * coefficients[i]; 141 } 142 return result; 143 } 144 145 /** 146 * Returns the derivative as a PolynomialRealFunction 147 * 148 * @return the derivative polynomial 149 */ 150 public PolynomialFunction polynomialDerivative() { 151 return new PolynomialFunction(differentiate(coefficients)); 152 } 153 154 /** 155 * Returns the derivative as a UnivariateRealFunction 156 * 157 * @return the derivative function 158 */ 159 public UnivariateRealFunction derivative() { 160 return polynomialDerivative(); 161 } 162 163 }