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.math.analysis; 18 19 import java.io.Serializable; 20 21 /** 22 * Immutable representation of a real polynomial function with real coefficients. 23 * <p> 24 * <a href="http://mathworld.wolfram.com/HornersMethod.html">Horner's Method</a> 25 * is used to evaluate the function.</p> 26 * 27 * @version $Revision: 615734 $ $Date: 2008-01-27 23:10:03 -0700 (Sun, 27 Jan 2008) $ 28 */ 29 public class PolynomialFunction implements DifferentiableUnivariateRealFunction, Serializable { 30 31 /** Serializable version identifier */ 32 private static final long serialVersionUID = 3322454535052136809L; 33 34 /** 35 * The coefficients of the polynomial, ordered by degree -- i.e., 36 * coefficients[0] is the constant term and coefficients[n] is the 37 * coefficient of x^n where n is the degree of the polynomial. 38 */ 39 private double coefficients[]; 40 41 /** 42 * Construct a polynomial with the given coefficients. The first element 43 * of the coefficients array is the constant term. Higher degree 44 * coefficients follow in sequence. The degree of the resulting polynomial 45 * is the length of the array minus 1. 46 * <p> 47 * The constructor makes a copy of the input array and assigns the copy to 48 * the coefficients property.</p> 49 * 50 * @param c polynominal coefficients 51 * @throws NullPointerException if c is null 52 * @throws IllegalArgumentException if c is empty 53 */ 54 public PolynomialFunction(double c[]) { 55 super(); 56 if (c.length < 1) { 57 throw new IllegalArgumentException("Polynomial coefficient array must have postive length."); 58 } 59 this.coefficients = new double[c.length]; 60 System.arraycopy(c, 0, this.coefficients, 0, c.length); 61 } 62 63 /** 64 * Compute the value of the function for the given argument. 65 * <p> 66 * The value returned is <br> 67 * <code>coefficients[n] * x^n + ... + coefficients[1] * x + coefficients[0]</code> 68 * </p> 69 * 70 * @param x the argument for which the function value should be computed 71 * @return the value of the polynomial at the given point 72 * @see UnivariateRealFunction#value(double) 73 */ 74 public double value(double x) { 75 return evaluate(coefficients, x); 76 } 77 78 79 /** 80 * Returns the degree of the polynomial 81 * 82 * @return the degree of the polynomial 83 */ 84 public int degree() { 85 return coefficients.length - 1; 86 } 87 88 /** 89 * Returns a copy of the coefficients array. 90 * <p> 91 * Changes made to the returned copy will not affect the coefficients of 92 * the polynomial.</p> 93 * 94 * @return a fresh copy of the coefficients array 95 */ 96 public double[] getCoefficients() { 97 double[] out = new double[coefficients.length]; 98 System.arraycopy(coefficients,0, out, 0, coefficients.length); 99 return out; 100 } 101 102 /** 103 * Uses Horner's Method to evaluate the polynomial with the given coefficients at 104 * the argument. 105 * 106 * @param coefficients the coefficients of the polynomial to evaluate 107 * @param argument the input value 108 * @return the value of the polynomial 109 * @throws IllegalArgumentException if coefficients is empty 110 * @throws NullPointerException if coefficients is null 111 */ 112 protected static double evaluate(double[] coefficients, double argument) { 113 int n = coefficients.length; 114 if (n < 1) { 115 throw new IllegalArgumentException("Coefficient array must have positive length for evaluation"); 116 } 117 double result = coefficients[n - 1]; 118 for (int j = n -2; j >=0; j--) { 119 result = argument * result + coefficients[j]; 120 } 121 return result; 122 } 123 124 /** 125 * Returns the coefficients of the derivative of the polynomial with the given coefficients. 126 * 127 * @param coefficients the coefficients of the polynomial to differentiate 128 * @return the coefficients of the derivative or null if coefficients has length 1. 129 * @throws IllegalArgumentException if coefficients is empty 130 * @throws NullPointerException if coefficients is null 131 */ 132 protected static double[] differentiate(double[] coefficients) { 133 int n = coefficients.length; 134 if (n < 1) { 135 throw new IllegalArgumentException("Coefficient array must have positive length for differentiation"); 136 } 137 if (n == 1) { 138 return new double[]{0}; 139 } 140 double[] result = new double[n - 1]; 141 for (int i = n - 1; i > 0; i--) { 142 result[i - 1] = (double) i * coefficients[i]; 143 } 144 return result; 145 } 146 147 /** 148 * Returns the derivative as a PolynomialRealFunction 149 * 150 * @return the derivative polynomial 151 */ 152 public PolynomialFunction polynomialDerivative() { 153 return new PolynomialFunction(differentiate(coefficients)); 154 } 155 156 /** 157 * Returns the derivative as a UnivariateRealFunction 158 * 159 * @return the derivative function 160 */ 161 public UnivariateRealFunction derivative() { 162 return polynomialDerivative(); 163 } 164 165 }