1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 }