View Javadoc

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 }