View Javadoc

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 }