blob: 7184147c08af8c379a75441a75deac1a7d16445e [file] [log] [blame]
/*
* Copyright 2003-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import java.io.Serializable;
/**
* Immutable representation of a real polynomial function with real coefficients.
* <p>
* <a href="http://mathworld.wolfram.com/HornersMethod.html">Horner's Method</a>
* is used to evaluate the function.
*
* @version $Revision$ $Date$
*/
public class PolynomialFunction implements DifferentiableUnivariateRealFunction, Serializable {
/** Serializable version identifier */
static final long serialVersionUID = 3322454535052136809L;
/**
* The coefficients of the polynomial, ordered by degree -- i.e.,
* coefficients[0] is the constant term and coefficients[n] is the
* coefficient of x^n where n is the degree of the polynomial.
*/
private double coefficients[];
/**
* Construct a polynomial with the given coefficients. The first element
* of the coefficients array is the constant term. Higher degree
* coefficients follow in sequence. The degree of the resulting polynomial
* is the length of the array minus 1.
* <p>
* The constructor makes a copy of the input array and assigns the copy to
* the coefficients property.
*
* @param c polynominal coefficients
* @throws NullPointerException if c is null
* @throws IllegalArgumentException if c is empty
*/
public PolynomialFunction(double c[]) {
super();
if (c.length < 1) {
throw new IllegalArgumentException("Polynomial coefficient array must have postive length.");
}
this.coefficients = new double[c.length];
System.arraycopy(c, 0, this.coefficients, 0, c.length);
}
/**
* Compute the value of the function for the given argument.
* <p>
* The value returned is <br>
* <code>coefficients[n] * x^n + ... + coefficients[1] * x + coefficients[0]</code>
*
* @param x the argument for which the function value should be computed
* @return the value of the polynomial at the given point
* @see UnivariateRealFunction#value(double)
*/
public double value(double x) {
return evaluate(coefficients, x);
}
/**
* Returns the degree of the polynomial
*
* @return the degree of the polynomial
*/
public int degree() {
return coefficients.length - 1;
}
/**
* Returns a copy of the coefficients array.
* <p>
* Changes made to the returned copy will not affect the coefficients of
* the polynomial.
*
* @return a fresh copy of the coefficients array
*/
public double[] getCoefficients() {
double[] out = new double[coefficients.length];
System.arraycopy(coefficients,0, out, 0, coefficients.length);
return out;
}
/**
* Uses Horner's Method to evaluate the polynomial with the given coefficients at
* the argument.
*
* @param coefficients the coefficients of the polynomial to evaluate
* @param argument the input value
* @return the value of the polynomial
* @throws IllegalArgumentException if coefficients is empty
* @throws NullPointerException if coefficients is null
*/
protected static double evaluate(double[] coefficients, double argument) {
int n = coefficients.length;
if (n < 1) {
throw new IllegalArgumentException("Coefficient array must have positive length for evaluation");
}
double result = coefficients[n - 1];
for (int j = n -2; j >=0; j--) {
result = argument * result + coefficients[j];
}
return result;
}
/**
* Returns the coefficients of the derivative of the polynomial with the given coefficients.
*
* @param coefficients the coefficients of the polynomial to differentiate
* @return the coefficients of the derivative or null if coefficients has length 1.
* @throws IllegalArgumentException if coefficients is empty
* @throws NullPointerException if coefficients is null
*/
protected static double[] differentiate(double[] coefficients) {
int n = coefficients.length;
if (n < 1) {
throw new IllegalArgumentException("Coefficient array must have positive length for differentiation");
}
if (n == 1) {
return new double[]{0};
}
double[] result = new double[n - 1];
for (int i = n - 1; i > 0; i--) {
result[i - 1] = (double) i * coefficients[i];
}
return result;
}
/**
* Returns the derivative as a PolynomialRealFunction
*
* @return the derivative polynomial
*/
public PolynomialFunction polynomialDerivative() {
return new PolynomialFunction(differentiate(coefficients));
}
/**
* Returns the derivative as a UnivariateRealFunction
*
* @return the derivative function
*/
public UnivariateRealFunction derivative() {
return polynomialDerivative();
}
}