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: 1.12 $ $Date: 2004/07/20 12:55:01 $
    27   */
    28  public class PolynomialFunction implements DifferentiableUnivariateRealFunction, Serializable {
    29
    30      /*** Serializable version identifier */
    31      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 }