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 }